1 pièce(s) jointe(s)
[Swing] [JLayeredPane] Propagation d'un événement souris dans les couches du JLayeredPane
Bonsoir,
Je développe des interfaces graphiques en Java Swing (Java 6) dans le cadre de mon boulot.
J’ai aujourd’hui un petit souci que je ne parviens pas à résoudre, j’ai cherché (un peu) sur les forums et dans les tutoriaux, sans succès.
Voici la description de mon problème, avec un exemple simplifié pour l’illustrer :
J’ai une JFrame dans laquelle je mets un JLayeredPane (LayoutManager = NULL). Dans ce JLayeredPane, je place plusieurs panneaux (JPanel) dans des couches différentes, avec parfois des recouvrements entre panneaux. Le problème que j’ai est que les panneaux du fond continuent à réagir aux événements (par exemple clic ou survol souris) et ce, même s’ils sont cachés par des panneaux des couches supérieures du JLayeredPane.
Pour information, je me retrouve dans cette situation car j’utilise des panneaux avec un comportement style « tiroir », c'est-à-dire qu’ils coulissent temporairement à partir d'un bord au-dessus du contenu de ma JFrame.
L’exemple de code ci-dessous est très simple, il superpose 2 panneaux et le JButton du panneau du dessous continue à prendre le focus et à réagir au clic quand la souris est dans le panneau de premier niveau (les panneaux sont opaques).
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
public class EssaiJLayeredPane {
public static void main(final String[] args) {
new EssaiJLayeredPane();
}
public EssaiJLayeredPane() {
JFrame frame = new EssaiFrame();
frame.setSize(new Dimension(320, 200));
frame.setLocation(100, 50);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle(">>> ESSAI LAYERED PANE");
frame.setVisible(true);
}
static private class EssaiFrame extends JFrame {
private JLayeredPane contentPanel;
private JPanel panelDuDessous;
private JPanel panelDuDessus;
static private final Dimension C_PANEL_SIZE = new Dimension(250, 100);
public EssaiFrame() {
this.contentPanel = new JLayeredPane();
this.contentPanel.setLayout(null);
this.contentPanel.setOpaque(true);
this.setContentPane(this.contentPanel);
int layerIndex = 0;
this.contentPanel.add(this.getPanelDuDessous(), Integer.valueOf(++layerIndex));
this.contentPanel.add(this.getPanelDuDessus(), Integer.valueOf(++layerIndex));
}
private JPanel getPanelDuDessous() {
if (this.panelDuDessous == null) {
this.panelDuDessous = createPanel(C_PANEL_SIZE, Color.BLUE);
this.panelDuDessous.setLocation(10, 10);
JButton boutonDuPanelDuDessous = new JButton("Bouton du dessous");
boutonDuPanelDuDessous.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
System.out.println("Clic sur bouton du dessous");
}
});
this.panelDuDessous.add(boutonDuPanelDuDessous, BorderLayout.EAST);
}
return this.panelDuDessous;
}
private JPanel getPanelDuDessus() {
if (this.panelDuDessus == null) {
this.panelDuDessus = createPanel(C_PANEL_SIZE, Color.ORANGE);
this.panelDuDessus.setLocation(50, 30);
JButton boutonDuPanelDuDessus = new JButton("Dessus");
boutonDuPanelDuDessus.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
System.out.println("Clic sur bouton du dessus");
}
});
this.panelDuDessus.add(boutonDuPanelDuDessus, BorderLayout.EAST);
}
return this.panelDuDessus;
}
private JPanel createPanel(final Dimension size, final Color bg) {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setOpaque(true);
panel.setBackground(bg);
panel.setSize(size);
panel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
return panel;
}
}
} |
Ce comportement de propagation de l’événement est-il normal lors de superposition de panneaux ?
Y a-t-il un contournement ou une API de Swing permettant d’éviter cela (car bien sûr je voudrais que les événements souris soient pris en compte uniquement par le panneau de plus haut niveau) ?
Si vous pouvez m’aider, merci par avance de prendre le temps de répondre.
Merci