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:

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:

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
kann es sein
, dass diese beiden Quadrate
, die in ein- und derselben paintComponent-Methode in ein- und demselben JPanel gemalt wurden
, vom Layout-Manger des aufnehmenden JFrames unterschiedlich behandelt werden??
????
?????
????
???? Ü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:

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):
Hier die JFrame mit den Zusatz-Komponenten; ich habe die Unterschiede im Code zum aller ersten Screenshot (einfaches JFrame) kommentiert:
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
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:

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:

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

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();
}
}
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