Inspiriert von dieser Frage JLayeredPane with a LayoutManager Ich versuche, die JLayeredPane mit dem GridBagLayout arbeiten zu lassen.JLayeredPane und GridBagConstraints
Hier ist die individuelle LayeredPane-Klasse:
class StackConstraints {
public final int layer;
public final Object layoutConstraints;
public StackConstraints(int layer, Object layoutConstraints) {
this.layer = layer;
this.layoutConstraints = layoutConstraints;
}
}
class LXLayeredPane extends JLayeredPane {
private static final long serialVersionUID = 1946283565823567689L;
@Override
protected void addImpl(Component comp, Object constraints, int index) {
int layer = 0;
int pos = 0;
Object constr = null;
if (constraints instanceof StackConstraints) {
layer = ((StackConstraints) constraints).layer;
constr = ((StackConstraints) constraints).layoutConstraints;
} else {
layer = getLayer(comp);
constr = constraints;
}
pos = insertIndexForLayer(layer, index);
super.addImpl(comp, constr, pos);
setLayer(comp, layer, pos);
comp.validate();
comp.repaint();
}
}
Und hier ist eine einfache Demo (ähnlich wie die Standard-JLayeredPane Demo aber für die Nutzung von GridBagConstraints und gestrippt der unnötigen Sachen angepasst).
public class LayeredPaneDemo extends JPanel implements ActionListener {
private final Color[] layerColors = { Color.yellow, Color.magenta, Color.cyan, Color.red, Color.green, Color.blue };
private final JLayeredPane layeredPane;
private final List<JLabel> labels;
private JButton update;
public LayeredPaneDemo() {
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
labels = new ArrayList<>();
layeredPane = new LXLayeredPane();
layeredPane.setPreferredSize(new Dimension(400, 410));
layeredPane.setBorder(BorderFactory.createTitledBorder("Click to change colors"));
// Add several labels to the layered pane.
layeredPane.setLayout(new GridBagLayout());
for (int i = 0; i < layerColors.length; i++) {
JLabel label = createColoredLabel("Test", layerColors[i]);
labels.add(label);
layeredPane.add(label, new StackConstraints(i, gbc(i)));
}
// Add control pane and layered pane to this JPanel.
add(Box.createRigidArea(new Dimension(0, 10)));
add(createControlPanel());
add(Box.createRigidArea(new Dimension(0, 10)));
add(layeredPane);
}
private GridBagConstraints gbc(int i) {
return new GridBagConstraints(i, i, 2, 2, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 0), 0, 0);
}
// Create and set up a colored label.
private JLabel createColoredLabel(String text, Color color) {
JLabel label = new JLabel(text);
label.setVerticalAlignment(JLabel.TOP);
label.setHorizontalAlignment(JLabel.CENTER);
label.setOpaque(true);
label.setBackground(color);
label.setForeground(Color.black);
label.setBorder(BorderFactory.createLineBorder(Color.black));
label.setPreferredSize(new Dimension(240, 240));
return label;
}
// Create the control pane for the top of the frame.
private JPanel createControlPanel() {
update = new JButton("Update");
update.addActionListener(this);
update.setActionCommand("UPDATE");
JPanel controls = new JPanel();
controls.add(update);
controls.setBorder(BorderFactory.createTitledBorder("Choose Duke's Layer and Position"));
return controls;
}
@Override
public void actionPerformed(ActionEvent e) {
Color prev = labels.get(labels.size() - 1).getBackground();
for (int i = labels.size() - 1; i > 0; --i) {
labels.get(i).setBackground(labels.get(i - 1).getBackground());
labels.get(i).validate();
labels.get(i).repaint();
}
labels.get(0).setBackground(prev);
labels.get(0).validate();
labels.get(0).repaint();
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("LayeredPaneDemo2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new LayeredPaneDemo();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
}
Mein Problem ist, dass ich 6 (sechs!) Etiketten hinzufügen, aber nur 5 (fünf!) Angezeigt werden. Der 0. verschwindet einfach irgendwo. Was ist der Grund dafür?
EDIT: Die anfängliche Motivation hinter der Verfolgung ist eine (teilweise transparent) Komponente auf einem anderen, wie in diesem Bildschirm Das Etikett hat 17.00.09 transparenten Hintergrund Anzeige zu platzieren und ist auf der Oberseite platziert der Chart-Komponente. GridBagLayout ist erforderlich, um es genau in der oberen Mitte des Diagramms zu platzieren.
'Ich versuche, die JLayeredPane arbeiten mit dem GridBagLayout zu bekommen.'Warum? Das sind zwei verschiedene Konzepte. Ein geschichtetes Fenster dient zum Anzeigen von Komponenten in einer Ebene. Ein GridBagLayout wird zum Anzeigen von Komponenten in einem Panel verwendet. Was ist das genaue Problem, das Sie versuchen zu lösen? Ich sehe nicht, wie das Verhalten, das Sie erreicht haben, anders ist als das der ursprünglichen, überlagerten Fenster-Demo. – camickr
Bearbeitete die Antwort, um die Motivation zu erklären. Ich hätte Platten mit transparentem Hintergrund und dem GridBagLayout für jede andere Ebene verwenden können, aber sie wollten einfach nicht richtig funktionieren. – Mischa
'aber sie wollten einfach nicht richtig funktionieren '- das definiert das Problem nicht. Sie haben zwei mögliche Probleme: 1) mit dem Layered-Panel-Code oder 2) mit den Einschränkungen, die für das GridBagLayout in jedem Panel verwendet werden. Veröffentlichen Sie eine ordnungsgemäße [mcve], die das Problem veranschaulicht. Aus dem Bild kann ich nicht sagen, welche Komponente gestapelt ist oder was das eigentliche Problem ist. – camickr