Beschriftete Linie in Java 2D

Status
Nicht offen für weitere Antworten.

Octavian

Mitglied
Hallo,

Hab grad folgendes Problem...

Ich zeichne in einem JPanel mehre Linien und will jede Linie nun beschriften. Das Problem ist, die Linien sind nicht immer Horizontal und die Start und Endpunkte der Linien werden erst zur Laufzeit berechnet.
drawString zeichnet einne Text ja aber nur horizontal hin.

Bin leider kein so großer Profi mit Java 2D und steh grad ziemlich auf dem Schlauch wie ich das angehen könnte. Hab mir überlegt den Text zu rotieren, aber ich wüsste nicht recht mit welchen Parametern.

Würde mich über jede Hilfe freuen!!

MfG,
Jan.
 
Da kann die Methode Graphics2D.rotate helfen, aber lies besser in der API nach, wie man sie verwendet.

Die Drehung wird dann auf *alles* angewendet, was später gezeichnet wird.
 
Das ich die gleich wieder umkehren muss hab ich auch schon mitbekommen, dass ist net so das Problem.
Hatte nur gehofft da gibt es vielleicht ne halbwegs einfache Lösung, weil ich im Winkelrechnen nicht mehr so fit bin und grad nicht mehr so recht weiß wie ich jetzt zu einer gegebenen Linie den Text an die richtige Stelle bekomme...
 
Hallo! Hier habe ich ein kleines Beispielprogramm geschrieben, das beschriftete Linien in einem Vollkreis zeichnet. Der Text wird automatisch so gedreht, dass er immer über der Linie steht. Die Transformationen werden direkt nach dem Anwenden wieder zurückgesetzt, danach kann also wie zuvor weiter gezeichnet werden. Das Anti-Aliasing kann natürlich auch ausgeschaltet bleiben, dann sieht's aber nicht ganz so gut aus.

Code:
import java.awt.*;
import java.awt.geom.*;

public class TextLinienBeispiel extends Canvas
{
    public static void main(String[] args)
    {
        // Frame mit Canvas erzeugen
        Frame f = new Frame();
        f.add(new LineText());
        f.setSize(600, 600);
        f.setVisible(true);
    }

    public void paint(Graphics g)
    {
        // Beispielfigur
        for (int w = 0; w < 360; w += 10)
        {
            int x1 = (int) (300 + 75 * Math.cos(-w * Math.PI / 180));
            int y1 = (int) (300 + 75 * Math.sin(-w * Math.PI / 180));
            int x2 = (int) (300 + 250 * Math.cos(-w * Math.PI / 180));
            int y2 = (int) (300 + 250 * Math.sin(-w * Math.PI / 180));

            // hier kommt die eigentliche Methode
            textlinie((Graphics2D) g, w + "°", x1, y1, x2, y2);
        }
    }

    public void textlinie(Graphics2D g, String s, int x1, int y1, int x2,
            int y2)
    {
        // Anti-Aliasing an
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        // Linie zeichnen
        g.drawLine(x1, y1, x2, y2);

        // Koordinatensystem drehen
        AffineTransform alt = g.getTransform(); 
        AffineTransform neu = new AffineTransform();
        neu.translate((x1 + x2) / 2, (y2 + y1) / 2);
        neu.rotate(Math.atan((1.0 * y2 - y1) / (x2 - x1)));
        g.setTransform(neu);

        // Text einzeichnen
        FontMetrics f = g.getFontMetrics();
        g.drawString(s, -f.stringWidth(s) / 2, -2);

        // Koordinatensystem zurücksetzen
        g.setTransform(alt);
    }
}

Hoffe, das hilft Dir bei Deinem Problem.

KaiE
 
Ahhh, grad erst gesehen...

Ziemlich genialer Code, hab den so ziemlich genau so übernommen und vom Prinzip her passt das perfekt!

Leider hab ich jetzt noch ein kleines Problem...
Meine Zeichnung kann unterschiedlich groß werden und liegt daher in einem ScrollPanel. Wenn ich jetzt scrolle, bewegt sich die Schrift dummerweise mit und damit natürlich auch weg von ihren Linien... Das werd ich wohl noch unter Kontreolle bekommen müssen. Habs mir aber selber noch net genau angeguckt, werd ich jetzt gleich machen.

Aber auf jeden Fall großes Danke!

Cu,
Jan.
 
Sorry, im Quelltext ist natürlich noch ein Fehler versteckt: hatte in letzter Sekunde die Klasse umbenannt, und dabei eine Zeile vergessen. Zeile 10 müsste lauten:

Code:
f.add(new TextLinienBeispiel());

Das kommt davon, wenn man Refactoring per Hand durchführt! :roll:

KaiE
 
Das ist mir ehrlichgesagt gar nicht aufgefallen, da ich die Funktion zum Linienzeichnen einfach in mein Programm übernommen habe und das ausprobiert habe.

Hat auch sehr gut funktioniert, bis auf das Problem mit dem Scrollen...
Bisher hab ich leider noch keinen Weg gefunden das zu verhindern... Evt. noch ne Ahnung wie man das umgehen könnte?
 
Hallo nochmal,

habe mir das Programm nochmal mit JScrollPane angesehen, und es funktioniert damit tatsächlich nicht. Aber nach kurzem Rumtüfteln mit den Transformationen klappt's jetzt doch: Du musst nur die beiden Zeilen in der Methode textlinie mit folgenden Zeilen ersetzen:

Code:
        AffineTransform neu = g.getTransform();
        AffineTransform alt = (AffineTransform)neu.clone();

Dann sollte es eigentlich funktionieren. Viel Spass damit wünscht

KaiE
 
Hallo KaiE,

besten Dank für deine tolle Beispielanwendung. Wir haben das Ganze mal nett adaptiert 🙂

Grüße,
Fabian
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben