mit drawString direkt zeichnen, aber wie das Ende finden?

bubi

Neues Mitglied
Hallo,

Ich bin neu in der Java-Entwicklung bin aber für meine Verhältnisse in kurzer Zeit recht weit gekommen.
Es geht darum via RS232 SMS zu empfangen und auf einem Beamer aufbereitet darzustellen.
Grundlegend funktioniert das ganze. Ich bin jetzt soweit das ich die Grafikausgabe überarbeite und es ein wenig "ausmale".

Ich habe mir für meine SMS die angezeigt werden eine eigene Klasse gemacht die auf JPanel basiert und dir paintComponent überschreibt. Es kann einen Text entgegennehmen und mal eine Sprechblase mit zufälliger Farbe auf das JFrame. Das ganze sieht im Moment wie folgt aus.

Java:
g.setColor(c);
        
        arx[0] = 100;
        arx[1] = 50;
        arx[2] = 60;
        ary[0] = rec_h+1;
        ary[1] = rec_h+50;
        ary[2] = rec_h+1;

        g.fillRoundRect(1,1,rec_w,rec_h,50,50);
        g.fillPolygon(this.arx,this.ary,3);

        g.setFont(font);
        g.setColor(Color.white);
        
        g.drawString(this.text1, 20, 30);
        g.drawString(this.text2, 20, 55);
        g.drawString(this.text3, 20, 80);
        g.drawString(this.text4, 20, 105);
        g.drawString(this.text5, 20, 130);

Das funktioniert auch.
rec_w und rec_h sollen dynamisch abhängig vom Text angepasst werden.
Das ganze(wieviele Zeilen und Spalten) ermittle ich bereits in meiner setText() Methode.

Java:
 public void setText(String text){
        this.col = text.length();

        if(text.length()>60){
            this.text1 = text.substring(0, 60);
            this.text2 = text.substring(61, text.length());
            this.row = 2;
        }else{
            this.text1 = text;
            this.row = 1;
        }

        if(text.length()>120){
            this.text2 = text.substring(61, 120);
            this.text3 = text.substring(121, text.length());
            this.row = 3;
        }
        if(text.length()>180){
            this.text3 = text.substring(121, 180);
            this.text4 = text.substring(181, text.length());
            this.row = 4;
        }
        if(text.length()>240){
            this.text4 = text.substring(181, 240);
            this.text5 = text.substring(241, 255);
            this.row = 5;
        }
        updateBorder();     
    }

und mit updateBorder() aktualisiere ich das ganze.

Java:
    public void updateBorder(){
        this.rec_h = 20+(22*row);
        this.rec_w =200 + (7 * col);
    }

Jetzt habe ich aber das Problem das ich nie die passende Größe erwische, ich vermute mal das liegt an der dynamischen "Breite" eines Zeichens.
Farbe ist hier noch nicht zufällig drinnen.

PS: Wenn wer Tipps hat wie ich das ganze noch weiter optisch aufpeppen kann immer her damit 🙂

LG
Michael

Gibt es eine Möglichkeit den letzten gezeichneten Pixel von zB drawString(...) zu finden? Das würde mir schon reichen.

Ich häng noch ein Bild an damit man sieht um was es geht 🙂
 

Anhänge

  • bsp.jpg
    bsp.jpg
    18,4 KB · Aufrufe: 37
Vllt hilft dir ja folgendes:

Mit
Code:
SwingUtilities.computeStringWidth(...);
könntest du dir die Weite des Strings berechnen lassen...

Also z.B.
Java:
int width= SwingUtilities.computeStringWidth(g.getFontMetrics(), "hallo"); //hallo = dein sms string

Müsstest dann natürlich nur, da du ja mehrere Zeilen unter Umständen anzeigen möchtest, den Längsten ermitteln wahrscheinlich
 
Vielen Dank!
Läuft perfekt, genau das was ich gesucht habe!

PS: Die längste Zeile habe ich bereits, das ist zu 100% die erste, da eine Zeile nie länger als 60 Zeichen werden kann, weil ich sie danach splitte!
 
Da dieser Eintrag per Google zu finden ist, mal kurz als Info: Für Mehrzeiligen Text kann auch die Klasse LineBreakMeasurer genutzt werden. Dabei muss man allerdings die gewünschte Breite kennen. Jedes TextLayout ist eine Zeile.

Java:
AttributedString as = new AttributedString(this.text);
as.addAttribute(TextAttribute.FONT, new Font(fontName, Font.PLAIN, desSize));
AttributedCharacterIterator aci = as.getIterator();
LineBreakMeasurer lbm = new LineBreakMeasurer(aci, g2d.getFontRenderContext());
while (lbm.getPosition() < aci.getEndIndex()) {
    TextLayout tl = lbm.nextLayout(this.getObjectWidth());
    drawy += tl.getAscent();
    newHeight += tl.getAscent();
    tl.draw(g2d, drawx, drawy);
    drawy += tl.getDescent() + tl.getLeading();
    newHeight += tl.getDescent() + tl.getLeading();
}

In den Beispiel wird auch gleich die Höhe des neuen Textes berechnet (ginge natürlich auch indem man einfach den Start Y-Wert vom Letzen Y-Wert abzieht).

Bei Einzeiligentext kann die Höhe/Breite auch wie folgt ermittelt werden:

Java:
Rectangle2D r = g2d.getFontMetrics().getStringBounds(text, g2d);
r.getHeight(); //Höhe des Textes
r.getWidth(); //Breite des Textes
 

Neue Themen


Zurück
Oben