gpt4 book ai didi

Java Swing : combine effects of CardLayout and JLayeredPane

转载 作者:行者123 更新时间:2023-11-30 03:01:45 25 4
gpt4 key购买 nike

我试图将一些 JPanel 放在另一个之上,完全重叠。我使用 JLayeredPane 使它们处于不同的“深度”,这样我就可以更改深度和不透明度以查看某个面​​板“位于”另一个面板的“下方”。这是我做的一个小测试,它运行正常:

    public class LayeredCardPanel extends JPanel  {

private static final String BLUE_PANEL = "blue ";
private static final String RED_PANEL = "red ";
private static final String GREEN_PANEL = "green";

private String[] panelNames = { BLUE_PANEL, RED_PANEL, GREEN_PANEL };
private Color[] panelColors = { Color.BLUE, Color.RED, Color.GREEN };

private List<JPanel> panels = new ArrayList<>();

private final int TOP_POSITION = 30;
private static final int PANELS_FIRST_POS = 10;

private JLayeredPane layeredPane;


public LayeredCardPanel() {

setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

add(createControlPanel());

layeredPane = new JLayeredPane();

////////////////////////////////////////////////////////////////
//setting layout here results in all grey, non functioning panel.
//layeredPane.setLayout(new CardLayout(0, 0));
//////////////////////////////////////////////////////////////

add(layeredPane);

//adding 3 panel
for (int i = 0; i < panelNames.length; i++) {

JPanel panel = new JPanel();
panel.setBackground(panelColors[i]);

layeredPane.add(panel);
layeredPane.setLayer(panel, PANELS_FIRST_POS + i);

panels.add(panel);
}

////////////////////////////////////////////////////////////
//setting the card here, after adding panels, works fine
layeredPane.setLayout(new CardLayout(0, 0));
//////////////////////////////////////////////////////////
}

测试结果如下:

正如您在//////注释行之间所看到的,只有当我将 CardLayout 设置为 JLayeredPane after< 时,此测试才能正常工作。/strong> 我将 JPanel 添加到其中。在我看来,JPanel 是使用默认布局管理器添加到 JLayeredPane 中的。布局(设置和更改边界以填充 JLayeredPane)由稍后应用的 CardLayout 完成。

我的问题是:虽然这按照我的需要工作,但该解决方案(使用一个布局管理器添加,然后替换它以实现我想要的布局)看起来并不是一个优雅的解决方案。我正在寻找更好的方法来做到这一点。

<小时/>

这是整个 SSCE:

    public class LayeredCardPanel extends JPanel  {

private static final String BLUE_PANEL = "blue ";
private static final String RED_PANEL = "red ";
private static final String GREEN_PANEL = "green";

private String[] panelNames = { BLUE_PANEL, RED_PANEL, GREEN_PANEL };
private Color[] panelColors = { Color.BLUE, Color.RED, Color.GREEN };

private List<JPanel> panels = new ArrayList<>();

private final int TOP_POSITION = 30;
private static final int PANELS_FIRST_POS = 10;

private JLayeredPane layeredPane;

public LayeredCardPanel() {

setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

add(createControlPanel());

layeredPane = new JLayeredPane();

add(layeredPane);

//add 3 panel
for (int i = 0; i < panelNames.length; i++) {

JPanel panel = new JPanel();
panel.setBackground(panelColors[i]);

layeredPane.add(panel);
layeredPane.setLayer(panel, PANELS_FIRST_POS + i);

panels.add(panel);
}

layeredPane.setLayout(new CardLayout());
}

private JPanel createControlPanel() {

ActionListener aListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {

if(e.getSource() instanceof JButton ) {

moveToTop(((JButton) e.getSource()).getActionCommand() );
}
}
};

JPanel controls = new JPanel();
controls.setLayout(new BoxLayout(controls, BoxLayout.Y_AXIS));

JButton blueViewBtn = new JButton(BLUE_PANEL);
blueViewBtn.setActionCommand(BLUE_PANEL);
blueViewBtn.addActionListener(aListener);
controls.add(blueViewBtn);

JButton redViewBtn = new JButton(RED_PANEL);
redViewBtn.setActionCommand(RED_PANEL);
redViewBtn.addActionListener(aListener);
controls.add(redViewBtn);

JButton greenViewBtn = new JButton(GREEN_PANEL);
greenViewBtn.setActionCommand(GREEN_PANEL);
greenViewBtn.addActionListener(aListener);
controls.add(greenViewBtn);

return controls;
}

private void moveToTop(String panelName) {

for(int i = 0; i < panelNames.length; i++) {

if(panelNames[i].equals(panelName)) {
layeredPane.setLayer(panels.get(i),TOP_POSITION);
} else {
layeredPane.setLayer(panels.get(i), PANELS_FIRST_POS + i);
}
}
}

public static void main(String[] args) {

javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {

JFrame frame = new JFrame("Layered Card Panel Simulation");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JComponent newContentPane = new LayeredCardPanel();
newContentPane.setPreferredSize(new Dimension(300,100));
frame.setContentPane(newContentPane);

frame.pack();
frame.setVisible(true);
}
});
}
}

最佳答案

基本上您没有使用 CardLayout。即使您没有 setLayout(...) 语句,您的代码也可以工作。

当您使用 CardLayout 时:

  1. 布局管理器只能跟踪您设置布局管理器后添加的卡片。
  2. 一次只显示一个组件,这是您不希望出现的情况,因为您想使用面板透明度

编辑:

当您在将面板添加到分层 Pane 之后设置 CardLayout 时,它们不会由 CardLayout 处理。结果,所有面板都保持可见。显然,所发生的一切是 CardLayout 将设置每个面板的大小以填充可用空间,以便绘画看起来可以正常工作。

当我修改您的 SSCCE 以在添加面板之前设置 CardLayout 时,CardLayout 会管理面板。因此,CardLayout 在除添加的第一个面板(在 SSCCE 中为蓝色面板)之外的所有面板上调用 setVisible(false)。因此,即使您尝试将不同的面板移到前面,您也只会看到蓝色面板。

通过对 SSCCE 进行以下更改可以轻松验证这一点:

layeredPane.setLayer(panel, PANELS_FIRST_POS + i);
System.out.println(panel.isVisible());

所以,是的,使用 CardLayout 确实是一种 hack,并且不是 CardLayout 的预期使用方式或 JLayeredPane 的预期使用方式。

JLayeredPane 实际上是与空布局一起使用,这意味着您负责设置每个组件的大小。为了获得更好的解决方案,我建议您需要将 ComponentListener 添加到分层 Pane 。然后您应该处理 componentResized(...) 事件。然后,您将迭代添加到分层 Pane 中的所有组件,并将每个组件的大小设置为等于分层 Pane 的大小。

关于Java Swing : combine effects of CardLayout and JLayeredPane,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35769412/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com