2D-Grafik Blocksatz mit drawString()

Taggert

Mitglied
Hallo,

ich habe das Problem, dass ich einen Text als Blocksatz ausgeben möchte - und zwar mit Hilfe von der 2D-API. Gibt es da eine Möglichkeit? Wie würdet Ihr an das Problem rangehen?

Danke für Eure Antworten
Grüße Taggert
 

Marco13

Top Contributor
Könnte sehr aufwändig sein. Wenn man's schön machen will. Wenn die Zeilenumbrüche vorgegeben sind, geht's vielleicht, aber wenn man die komplett selbst berechnen will, wird's kompliziert (gut, ist "nur" ein Kürzesete-Wege-Problem, aber implementiert werden muss das erstmal). Irgendein (leicht hackiger) "workaround" könnte sein, in eine Zeile an den Stellen, wo schon Leerzeichen stehen, weitere Leerzeichen einzufügen, bis die gewünsche Zeilenlänge erreicht ist...
 

Taggert

Mitglied
Daran hbe ich auch gedacht, aber gibt es nicht vielleicht noch einen eleganteren Weg das Problem anzugehen? Meine Idee wäre gewesen, den String in Chars umzuwandeln, um dann immer die gleiche anzahl an Zeichen pro Zeile zu haben. Aber geht das nicht vielleicht einfacher, habe ich nicht vielleicht noch irgendeine coole Funktion übersehen?
 

Marco13

Top Contributor
Hm. Die gleiche Anzahl bringt nicht viel, außer bei Monospaced-Schrift:

iiiiiiiiii
mmmmmmmmmm

vs.
[c]iiiiiiiiii[/c]
[c]mmmmmmmmmm[/c]
 

Marco13

Top Contributor
Der angedeutete "Hackige workaround" wäre, mit FontMetrics.getStringBounds rumzuspielen, und leerzeichen Hinzuzufügen/zu entfernen, bis es passt, oder die einzelnen Worte an die passenden Stellen zu malen.

RICHTIG gehackt:
Java:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.util.*;
import java.util.List;

class JustifyPanel extends JPanel
{
    private String text;

    public JustifyPanel(String text)
    {
        this.text = text;
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        drawJustified(g, text, getWidth());
    }

    private void drawJustified(Graphics g, String s, int w)
    {
        List<String> allWords = Arrays.asList(s.split(" "));

        FontMetrics fm = g.getFontMetrics();
        double lineHeight = (int)fm.getStringBounds("fg", g).getHeight();

        int index = 0;
        int y = (int)lineHeight;
        while (index < allWords.size())
        {
            List<String> subList = new ArrayList<String>();
            index = computeSublist(g, allWords, index, subList, w);
            int width = computeWidth(g, subList);

            System.out.println("Words until "+index+": "+subList+" width "+width);

            draw(g, subList, width, w, y);
            y += lineHeight;
        }
    }

    private int computeSublist(Graphics g, List<String> allWords, int startIndex, List<String> subList, int w)
    {
        FontMetrics fm = g.getFontMetrics();

        double spaceWidth = (int)fm.getStringBounds(" ", g).getWidth();

        double x = 0;
        int index = startIndex;
        while (index < allWords.size())
        {
            String word = allWords.get(index);
            Rectangle2D r = fm.getStringBounds(word+" ", g);
            x += (int)(r.getWidth() + spaceWidth);
            if (x > w)
            {
                if (subList.size() == 0)
                {
                    subList.add(word);
                    return index+1;
                }
                break;
            }
            subList.add(word);
            index++;
        }
        return index;
    }

    private int computeWidth(Graphics g, List<String> words)
    {
        FontMetrics fm = g.getFontMetrics();
        double spaceWidth = (int)fm.getStringBounds(" ", g).getWidth();
        double width = 0;
        for (int i=0; i<words.size(); i++)
        {
            Rectangle2D r = fm.getStringBounds(words.get(i)+" ", g);
            width += (int)(r.getWidth() + spaceWidth);
        }
        return (int)width;
    }

    private void draw(Graphics g, List<String> words, int wordsWidth, int w, int y)
    {
        FontMetrics fm = g.getFontMetrics();
        double remaining = (w - wordsWidth);
        double fill = 0;
        if (words.size() > 0)
        {
            fill = remaining / (words.size()-1);
        }
        double x = 0;
        for (int i=0; i<words.size(); i++)
        {
            g.drawString(words.get(i), (int)x, y);
            x += fm.getStringBounds(words.get(i)+" ", g).getWidth() + fill;
        }
    }


}

class JustifyTest
{
    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.getContentPane().add(new JustifyPanel(
                    "Lorem ipsum dolor sit amet, consectetur adipisicing "+
                    "elit, sed do eiusmod tempor incididunt ut labore et "+
                    "dolore magna aliqua. Ut enim ad minim veniam, quis "+
                    "nostrud exercitation ullamco laboris nisi ut aliquip "+
                    "ex ea commodo consequat. Duis aute irure dolor in "+
                    "reprehenderit in voluptate velit esse cillum dolore eu "+
                    "fugiat nulla pariatur. Excepteur sint occaecat cupidatat "+
                    "non proident, sunt in culpa qui officia deserunt mollit "+
                    "anim id est laborum."
                    ));
                f.setSize(300,300);
                f.setVisible(true);
            }
        });
    }

}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Text in JLabel als Blocksatz? AWT, Swing, JavaFX & SWT 13
P Blocksatz im JTextField? AWT, Swing, JavaFX & SWT 3
C SWT autosize bei gc.drawString() auf einem Label AWT, Swing, JavaFX & SWT 7
M Graphics2D: drawString Berechnung AWT, Swing, JavaFX & SWT 1
X AWT Text der mit Graphics "drawString(...)" geschreiben wurde wieder löschen. AWT, Swing, JavaFX & SWT 6
M JFrame Graphics.drawString Problem AWT, Swing, JavaFX & SWT 11
P drawString in einem Rectangle AWT, Swing, JavaFX & SWT 4
Luk10 g.drawString funktioniert nicht + Frage zur Text-Rendering Qualität AWT, Swing, JavaFX & SWT 7
C drawString wird beim starten des Programmes nicht ausgeführt AWT, Swing, JavaFX & SWT 3
B Graphics2d drawString mit double Werten? AWT, Swing, JavaFX & SWT 5
K Java DrawString zentriert und mehrzeilig AWT, Swing, JavaFX & SWT 8
R AWT drawString - Ausmaße AWT, Swing, JavaFX & SWT 4
F Browser drawString AWT, Swing, JavaFX & SWT 4
J 2D-Grafik Html in drawString() AWT, Swing, JavaFX & SWT 2
A Formatierten String ausgeben (drawString) AWT, Swing, JavaFX & SWT 5
Zettelkasten drawString() Zeilenumbruch AWT, Swing, JavaFX & SWT 2
M breite eines "drawString()-Strings" AWT, Swing, JavaFX & SWT 2
F AWT Probleme mit drawString() AWT, Swing, JavaFX & SWT 5
S drawString für HTML-Text? AWT, Swing, JavaFX & SWT 7
R drawString mit double Koordinaten AWT, Swing, JavaFX & SWT 5
D AWT drawString funktioniert nicht unter Linux AWT, Swing, JavaFX & SWT 7
G [gelöst] "Größe" von drawString AWT, Swing, JavaFX & SWT 4
spross line break bei drawString() mit LineBreakMeasurer? AWT, Swing, JavaFX & SWT 4
MasterEvil HTML formatierten Text mit drawString ? AWT, Swing, JavaFX & SWT 3
A Zentrieren von drawstring() in einem fillRect() AWT, Swing, JavaFX & SWT 3
m@nu Graphics: Per drawString() Text vertikal zentriert zeichnen AWT, Swing, JavaFX & SWT 5
T drawString AWT, Swing, JavaFX & SWT 9

Ähnliche Java Themen


Oben