Eine paint-Methode, 2 Welten?

Goldi

Aktives Mitglied
Hallo zusammen!
Ich bin einem Mysterium auf der Spur, im Zweifel dem meiner eigenen Unwissenheit, aber das ist wirklich komisch. Ich möchte gerne wissen, ob ich zu blöd bin oder ob's diesmal an Duke liegt. Ich habe zur Problembeschreibung ein einfaches Programm geschrieben und fange am besten mit dem Ergebnis an. In einem mehr oder weniger verschachtelten und komplexen Fenster soll folgende Grafik erscheinen:

upload_2016-8-5_18-35-6.png

Der Aufbau: Die 2 Quadrate werden von einem JPanel in ein- und derselben paintComponent-Methode gemalt. Das JPanel liegt hier auf einem einfach JFrame. So weit, so gut. Nun ein Fenster, das halt noch andere Komponenten und ein BorderLayout haben:

upload_2016-8-5_18-38-55.png

Aufbau: Auf dem JFrame liegt ein BorderLayout: Der Norden nimmt nun mit irgendwelchen Komponenten Platz weg, der Süden enthält das alt bekannte JPanel mit den zwei Quadraten.

Das rote Quadrat verhält sich unauffällig, so wie erwartet. Dagegen das gelbe Quadrat, dessen einzige Besonderheit es ist transformiert zu sein (Drehung), hat seine Grenze nicht an der Oberkante des Containers, der es beherbergt, sondern exakt an der Oberkante des JFrames. Und doch wurden beide "im gleichen Atemzug" erzeugt!

Wie zum Henker :confused: kann es sein :eek:, dass diese beiden Quadrate o_O, die in ein- und derselben paintComponent-Methode in ein- und demselben JPanel gemalt wurden :oops:, vom Layout-Manger des aufnehmenden JFrames unterschiedlich behandelt werden??:confused:????:eek:?????o_O????:oops:???? Übrigens: Wenn ich das Fenster nach unten vergrößere, zieht das rote Quadrat und auch das JPanel mit, das gelbe bleibt stehen und wandert im Umkehrschluss aus seinem eigenen JPanel raus:

upload_2016-8-5_18-44-27.png

Ich hab's übrigens auch mit deinem GridBagLayout probiert: Das gleiche Ergebnis.

Und hier der Programmcode:

Zunächst zur Klasse, die die Quadrate malt (sie ist von JPanel abgeleitet):

Java:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

/** Diese Panel erzeigt einfach nur 2 Quadraten mit Seitenlänge 250 Pixel,
 * eines davon gedreht um 45°. Diese werden in der überlagerten paintComponent-
 * Methode realisiert. Damit die Grafiken auf der JFrame später vollständig angezeigt
 * werden,müssen die Methoden getPreferredSize und getMinimumSize überlagert werden.
 * Sie geben genau die Ausmaße zurück, die die grafiken brauchen. */
public class TestPanel
extends JPanel {

   private static final long serialVersionUID = 1L;

   @Override
   public Dimension getPreferredSize() {
     return new Dimension(354, 354);     // Errechnet mit dem guten alten Pythagoras
   }
   
   @Override
   public Dimension getMinimumSize() {
     return getPreferredSize();
   }
   
   @Override
   protected void paintComponent(Graphics g) {
     Graphics2D g2d = (Graphics2D)g;
     
     // Ein rotes, nicht transformiertes Quadrat wird im Bezug auf das nächste gelbe
     // Quadrat genau mittig gemalt
     g2d.setColor(new Color(255, 0, 0));
     g2d.fillRect(52, 52, 250, 250);
     
     // Das gelbe Quadrat soll um 45° gedreht werden:
     AffineTransform trans = new AffineTransform();
     trans.rotate(45d * Math.PI / 180d,   // Bogenmaß zu 45°
         177, 0);           // Die Anker (x: 177, y: 0) sollen identisch sein
                       // mit den Koordinaten des gelben Quadrats, so dass
                       // es durch die Rotation keine x-/y-Verschiebungen gibt.
     g2d.setTransform(trans);
     
     g2d.setColor(new Color(255, 255, 0));
     g2d.fillRect(177, 0, 250, 250);      // x=177, y=0 => identisch mit Anker (s. o.)
     
   }
}

Hier die JFrame mit den Zusatz-Komponenten; ich habe die Unterschiede im Code zum aller ersten Screenshot (einfaches JFrame) kommentiert:

Java:
import javax.swing.*;
import java.awt.*;

public class TestFrame2
extends JFrame {

   private static final long serialVersionUID = 1L;
   
   public TestFrame2() {
     
     super("Testfenster mit BorderLayout");
     addWindowListener(new myWindowListener());
     
     Container cp = getContentPane();
     
     // --------------------------------------------------------------------
     // Hier der Programmteil, der sich von TestFrame1 unterscheidet:
     
     setLayout(new BorderLayout());
     
     // Panel mit zusätzlichen Komponenten im Norden:
     JPanel irgendwasPanel = new JPanel(new BorderLayout());
     irgendwasPanel.add(new JTextArea("Ein paar\nbedeutungslose\nZeilen", 3, 100), BorderLayout.NORTH);
     irgendwasPanel.add(new JButton("Irgendein Button ohne Funktion"), BorderLayout.SOUTH);
     
     cp.add(irgendwasPanel, BorderLayout.NORTH);
     
     // Der grafische Teil (2 Quadrate) steht im Süden:
     TestPanel testpanel = new TestPanel();
     cp.add(testpanel, BorderLayout.SOUTH);
     
     // ------------- Unterschied Ende --------------------------------------
     
     pack();
     setVisible(true);
   }
   
   
   public static void main(String[] args) {
     new TestFrame2();
   }
}
Den WindowListener kann ich mir denke ich sparen :).

Jetzt bin ich ja mal gespannt, was die Gemeinde dazu sagt: Welche Nachhilfe brauche ich noch oder ist das tatsächlich ein Fehler in Java?

Herzlichen Gruß
Stefan
 

Anhänge

  • upload_2016-8-5_17-44-3.png
    upload_2016-8-5_17-44-3.png
    13,5 KB · Aufrufe: 17
  • upload_2016-8-5_17-48-20.png
    upload_2016-8-5_17-48-20.png
    24,4 KB · Aufrufe: 18
  • upload_2016-8-5_18-36-37.png
    upload_2016-8-5_18-36-37.png
    23,7 KB · Aufrufe: 26
  • upload_2016-8-5_18-44-5.png
    upload_2016-8-5_18-44-5.png
    24,1 KB · Aufrufe: 30

JCODA

Top Contributor
Interessant! Ich kannte diese Interaktion auch noch nicht. Scheint als wäre die AffineTransform etwas "Globales" ... naja, mit

Java:
 g2d.rotate(45d * Math.PI / 180d, 177, 0);
statt der AffineTransform geht es.

Eine Erklärung wäre, dass die "Welten", wie du sie nennst, ebenfalls du AffineTransform erzeugt werden, und wenn du sie selbst "setzt" machst du sie kaputt.
Oh, ich hab gerade nachgeschaut: tatsächlich, siehe: https://docs.oracle.com/javase/7/do...l#setTransform(java.awt.geom.AffineTransform)
public abstract void setTransform(AffineTransform Tx)
Overwrites the Transform in the Graphics2D context. WARNING: This method should never be used to apply a new coordinate transform on top of an existing transform because the Graphics2D might already have a transform that is needed for other purposes, such as rendering Swing components or applying a scaling transformation to adjust for the resolution of a printer.
To add a coordinate transform, use the transform, rotate, scale, or shear methods.
 

Goldi

Aktives Mitglied
Vielen herzlichen Dank, das war der richtige Hinweis! Klar ... die Doku :rolleyes:. Zu meiner Verteidigung: Die Vorgehensweise, das AffineTrans-Dings auf das Graphics2D-Objekt direkt anzuwenden, kam aus einem Java-Fachschmöker in meinem Bücherregal. Das hätte ich nie in Frage gestellt. Ich sollte dem Autoren mal eine Email schreiben;).

Übrigens für Interessierte: Habe jetzt in der AffineTrans-Klasse die createTransformedShape-Methode entdeckt, mit deren Hilfe man die u. U. geschachtelte Transformationen auf ein Shape (grafische Formen aus Java2D, z. B. RectAngle2D) anwenden kann.
 

AndyJ

Bekanntes Mitglied
Ich wuerde mal sagen, du hast einfach vergessen die alte transformation zu speichern und wieder herzustellen:
Code:
// Get the current transform 
AffineTransform saveAT = g2.getTransform(); 
// Perform transformation 
g2d.transform(...); 
// Render 
g2d.draw(...); 
// Restore original transform 
g2d.setTransform(saveAT);
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
jojoge wie kann ich in eine Benennung eines JButtons eine Variable einbauen? AWT, Swing, JavaFX & SWT 6
MartinNeuerlich Kann mir jemand, der einen Mac mit einem m1 oder m2-Chip hat, eine POM geben mit der Javafx-Fullscreen beim Mac mit m-Chip funktioniert? AWT, Swing, JavaFX & SWT 1
berserkerdq2 Buttons und Shapes sehen ja nach Screengröße klein oder zu groß aus, jemand eine Idee, was man tun kann? AWT, Swing, JavaFX & SWT 1
ExceptionOfExpectation Mit einer laufenden GUI Applikation eine Datei in dem Rechner löschen AWT, Swing, JavaFX & SWT 2
Jose05 Aus einer normalen Java Klasse eine FXML-Klasse laden AWT, Swing, JavaFX & SWT 12
_user_q Gibt es eine Möglichkeit, in Java alle möglichen Zeichen automatisch tippen zu lassen? AWT, Swing, JavaFX & SWT 13
J Ich kriege eine Fehler Messesage bei meinem Media Player AWT, Swing, JavaFX & SWT 8
I Einbindung eines jpg/png/icons in eine GUI AWT, Swing, JavaFX & SWT 1
mrbody234 ArrayList<Message> in eine TableView visualisieren AWT, Swing, JavaFX & SWT 2
U Gibt es eine Möglichkeit statt concatenate einen anderen Befehl zu nutzen? AWT, Swing, JavaFX & SWT 9
D Tastaturabfragen CTRL+t, CTRL+E bei eine JTable, bestehend aus JTextAteas AWT, Swing, JavaFX & SWT 4
G JavaFX Wert aus DB lesen, wenn erfolgreich automatisch eine fxml laden, möglich? AWT, Swing, JavaFX & SWT 2
Lukas2904 Wie speicher ich eine Einstellung? AWT, Swing, JavaFX & SWT 1
T Getter und Setter für eine Stage AWT, Swing, JavaFX & SWT 6
P Zwei JTables auf eine A4-Seite mit einstellbaren Rändern AWT, Swing, JavaFX & SWT 9
Monokuma 2D-Grafik Imageimport durch eine gezeichnete Form ersetzen AWT, Swing, JavaFX & SWT 16
M Eine Datei auf den Apache Server hochladen - über das Menü im JavaProgramm AWT, Swing, JavaFX & SWT 7
B JavaFX Warum wird hier eine NullPointer-Exception geworfen? AWT, Swing, JavaFX & SWT 7
VPChief Gibt es eine möglichkeit Dateien aus der jar datei zu kopieren? AWT, Swing, JavaFX & SWT 46
B Swing Sudoku: Laden / Speichern von Zahlen aus/in mehrere JTextFields aus/in eine(r) Textdatei AWT, Swing, JavaFX & SWT 9
P Swing Icon einfügen wirft eine Fehlermeldung AWT, Swing, JavaFX & SWT 3
F Variablen an eine Form binden? AWT, Swing, JavaFX & SWT 2
V Swing für jedes Kästchen eine eigene Farbe AWT, Swing, JavaFX & SWT 2
F Wie bekomme ich den Wert der ComboBox in eine Variable gespeichert welche ich für meinen ActionListener nutzen kann? AWT, Swing, JavaFX & SWT 3
W JavaFX Warum kriege ich eine Exception? AWT, Swing, JavaFX & SWT 23
karlmasutra JavaFX Zugriff auf eine erzeugte Scene aus einer anderen Klasse AWT, Swing, JavaFX & SWT 1
Informatiknoob AWT Zahlenraten (eine Zahl zwischen 1 und 10) AWT, Swing, JavaFX & SWT 1
A eine Fehler AWT, Swing, JavaFX & SWT 9
TheJavaKid Auf eine Zeichnung im Canvas reagieren AWT, Swing, JavaFX & SWT 13
A JavaFX Daten in eine HTML-Table mit JS schreiben AWT, Swing, JavaFX & SWT 3
B JavaFX TableView eine Zeile markieren AWT, Swing, JavaFX & SWT 5
J jButton soll nach klicken eine Variable um 1 erhöhen AWT, Swing, JavaFX & SWT 2
J Compiler in der JavaFX stop() Methode warten lassen bist eine Aktion in einer anderen Scene gemacht AWT, Swing, JavaFX & SWT 5
J Swing JavaProgramm für Verschlüssen für eine Datei AWT, Swing, JavaFX & SWT 19
xYurisha JLabel Text einer geöffneten Gui über eine andere Klasse ändern! AWT, Swing, JavaFX & SWT 3
J JavaFX Die Webview stellt eine Webseite nicht dar AWT, Swing, JavaFX & SWT 0
M JavaFX Ein Labeltext eine zeitlang anzeigen dann weiter machen AWT, Swing, JavaFX & SWT 3
F Event wenn Maus eine JList verlässt AWT, Swing, JavaFX & SWT 13
I JAVAFX - Übergabe der Inhalte an eine Scene - Wo ist der Vorteil gegenüber Swing? AWT, Swing, JavaFX & SWT 2
Joker4632 JFrame in eine Runnable auslagern? AWT, Swing, JavaFX & SWT 4
A JScrollPane soll JPanel mit JButtons enthalten und eine Scollbar anzeigen AWT, Swing, JavaFX & SWT 1
B Wie erstelle ich eine JavaFX Anwendung von diesem Code? AWT, Swing, JavaFX & SWT 3
Sanni94 JavaFX Kann man eine Grafik in einen Text einbinden? AWT, Swing, JavaFX & SWT 2
Java_RY AWT Frame in eine eigene klasse auslagern und aufrufen AWT, Swing, JavaFX & SWT 6
I 2D-Grafik Problem beim Ändern der Farbe eine 2d Objekts AWT, Swing, JavaFX & SWT 3
Thallius Swing JDatePicker oder Sucht jemand eine Aufgabe? AWT, Swing, JavaFX & SWT 0
K Wie kann ich eine Variable zwischen Tab Klassen weitergeben ? AWT, Swing, JavaFX & SWT 7
D JavaFX Erkennen wenn eine Anwendung geschlossen wird und etwas tun? AWT, Swing, JavaFX & SWT 4
R Swing Durch JComboBox-Item eine TextArea aktualisieren AWT, Swing, JavaFX & SWT 2
M Wie binde ich eine JavaFX ProgressBar an eine Datei Übertragung? AWT, Swing, JavaFX & SWT 2
D Objekte einer Oberfläche in eine Datei/Ordner speichern AWT, Swing, JavaFX & SWT 9
A Mit dem Scene Builder eine Collage erstellen (Bilder beziehen aus Flickr) AWT, Swing, JavaFX & SWT 1
A JFace Wizard: Ist es möglich eine Page zu löschen? AWT, Swing, JavaFX & SWT 2
L Swing Wie programmiere ich eine eigene GUI? AWT, Swing, JavaFX & SWT 12
M Combo Box auswahl in eine Datenbank speichern AWT, Swing, JavaFX & SWT 1
M Swing JTextField getText Mehtode übergeben in eine Klasse zu einer Rechnung AWT, Swing, JavaFX & SWT 1
D AWT Das ganze GUI in eine Klasse? AWT, Swing, JavaFX & SWT 1
J JavaFX eine Art Tabelle, jedoch mit mehreren Zeilen AWT, Swing, JavaFX & SWT 2
L Zwei String Array in eine Spalte einfügen AWT, Swing, JavaFX & SWT 1
U LookAndFeel für eine Komponente AWT, Swing, JavaFX & SWT 2
E Mit Netbeans von einer Form auf eine Komponente einer anderen Form zugreifen AWT, Swing, JavaFX & SWT 2
G Zeichnen auf eine schwergewichtige Komponente? AWT, Swing, JavaFX & SWT 0
S Swing Update eine JTabelle nach einer Drag&Drop Operation AWT, Swing, JavaFX & SWT 0
M Über eine JMenuBar überprüfen ob ein JCheckBoxMenuItem selectiert ist. AWT, Swing, JavaFX & SWT 4
M Wie kann ich eine an Apple Automator angelehnte GUI erstellen? AWT, Swing, JavaFX & SWT 1
A JavaFX Eine Task mit einer ProgressBar verbinden AWT, Swing, JavaFX & SWT 0
S JavaFX Canvas - nur eine Figur auf der Zeichenfläche färben? AWT, Swing, JavaFX & SWT 1
S Swing Mit einem Link eine Methode aufrufen AWT, Swing, JavaFX & SWT 2
C Swing Durch Inhaltsänderung eines JTextfields eine Funktion aufrufen AWT, Swing, JavaFX & SWT 5
G 2D-Slider bzw. eine graphische Auswahlkomponente die sich so verhält AWT, Swing, JavaFX & SWT 6
H Lust auf eine Open-Source Lösung für universelle Java Client-Technologie? AWT, Swing, JavaFX & SWT 11
T Aus JAVA.Jar GUI eine Flash-Datei machen AWT, Swing, JavaFX & SWT 3
S 5 Playlisten eine Skip() AWT, Swing, JavaFX & SWT 4
M SWT Browser nur eine Seite erlauben AWT, Swing, JavaFX & SWT 3
B Daten in eine JTable schreiben AWT, Swing, JavaFX & SWT 3
K GUI Elemente über eine separate Textdatei beschriften? AWT, Swing, JavaFX & SWT 4
G noch eine Frage zum EventDispachThread AWT, Swing, JavaFX & SWT 4
I Anhand ButtonGroup eine Auswahl treffen AWT, Swing, JavaFX & SWT 2
B Nach dem Öffnen des Dialogs eine Aktion ausführen. AWT, Swing, JavaFX & SWT 6
W Funktion aus einer Java Datei in eine andere einbauen AWT, Swing, JavaFX & SWT 25
A Swing Text auf eine Seite an beliebigen Orten schreiben AWT, Swing, JavaFX & SWT 6
G Swing Value von einer JScrollBar auf eine andere übertragen AWT, Swing, JavaFX & SWT 2
Rudolf Swing Wie testet man am besten eine GUI? AWT, Swing, JavaFX & SWT 3
P Swing Alle Zeilen einer Spalte (jTable) zusammen zählen und in eine eigene Zeile das Ergebnis schreiben. AWT, Swing, JavaFX & SWT 7
F GroupableTableHeader zeigt nur eine Zeile AWT, Swing, JavaFX & SWT 4
N Swing Optimale Höhe eine JTextPanes bei festgelegter Breite bestimmen AWT, Swing, JavaFX & SWT 23
R Swing Mit Swing eine throws Exception Methode öffnen AWT, Swing, JavaFX & SWT 3
M Eine Kugel nach rechts bewegen AWT, Swing, JavaFX & SWT 5
C Swing NullPointerException beim Hinzufügen von Checkboxes in eine ArrayList AWT, Swing, JavaFX & SWT 5
GUI-Programmer LayoutManager Kurze Layout Frage - eine komponente mittig? AWT, Swing, JavaFX & SWT 5
lumo SWT Zeichnen bescheunigen bzw eine allg. Frage AWT, Swing, JavaFX & SWT 8
M Auf einem Bild eine Markierung aufziehen AWT, Swing, JavaFX & SWT 3
R Eine Instanz von JPanel mehrfach hinzufügen AWT, Swing, JavaFX & SWT 2
B eine .jar erzeugen AWT, Swing, JavaFX & SWT 4
M In JField eine Kommazahl darstellen java.lang.NumberFormatException AWT, Swing, JavaFX & SWT 4
N Button on click eine andere Klasse aufrufen... AWT, Swing, JavaFX & SWT 2
M Eine nicht korrekte Darstellung bei repaint() warum? AWT, Swing, JavaFX & SWT 4
M Ein Tab eine JTabbedPane durch Button Druck öffen AWT, Swing, JavaFX & SWT 2
B Swing JButtons in eine Arraylist<JButton> einfügen AWT, Swing, JavaFX & SWT 2
aze GeneralPath wie eine Parabel: Scheitelpunkt bestimmen AWT, Swing, JavaFX & SWT 9

Ähnliche Java Themen

Neue Themen


Oben