如何动态更改JFrame中的JPanel?

时间:2008-10-20 11:53:42

标签: java swing jpanel layout-manager cardlayout

简单来说,有一个简单的java swing应用程序,它包含JFrame及其中的一些组件。其中一个组件是一个JPanel,意图在用户操作上被另一个JPanel替换。

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

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

但这不起作用。你会建议什么?

14 个答案:

答案 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.invokeLaterSwingWorker

答案 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!我找到的解决方案是:

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

问题:将我的组件添加到容器后,我的组件才会显示。

您需要在中添加组件之后再调用,然后才能在容器中显示

来源:revalidate

答案 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。