问题描述
我试图将一个JPanel
放在另一个之上,完全重叠.我使用JLayeredPane
将它们设置为不同的深度",因此可以更改深度和不透明度,以查看某个面板在另一个"下方.这是我所做的一个小测试,可以正常运行:
I am trying to place some JPanel
s one on top of the other, completely overlapping.I use JLayeredPane
to have them in different "depth" so I can change the depth and opacity to see a certain panel "under" another.Here is a small test I did which is working properly:
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));
//////////////////////////////////////////////////////////
}
测试结果如下:
The test result looks like this:
正如您在//////注释行之间看到的那样,仅当我在添加JPanel
s后将CardLayout
设置为JLayeredPane
后,此测试才能正常工作做到这一点.在我看来,JPanel
是使用默认布局管理器添加到JLayeredPane
的.布局(设置和更改边界以填充JLayeredPane
)由稍后应用的CardLayout
完成.
As you can see in between the ////// commented line, this test works fine only if I set CardLayout
to the JLayeredPane
after I add the JPanel
s to it.It seems to me that the JPanel
s are added to the JLayeredPane
using the default layout manager. The layout (setting and changing bounds to fill the JLayeredPane
) is done by the later-applied CardLayout
.
我的问题是:尽管这可以按我的需要工作,但解决方案(使用一个布局管理器添加,然后替换它以实现所需的布局)看起来不是一个很好的解决方案.我正在寻找更好的方法来做到这一点.
My question is: although this is working as I need, the solution (using one layout manager to add, and then replacing it to achieve the layout I want) does not look an elegant solution. I am looking for better ways to do it.
这是整个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);
}
});
}
}
推荐答案
我应用的解决方案如下:我更改了承包商,因此layeredPane使用自定义布局管理器Layout()
:
The solution I applied is the following: I changed the contractor so layeredPane uses custom layout manager Layout()
:
public LayeredCardPanel() {
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
add(createControlPanel());
layeredPane = new JLayeredPane();
layeredPane.setLayout(new Layout());
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);
}
}
Layout()
扩展了CardLayout
覆盖了addLayoutComponent
却什么也不做:
Layout()
extends CardLayout
overriding addLayoutComponent
to do nothing:
class Layout extends CardLayout{
@Override
public void addLayoutComponent(String name, Component comp) {
// override to do nothing
}
}
这篇关于Java Swing:结合CardLayout和JLayeredPane的效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!