JLabel mit Swing drehen - ohne Graphics

Rhodo

Grünschnabel
Moin zusammen,

habe mich die letzte Zeit immer irgendwie voran "gekämpft", aber jetzt verzweifel ich gerade an einem kleinen Problem.

Erstmal zu meinem Projekt:
Ich lese eine XML aus in der Texte gesetzt werden. Diese Texte sollen dann mit Swing dargestellt werden. Das klappt auch alles soweit ganz gut, nur das drehen funktioniert nicht.

So sieht das ungefähr aus:
Code:
<Text x="100" y="300" w="50" h="100" color="#FF00FF00" angle="10" />

Da in der XML auch die Position gesetzt wird, hab ich beschlossen keinen LayoutManager zu verwenden, also
Java:
setLayout(null);
Dadurch steht mir ja die Graphics-Schnittstelle nich zur Verfügung bzw die relevante paint-Methode wird nicht aufgerufen (wie ich jetzt gelesen habe).

Die Frage ist jetzt: Wie kann ich ohne paint ein Label drehen? Oder geht das überhaupt nicht? Oder über einen Umweg mit viel gecaste oder so?

Wäre über jeden Tipp dankbar.

Grüße
-Rhodo
 
Zuletzt bearbeitet:

genodeftest

Erfahrenes Mitglied
1. Wenn du das null-Layout verwendest, heißt das nicht, dass du Graphics nicht verwenden kannst. Genauer: du brauchst Graphics unabhängig vom Layout immer!

2. zum Drehen von Text eignet es sich Graphics.rotate() für jedes einzelne Label aufzurufen.
 

Rhodo

Grünschnabel
Danke für deine Antwort.

Aber zumindest die paint-Methode ist nich verfügbar bzw Override hat keine Auswirkung?

Und wie ruf ich dann genau Graphics.rotate() auf dem Label auf?
 

Rhodo

Grünschnabel
paintComponent() funktioniert leider beim null-Layout nicht.
Somit kann ich die Funktion auch nicht überladen.

So spontan fällt mir dann nur noch eine äußerst unschöne Lösung ein:
Java:
for(JLabel aktuellesLabel : labels[]){
    JPanel foo = new JPanel();
    foo.setLayout(...);
    aktuellesLabel.paintComponents(); //mit @Override dann
    foo.add(aktuellesLabel);
    main.add(foo);
}

Aber so wirklich zufriedenstellend ist das auch nicht, wenn ich extra für jedes Label nochmal ein eigenes Panel erzeug...
 

Rhodo

Grünschnabel
Ok, ne neue etwas sparsamere Methode (zumindest für das Endergebnis):

Java:
public JLabel rotateLabel(int angle, String text) {
    JPanel foo = new JPanel();
    foo.setLayout(/*irgendwas != null*/);
    JLabel bar = new JLabel();
    foo.add(bar);
    bar.setText(text);
    bar.setVisible(true);
    Graphics2D g2 = bar.getGraphics();
    g2.rotate(angle);
    return JLabel ret = bar;
}

würde das so funktionieren?
Und ist das sinnvoll? bzw gibts was einfacheres/besseres?
 

Rhodo

Grünschnabel
Java:
window = new JFrame("foo");
window.setSize(1000,700);
window.setLocation(50,50);
window.setLayout(null);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

display = new JLayeredPane();
display.setLayout(null);
display.setBounds(10, 10, 450, 600 );
display.setBackground(Color.black);
display.setOpaque(true);

vars = new JPanel();
vars.setLayout(null);
vars.setBounds(480, 600, 450, 600);
vars.setBackground(Color.gray);

window.add(display);
window.add(vars);

Innerhalb von vars und display will ich jetzt gedrehte JLabels erzeugen.
D.h. ich überlade für display und vars die paintComponent?
 

genodeftest

Erfahrenes Mitglied
Eigentlich müsste es 2 Möglichkeiten geben:

1. du überlädst in 'display' und 'vars' die Methode paintChildren(), dazu solltest du dir aber unbedingt den Quellcode von JComponent.paintChildren() ansehen! Das sollte der einfachere Weg sein. Ich würde dabei so ansetzen, dass ich den Code aus JComponent.paintChildren() kopiere und dort nach Zeile 860:
Java:
Graphics cg = sg.create(cr.x, cr.y, cr.width, cr.height);
eine neue Zeile einfüge, die 'cg' rotiert. Den Rest solltest du eigentlich so stehen lassen können. Allerdings musst du beachten, dass die Position deines childComponents auch mit gedreht wird, was du beim setzen der absoluten Positionen beachten musst. Am besten ist wohl, wenn du dein 'cg' um den Punkt drehst, der die linke obere Ecke deines childComponents ist.

2. du überlädst in den jeweils gedrehten Components die Methoden für paintBorder, paintComponent und paintChildren, das wird aber kompliziert. Und solange die Komponenten gültige Bounds haben, muss das auch ohne LayoutManager funktionieren.

Für beide solltest du noch beachten, dass das Null-Layout äußerst problematisch ist, weil du absolute Werte für Position und Höhe/Breite eingeben musst. Je nach verwendeter Oberfläche/Theme des Betriebssystems, LookAndFeel, Systemschrift (Art, Typ, Größe), evtl. Theme deines LookAndFeels, dpi deines Betriebssystems, … kann deine graphische Oberfläche ganz anders aussehen. Für eine echt plattformunabhängige Lösung müsstest du einen eigenen LayoutManager implementieren und garantieren, dass für Container mit gedrehten Elementen dieser LayoutManager eingesetzt wird.
 
Zuletzt bearbeitet:

Rhodo

Grünschnabel
Danke für die Antwort. Muss ich mal gucken was davon einfacher zu machen ist.
Weiß auch noch nicht ob bei gedrehten Labels der x-Wert aus der XML dem neuen gedrehten x-Wert entspricht oder wie sich das verhält. Aber das seh ich dann.

Ich muss ja leider auf das Null-Layout zurückgreifen. Aber das mit den Schriften sollte kein Problem sein, da die vorher selbst festgelegt wird. Das funktioniert auch eig richtig.

Ich schau mal wie ich jetzt voran komm damit ;)
 

Neue Beiträge