JPanels übereinander legen

CptK

Bekanntes Mitglied
Hallo, ich habe ein JPanel auf dem etwas gezeichnet wird und bei einem bestimmten Event soll ein zweites Panel über das erste drüber gelegt werden. Dabei ist das zweite JPanel durchsichtig (also opacity des Hintergrunds = 0.5) und man soll das erste Panel noch sehen. An sich klappt das auch ganz gut, aber es gibt noch 2 Probleme:
1. Wenn ich nicht die vordefinierte Größe des JFrames nutze, sprich die Größe des Frames wird manuell geändert, werden im hinteren Panel die Sachen alle doppelt gezeichnet.

2. Wenn ich die größe des Frames verändere, während das zweite Panel angezeigt wird, wird dann nur noch das vordere Panel gezeichnet, ich hätte ja aber gerne, dass das hintere auch weiterhin sichtbar ist.

Der Code:
[CODE lang="java" title="Hinteres JPanel"]public class GamePanel extends JPanel {
private final static int PILLAR_DISTANCE = 300;
private final GameFrame frame;
private Player player;
private List<Obstacle> pillars;
private ResultPanel resultPanel; // das vordere Pane
private JLabel scoreLabel;
private int score;

public GamePanel(Dimension d, final GameFrame frame) {
this.frame = frame;
setSize(d);
setLayout(null);
init();
setVisible(true);
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
player.draw(g);
pillars.forEach(p -> p.draw(g));
}

public void onResize() {
player.setY(getHeight() / 2 - player.getHeight() / 2);
pillars.forEach(p -> p.resize(getSize()));
resultPanel.setSize(getSize());
resultPanel.onResize();
}

public void addPillar() {
pillars.add(new Obstacle(pillars.get(pillars.size() - 1).getX() + PILLAR_DISTANCE, getSize()));
}

private void init() {
resultPanel = new ResultPanel(getSize(), this);
resultPanel.setVisible(false);
add(resultPanel);

scoreLabel = new JLabel();
scoreLabel.setFont(new Font("Impact", Font.BOLD, 40));
scoreLabel.setBounds(40, 40, 150, 40);
scoreLabel.setVisible(true);
add(scoreLabel);

initGameObjects();
}

private void initGameObjects() {
score = 0;
scoreLabel.setText("" + score);

pillars = Collections.synchronizedList(new ArrayList<>());
player = new Player("rsc/flappy_bird/player.png");
player.setSize(84, 65);
player.setY(getHeight() / 2 - player.getHeight() / 2);
player.setX((int) (getWidth() * 0.3));

int x = PILLAR_DISTANCE;
for (int i = 0; i < 10; i++) {
pillars.add(new Obstacle(x + 500, getSize()));
x += PILLAR_DISTANCE;
}
pillars.forEach(p -> p.resize(getSize()));
repaint();
}

...
}[/CODE]
[CODE lang="java" title="Vorderes JPanel"]public class ResultPanel extends JPanel {
private final GamePanel panel; // das hintere Panel
private JButton restartBtn;
private JLabel crashedLabel;

public ResultPanel(Dimension d, final GamePanel panel) {
this.panel = panel;
setSize(d);
setLayout(null);
setBackground(new Color(1, 1, 1, 0.5f));
init();
}

public void onResize() {
restartBtn.setBounds(getWidth() / 2 - 50, (getHeight() / 2 - 20), 100, 40);
crashedLabel.setBounds(getWidth() / 2 - 150, (getHeight() / 5), 300, 50);
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
}

public void activate() {
setVisible(true);
restartBtn.setVisible(true);
crashedLabel.setVisible(true);
}

private void init() {
restartBtn = new JButton("restart");
restartBtn.setBounds(getWidth() / 2 - 50, (getHeight() / 2 - 20), 100, 40);
restartBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
panel.reset();
restartBtn.setVisible(false);
crashedLabel.setVisible(false);
}
});
add(restartBtn);
restartBtn.setVisible(false);

crashedLabel = new JLabel("YOU CRASHED");
crashedLabel.setFont(new Font("Impact", Font.BOLD, 50));
crashedLabel.setBounds(getWidth() / 2 - 150, (getHeight() / 5), 300, 50);
crashedLabel.setVisible(false);
add(crashedLabel);
repaint();
}
}[/CODE]
Und zur Sicherheit noch das JFrame:
Java:
public class GameFrame extends JFrame {
    private GamePanel panel; // hinteres JPanel

    public GameFrame() {
        setSize(new Dimension(800, 600));
        setLayout(null);
        panel = new GamePanel(getSize(), this);

        addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                panel.setSize(getSize());
                panel.onResize();
            }
        });

        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                // hier wird u.a. das Event getriggert, mit dem das vordere JPanel aktiviert wird
            }
        });

        add(panel);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }
 
Beste Antwort
Was den Layoutmanager angeht. Nimm mal ein Borderlayout und adde das Panel mit .add(panel, SwingConstants.CENTER);
Damit füllt das Panel die gesamte verfügbare Fläche aus, sofern du an den Seitenrändern nichts einfügst.
Das erleichtert das Handling ungemein.
In der Regel gilt: Alles, was du da manuell machst, haben andere schon gemacht, meistens besser.

Was dein setBackground angeht ...
So wie ich Swing kenne, ist es egal, welche Farbe du verwendest. So lange opaque auf true steht, wird das, was darunter liegt, nicht nochmal gezeichnet.
Das dürfte erklären (hab ich jetzt nicht explizit getestet), dass das, was darunter liegt, nur nach dem Einfügen des Panels sichtbar ist und danach - nach Größenordnung - nicht mehr.
Setz den Wert mal...

Neumi5694

Top Contributor
Was heißt "doppelt" gezeichnet? Das müsstest du ja noch nicht mal merken. Ich gehe davon aus, dass der Player an 2 verschiedenen Stellen auftaucht? Das klingt danach, als ob der Background nicht neu gezeichnet worden wäre.

Du gehst für Resize-Events einen recht umständlichen Weg (Größen bei Größenänderung des Parents manuell setzen). Wie wär's stattdessen mit der Verwendung von Layoutmanagern? Die lösen dann auch die notwendigen Events aus. Eventuell fehlt der Event, der den Aufruf von paintComponent auslöst.

Im Code hab ich die Stelle nicht finden können, an der du opaque für das Result-Panel setzt.

ps: Mit dem Keylistener wirst du wahrscheinlich nicht glücklich werden, da der nur reagiert, wenn die Komponente den Fokus hat und nicht eine ihrer Subkomponenten. Eventuell wirst du auf eine Inputmap/Actionmap ausweichen müssen.

Ich geh mal davon aus, dass das Result eine Art Overlay darstellen soll. Hier könntest du z.B. das Result als Glasspane für das Frame verwenden (blockiert alles, was darunter ist), wär vielleicht sinnvoller.
Aber ich gehe davon aus, dass die Mustervorgehensweise ein Layeredpane wäre.
 

CptK

Bekanntes Mitglied
Was heißt "doppelt" gezeichnet? Das müsstest du ja noch nicht mal merken. Ich gehe davon aus, dass der Player an 2 verschiedenen Stellen auftaucht? Das klingt danach, als ob der Background nicht neu gezeichnet worden wäre.
Ja genau, alle Objekte tauchen an 2 Stellen auf, ich verstehe aber nicht wieso. Also ich habe ja eine initiale Größe von 800 x 600. Wenn ich nichts ändere funktioniert auch alles. Wenn ich die Größe ändere, bevor das vordere Panel erscheint, so wird alles 2 mal gezeichnet und wenn ich die Größe ändere, während das vordere Panel schon da ist, ist nur noch das vordere Panel sichtbar.
Du gehst für Resize-Events einen recht umständlichen Weg (Größen bei Größenänderung des Parents manuell setzen). Wie wär's stattdessen mit der Verwendung von Layoutmanagern? Die lösen dann auch die notwendigen Events aus. Eventuell fehlt der Event, der den Aufruf von paintComponent auslöst.
Joa damit kenne ich mich nicht wirklich aus, das so zu machen war erstmal der intuitivere Weg. Ich habe schon versucht auf alle Panels repaint() an allen möglichen Stellen aufzurufen, das hat auch nicht geholfen.
Im Code hab ich die Stelle nicht finden können, an der du opaque für das Result-Panel setzt.
Einfach beim Hintergrund:
Java:
setBackground(new Color(1, 1, 1, 0.5f));
ps: Mit dem Keylistener wirst du wahrscheinlich nicht glücklich werden, da der nur reagiert, wenn die Komponente den Fokus hat und nicht eine ihrer Subkomponenten. Eventuell wirst du auf eine Inputmap/Actionmap ausweichen müssen.
Also der KeyListner macht genau das, was er soll. Da habe ich keine Probleme.
 
K

kneitzel

Gast
Das klingt etwas nach optimized Drawing.
Returns true if this component tiles its children -- that is, if it can guarantee that the children will not overlap. The repainting system is substantially more efficient in this common case. JComponent subclasses that can't make this guarantee, such as JLayeredPane, should override this method to return false.

Sprich: Bei deinen Panels einfügen:

Java:
@Override
public boolean isOptimizedDrawingEnabled()
{
    return false;
}

Das wäre zumindest ein Versuch wert.

Und das repaint erwirkt nichts, weil Du damit ja nur das System aufforderst, die Elemente neu zu zeichnen. Dinge, von denen das System ausgeht, dass diese nicht gezeichnet werden müssen, werden dann natürlich jedes Mal nicht gezeichnet.
 

Neumi5694

Top Contributor
Was den Layoutmanager angeht. Nimm mal ein Borderlayout und adde das Panel mit .add(panel, SwingConstants.CENTER);
Damit füllt das Panel die gesamte verfügbare Fläche aus, sofern du an den Seitenrändern nichts einfügst.
Das erleichtert das Handling ungemein.
In der Regel gilt: Alles, was du da manuell machst, haben andere schon gemacht, meistens besser.

Was dein setBackground angeht ...
So wie ich Swing kenne, ist es egal, welche Farbe du verwendest. So lange opaque auf true steht, wird das, was darunter liegt, nicht nochmal gezeichnet.
Das dürfte erklären (hab ich jetzt nicht explizit getestet), dass das, was darunter liegt, nur nach dem Einfügen des Panels sichtbar ist und danach - nach Größenordnung - nicht mehr.
Setz den Wert mal auf false.
 
Beste Antwort

CptK

Bekanntes Mitglied
Sprich: Bei deinen Panels einfügen:
Java:
@Override
public boolean isOptimizedDrawingEnabled()
{
    return false;
}
Das hat leider nichts bewirkt.
Was dein setBackground angeht ...
So wie ich Swing kenne, ist es egal, welche Farbe du verwendest. So lange opaque auf true steht, wird das, was darunter liegt, nicht nochmal gezeichnet.
Das dürfte erklären (hab ich jetzt nicht explizit getestet), dass das, was darunter liegt, nur nach dem Einfügen des Panels sichtbar ist und danach - nach Größenordnung - nicht mehr.
Setz den Wert mal auf false.
Das opaque hingegen hat alle Probleme gelöst.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
C LayoutManager Bei verkleinern des Fensters, verschieben sich JPanels übereinander. AWT, Swing, JavaFX & SWT 7
F Swing JPanels übereinander ohne Mananger AWT, Swing, JavaFX & SWT 1
Apfelbaum2005 Swing JFrame mehrere JPanels mit unterschiedlichen Formen hinzufügen AWT, Swing, JavaFX & SWT 1
B viele JPanels auf JLayeredPane -> to SVG? AWT, Swing, JavaFX & SWT 15
CptK JPanels wechseln AWT, Swing, JavaFX & SWT 2
B Minimum x und y von Children-JPanels ermitteln AWT, Swing, JavaFX & SWT 3
L Swing JPanels werden nicht angezeigt! AWT, Swing, JavaFX & SWT 7
P Swing Mehrere JPanels auf ein JFrame hinzufügen? AWT, Swing, JavaFX & SWT 2
A Swing JPanels dynamisch untereinander einfügen AWT, Swing, JavaFX & SWT 3
J bestimmten Bereich eines JPanels drucken AWT, Swing, JavaFX & SWT 2
R Swing JPanels auf JFrame auf verfügbaren Platz aufblasen AWT, Swing, JavaFX & SWT 4
K Swing Inhalt eines JPanels lesen AWT, Swing, JavaFX & SWT 3
R Swing Bewegung eines Graphics Objektes innerhalb eines JPanels funktioniert nicht richtig AWT, Swing, JavaFX & SWT 2
W Swing Farbige JPanels auf JFrame werden nicht gezeigt. Was mach ich falsch? AWT, Swing, JavaFX & SWT 7
N Swing CardLayout: Problem beim Wechsel zwischen den JPanels AWT, Swing, JavaFX & SWT 3
K Swing Klassenstruktur mit mehreren JPanels AWT, Swing, JavaFX & SWT 3
S Swing Navigation durch JPanels AWT, Swing, JavaFX & SWT 0
S Bei BoxLayout haben hinzugefügten Jpanels einen Versatz/Space AWT, Swing, JavaFX & SWT 0
B Größer-/Kleinerziehen eines JFrames/JPanels erkennen AWT, Swing, JavaFX & SWT 2
C Bei Btn Klick zwei JPanels switchen AWT, Swing, JavaFX & SWT 14
M Swing Aktualisieren eines JPanels nach Tasteneingabe AWT, Swing, JavaFX & SWT 2
S Liste von JPanels mit festen Höhen AWT, Swing, JavaFX & SWT 3
I Rechteck eines Graphics eines JPanels in einem anderen JPanel anzeigen AWT, Swing, JavaFX & SWT 7
S Swing Kopie eines JPanels inkl. aller objekte darin erstellen AWT, Swing, JavaFX & SWT 5
S Aufteilung von JPanels in einem Frame AWT, Swing, JavaFX & SWT 13
F Event Handling Kommunikation eines JButton ueber JPanels hinaus AWT, Swing, JavaFX & SWT 6
S Swing Drag&Drop mit TransferHandler und JPanels AWT, Swing, JavaFX & SWT 8
Jats Zeichen auf mehrere JPanels AWT, Swing, JavaFX & SWT 7
A Swing Aktualisieren eines JPanels AWT, Swing, JavaFX & SWT 13
N Abspeichern eines kompletten JPanels AWT, Swing, JavaFX & SWT 57
S Swing Zwischenräume zwischen JPanels AWT, Swing, JavaFX & SWT 4
H Verschiedene JPanels aus eigenen Klassen in JFrame einfügen, nur ein Panel sichtbar AWT, Swing, JavaFX & SWT 4
X zwischen 2 JPanels "elegant" wechseln AWT, Swing, JavaFX & SWT 3
S Swing MVC Ein JFrame, mehrere JPanels AWT, Swing, JavaFX & SWT 6
K JButtons innerhalb eines JPanels verschieben (DRAG&DROP) AWT, Swing, JavaFX & SWT 5
T jPanels im jFrame bewegen - Auch ohne Textfield? AWT, Swing, JavaFX & SWT 4
G ein JTextArea in zwei JPanels AWT, Swing, JavaFX & SWT 2
W Swing JFrame mit unterschiedlichen JPanels AWT, Swing, JavaFX & SWT 2
D Grafik über JPanels hinweg verschieben AWT, Swing, JavaFX & SWT 2
C klassenübergreifende JPanels auf ein JFrame AWT, Swing, JavaFX & SWT 22
X Alle Components eines JPanels Enablen AWT, Swing, JavaFX & SWT 7
D Swing Problem mit Gridbaglayout bzw. Größenanpassung JPanels AWT, Swing, JavaFX & SWT 7
P Swing Größe eines JPanels bestimmen (ohne Border!) AWT, Swing, JavaFX & SWT 2
0 Ausschnitt eines JPanels als Bild speichern AWT, Swing, JavaFX & SWT 4
N Richtiges einstellen der size von JPanels AWT, Swing, JavaFX & SWT 10
D LayoutManager JPanels ohne LayoutManager platzieren AWT, Swing, JavaFX & SWT 6
Weltall 7 Swing JPanels werden doppelt gezeichnet AWT, Swing, JavaFX & SWT 6
C Swing JList mit JPanels AWT, Swing, JavaFX & SWT 6
J Swing JPanels werden ständig gezeichnet AWT, Swing, JavaFX & SWT 11
C Swing Inhalt eines JPanels ermitteln & bearbeiten AWT, Swing, JavaFX & SWT 5
G Swing Komponenten dem Hintergrundbild des JPanels anpassen? AWT, Swing, JavaFX & SWT 6
N Swing GUI updaten / Aufklappbare Jpanels AWT, Swing, JavaFX & SWT 2
E Swing JPanels durch ziehen am Rand vergrößern/verkleinern?! AWT, Swing, JavaFX & SWT 2
buntuswalus Swing Datentransfer zwischen JPanels AWT, Swing, JavaFX & SWT 18
T Sichtbarmachen von Objekten auf mehreren JPanels AWT, Swing, JavaFX & SWT 2
J Swing Container innerhalb eines JPanels erfragen AWT, Swing, JavaFX & SWT 3
H Z-Order von JPanels in JFrames AWT, Swing, JavaFX & SWT 2
B Swing JFormattedTextField auf mehreren JPanels in einer JTabbedPane AWT, Swing, JavaFX & SWT 3
R Verschachtelte JPanels FocusTraversalPolicy AWT, Swing, JavaFX & SWT 6
L mehere JPanels auf JFrame - setVisible() funktioniert nicht AWT, Swing, JavaFX & SWT 3
J Swing JScrollPane fasst JPanel und Groesse des JPanels soll sich aendern AWT, Swing, JavaFX & SWT 2
H Größen von JPanels,JLable und JTextfield.. AWT, Swing, JavaFX & SWT 12
H Layoutprobleme mit Jpanels AWT, Swing, JavaFX & SWT 2
S Swing Dynamische JPanels: Vertikales Strecken verhindern AWT, Swing, JavaFX & SWT 4
Pithecanthropus Swing JPanels dynamisch austauschen AWT, Swing, JavaFX & SWT 8
J SWING Fenster mit mehreren JPanels (dank JLayeredPane) AWT, Swing, JavaFX & SWT 19
R Swing JPanel enthält mehrere JPanels - Positionsvergabe AWT, Swing, JavaFX & SWT 4
P verschiedene JPanels einblenden je nach auswahl AWT, Swing, JavaFX & SWT 2
R MousePosition über mehrere JPanels darstellen AWT, Swing, JavaFX & SWT 13
A Mehrere JPanels in ein JFrame AWT, Swing, JavaFX & SWT 4
R JFrame enthält JScrollPane mit JPanels AWT, Swing, JavaFX & SWT 3
R Mehrere JPanels in JScrollPane AWT, Swing, JavaFX & SWT 3
R JScrollPane, mehrere JPanels hinzufügen AWT, Swing, JavaFX & SWT 2
R Hinzufügen mehrer JPanels zu einem JFrame AWT, Swing, JavaFX & SWT 2
D Event beim Laden eines JPanels? AWT, Swing, JavaFX & SWT 3
A Problem beim Setzen von JPanels AWT, Swing, JavaFX & SWT 4
M Automatische Anpassung eines JPanels in einem JFrame AWT, Swing, JavaFX & SWT 6
M Anpassen der Größe eines JPanels (incl. gezeichneter Ampel) AWT, Swing, JavaFX & SWT 2
G Hilfe Meine JPanels verschwinden im Müll AWT, Swing, JavaFX & SWT 10
G Hintergrundfarbe eines JPanels zurücksetzen AWT, Swing, JavaFX & SWT 12
G Alle Komponenten eines JPanels durchlaufen AWT, Swing, JavaFX & SWT 11
G MVC Modell mit JPanels? AWT, Swing, JavaFX & SWT 1
P Problem bei Aktualisierung eines JPanels AWT, Swing, JavaFX & SWT 2
G mehrere JPanels untereinander ? AWT, Swing, JavaFX & SWT 2
M Wirkliche Größe eines JPanels/o.ä. ermitteln AWT, Swing, JavaFX & SWT 3
T Bisherige JFrames in JPanels oder JInternalFrames? AWT, Swing, JavaFX & SWT 2
M Minimieren von verschachtelten JPanels AWT, Swing, JavaFX & SWT 2
M Problem, an ImageIcon in JPanels zu kommen. AWT, Swing, JavaFX & SWT 2
G Größe eines JPanels beeinflussen AWT, Swing, JavaFX & SWT 5
S Update des fensters beim Ersetzen von JPanels AWT, Swing, JavaFX & SWT 9
S Automatisches Rendern einen JPanels AWT, Swing, JavaFX & SWT 8
S Frage: Mehrere JPanels gleichen Button zuzweisen? AWT, Swing, JavaFX & SWT 10
D JTree mit JPanels als UserObjects AWT, Swing, JavaFX & SWT 4
S Stapel aus transpareneten JPanels AWT, Swing, JavaFX & SWT 2
C Verschachtelung von JPanels mit verschiedenen LayoutManager AWT, Swing, JavaFX & SWT 4
G Auf Graphic-Context eines bestimmten JPanels zeichnen AWT, Swing, JavaFX & SWT 3
S GUI, dynamisches Wechseln von JPanels in einem JFrame AWT, Swing, JavaFX & SWT 2
A dynamisch weitere jpanels untereinander hinzufügen AWT, Swing, JavaFX & SWT 10
L Probleme mit Löschen von JPanels AWT, Swing, JavaFX & SWT 2
U Jpanels auf einem Jframe austauschen AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben