如何更改JFrame中的JPanel?

简单来说,有一个简单的java swing应用程序,它由JFrame和其中的一些组件组成。 其中一个组件是一个JPanel,它意味着在用户操作上被另一个JPanel所取代。

那么做这样的事情的正确方法是什么? 我试过了

panel = new CustomJPanelWithComponentsOnIt(); parentFrameJPanelBelongsTo.pack(); 

但这是行不通的。 你会build议什么?

您的使用案例,对于CardLayout来说似乎是完美的。

在卡片布局中,您可以在同一位置添加多个面板,但一次显示或隐藏一个面板。

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使用“按值复制引用”parameter passing。 所以改变一个variables不会改变传递给其他方法的引用的副本。

另外请注意JFrame在可用性的名称是非常混乱的。 添加组件或设置布局(通常)在内容窗格上执行操作。 奇怪的是,获得布局真的给你框架的布局pipe理器。

希望这段代码给你一个改变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); } } 

在用户操作上:

//你必须沿着这条线做点什么

 myJFrame.getContentPane().removeAll() myJFrame.getContentPane().invalidate() myJFrame.getContentPane().add(newContentPanel) myJFrame.getContentPane().revalidate() 

那么你可以根据需要调整你的wndow。

这一切都取决于它将如何使用。 如果您想要在这两个面板之间来回切换,请使用CardLayout。 如果你只是从第一个切换到第二个(而不是返回),那么我会使用telcontar的build议,只是将其replace。 虽然如果JPanel不是你的框架中唯一的东西,我会使用remove(java.awt.Component)而不是removeAll。

如果你在这两种情况之间的某个地方,它基本上是一个时空关系。 CardLayout将节省您的时间,但占用更多的内存,因为必须始终将这个整个其他面板保存在内存中。 但是,如果您只是在需要时更换面板并根据需要构build面板,则不必保持这种可能性,但需要更多时间进行切换。

你也可以尝试一个JTabbedPane来使用标签来代替(它比CardLayout更容易,因为它自动处理显示/隐藏)

其他人回答了这个问题。 我想build议你使用JTabbedPane而不是replace内容。 通常,应用程序的视觉元素消失或被其他内容替代是不好的。 当然,每条规则都有例外,只有你和你的用户社区才能决定最好的方法。

我有完全相同的问题! Increadible! 我find的解决scheme是:

  1. 将所有组件(JPanels)添加到容器中;
  2. 对所有的人使用setVisible(false)方法;
  3. 在用户操作上,将setVisible(true)设置为我想要显示的面板。
 // 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(),没有validation(),没有CardLayout需要。

layout.replace()答案只存在/在GroupLayoutpipe理器上工作。

其他布局pipe理器(CardLayout,BoxLayout等)不支持此function,但需要您先将RemoveLayoutComponent(然后AddLayoutComponent(再次回来。:-) [只需设置logging]

我build议你在创build框架时添加两个面板,然后通过调用setVisible(true / false)来更改可见面板。 当调用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 } 

有时你可以不使用重新validation,有时不使用重新绘制工作,我build议使用两者。

问题 :我的组件在添加到容器后没有出现。

添加组件之前,需要调用revalidate和repaint 然后才会显示在容器中。

资料来源: http : //docs.oracle.com/javase/tutorial/uiswing/layout/problems.html

只需在设置ContentPanejava 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(); ... 

你可以使用布局的replace方法:

 layout.replace(existingComponent, newComponent) 

现有的和新的组件也可以是JPanels。