简单来说,有一个简单的java swing应用程序,它包含JFrame及其中的一些组件。其中一个组件是一个JPanel,意图在用户操作上被另一个JPanel替换。
那么,这样做的正确方法是什么?我试过了
panel = new CustomJPanelWithComponentsOnIt();
parentFrameJPanelBelongsTo.pack();
但这不起作用。你会建议什么?
答案 0 :(得分:49)
您的使用案例似乎非常适合CardLayout。
在卡片布局中,您可以在同一个位置添加多个面板,然后一次显示或隐藏一个面板。
答案 1 :(得分:24)
1)设置第一个面板:
JFrame frame=new JFrame();
frame.getContentPane().add(new JPanel());
2)更换面板:
frame.getContentPane().removeAll();
frame.getContentPane().add(new JPanel());
另请注意,您必须在事件的主题中执行此操作,以确保使用SwingUtilities.invokeLater或SwingWorker
答案 2 :(得分:17)
frame.setContentPane(newContents());
frame.revalidate(); // frame.pack() if you want to resize.
请记住,Java使用'按值复制引用'参数传递。因此,更改变量不会更改传递给其他方法的引用的副本。
另请注意,JFrame
在可用性名称中非常混乱。添加组件或设置布局(通常)会在内容窗格上执行操作。奇怪的是,获得布局确实会给你框架的布局管理器。
答案 3 :(得分:6)
希望这段代码能让您了解如何更改JFrame中的jPanel。
public class PanelTest extends JFrame {
Container contentPane;
public PanelTest() {
super("Changing JPanel inside a JFrame");
contentPane=getContentPane();
}
public void createChangePanel() {
contentPane.removeAll();
JPanel newPanel=new JPanel();
contentPane.add(newPanel);
System.out.println("new panel created");//for debugging purposes
validate();
setVisible(true);
}
}
答案 4 :(得分:5)
关于用户操作:
//你必须按照
的方式做点什么myJFrame.getContentPane().removeAll()
myJFrame.getContentPane().invalidate()
myJFrame.getContentPane().add(newContentPanel)
myJFrame.getContentPane().revalidate()
然后你可以根据需要调整你的wndow。
答案 5 :(得分:3)
这一切都取决于它的使用方式。如果您想在这两个面板之间来回切换,请使用CardLayout。如果您只是从第一个切换到第二个并且(而不是回头),那么我会使用telcontar的建议并将其替换掉。虽然如果JPanel不是你的框架中我唯一会使用的东西 remove(java.awt.Component)而不是removeAll。
如果你介于这两种情况之间,它基本上是一个时空权衡。 CardLayout将节省您的时间,但是必须始终将整个其他面板保留在内存中以占用更多内存。但是如果你只需要在需要时更换面板并按需构建它,你就不必保持这种状态,但需要更多的时间来切换。
你也可以尝试使用JTabbedPane代替标签(它比CardLayout更容易,因为它可以自动处理显示/隐藏)
答案 6 :(得分:1)
其他人回答了这个问题。我想建议您使用JTabbedPane而不是替换内容。作为一般规则,使应用程序的可视元素消失或被其他内容替换是不好的。当然,每条规则都有例外,只有您和您的用户社区才能决定最佳方法。
答案 7 :(得分:1)
我遇到了完全相同的问题!! Increadible!我找到的解决方案是:
// Hiding all components (JPanels) added to a container (ex: another JPanel)
for (Component component : this.container.getComponents()) {
component.setVisible(false);
}
// Showing only the selected JPanel, the one user wants to see
panel.setVisible(true);
没有revalidate(),没有validate(),也没有需要CardLayout。
答案 8 :(得分:1)
答案 9 :(得分:1)
Game game = new Game();
getContentPane().removeAll();
setContentPane(game);
getContentPane().revalidate(); //IMPORTANT
getContentPane().repaint(); //IMPORTANT
答案 10 :(得分:0)
我建议您在创建帧时添加两个面板,然后通过在两者上调用setVisible(true / false)来更改可见面板。 调用setVisible时,将通知父级并要求重新绘制自己。
答案 11 :(得分:0)
class Frame1 extends javax.swing.JFrame {
remove(previouspanel); //or getContentPane().removeAll();
add(newpanel); //or setContentPane(newpanel);
invalidate(); validate(); // or ((JComponent) getContentPane()).revalidate();
repaint(); //DO NOT FORGET REPAINT
}
有时你可以在不使用重新验证的情况下完成工作,有时不使用重绘。我建议同时使用。
答案 12 :(得分:0)
在设置ContentPane
,(java 1.7
,可能更旧)后,只需调用 pack()方法,如下所示:
JFrame frame = new JFrame();
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
....
frame.setContentPane(panel1);
frame.pack();
...
frame.setContentPane(panel2);
frame.pack();
...
答案 13 :(得分:-1)
您可以使用布局的替换方法:
layout.replace(existingComponent, newComponent)
现有的和新的组件也可以是JPanel。