说得简单,有一个简单的Java Swing应用程序,包括JFrame的,在它的一些组成部分。组分之一是,意在通过对用户操作的另一个的JPanel替换一个JPanel。
那么,什么是做这种事情的正确方法是什么?我试过了
panel = new CustomJPanelWithComponentsOnIt();
parentFrameJPanelBelongsTo.pack();
但是这将无法正常工作。您有什么建议?
您的使用情况下,似乎是完美的CardLayout。
在卡片布局,您可以在同一时间在同一个地方添加多个面板,但随后显示或隐藏,一个面板。
该layout.replace()答案只存在/工程对的GroupLayout管理器。
其他布局管理(CardLayout,BoxLayout的等),不支持此功能,但要求你先中的removeLayoutComponent(然后addLayoutComponent方法(回来了。:-) [只设置打抱不平]
我建议你到两个面板的边框添加创建,然后通过调用调用setVisible两个(真/假)改变显示的面板。当调用调用setVisible,父母将被通报,并要求重绘自己。
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
}
有时候,你可以做的工作,而无需使用重新验证,有时甚至不使用repaint.My劝同时使用。
只需设置ContentPane
,(java 1.7
,也许以上)这样以后调用该方法包():
JFrame frame = new JFrame();
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
....
frame.setContentPane(panel1);
frame.pack();
...
frame.setContentPane(panel2);
frame.pack();
...
您可以使用替代的布局的方法:
layout.replace(existingComponent, newComponent)
现有的和新的组件可以JPanels了。
1)设置第一面板:
JFrame frame=new JFrame();
frame.getContentPane().add(new JPanel());
2)更换面板:
frame.getContentPane().removeAll();
frame.getContentPane().add(new JPanel());
另请注意,您必须在事件的线程做到这一点,以确保这一使用SwingUtilities.invokeLater或SwingWorker
frame.setContentPane(newContents());
frame.revalidate(); // frame.pack() if you want to resize.
请记住,Java的“按值复制引用”参数传递使用。因此,改变传递给其他方法参考变量不会改变副本。
还要注意JFrame
在可用性方面的名称非常混乱。添加组件或设置布局(通常)对所述内容窗格中的操作。奇怪的是,越来越布局确实给你的框架的布局管理器。
希望这一段代码给你改变一个JFrame内jPanels的想法。
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);
}
}
在用户操作:
//你必须做的线沿线的东西
myJFrame.getContentPane().removeAll()
myJFrame.getContentPane().invalidate()
myJFrame.getContentPane().add(newContentPanel)
myJFrame.getContentPane().revalidate()
然后,您可以根据需要调整窗口的大小。
这一切都取决于它如何去使用。如果你将要来回切换这两个板之间,然后使用CardLayout。如果你只从第一次切换到第二和(而不是回去),那么我会用telcontars建议,只需更换它。如果JPanel的是虽然不是在你的框架我唯一会改用的removeAll的remove(java.awt.Component)。
如果你在某处这两种情况下它基本上是一个时间和空间之间的权衡。该CardLayout将节省您的时间,但由于必须保持这整个其他面板内存在任何时候都占用更多的内存。但是,在需要的时候,如果你只是更换面板和构建它的需求,你不必记住这meory左右,但它需要更多的时间来进行切换。
你也可以尝试JTabbedPane中使用的标签,而不是(它的,因为它处理显示出比CardLayout更容易/隐藏automitically)
其他人回答了这个问题。我想建议你使用,而不是更换内容的JTabbedPane的。作为一般规则,它是坏的有应用程序的视觉元素消失或者被其他内容替换。当然,也有例外的每一个规则,只有你和你的用户社区可以决定的最佳方法。
问题:我已经把它添加到容器后,我的分量不会出现。
你需要添加一个组件后调用revalidate和repaint之前它会在你的容器出现。
来源:http://docs.oracle.com/javase/tutorial/uiswing/layout/problems.html
我有完全相同的问题! 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);
没有重新验证(),没有的validate(),没有CardLayout需要。