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

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

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

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

有帮助吗?

解决方案

您的使用案例似乎非常适合 CardLayout

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

其他提示

1)设置第一个面板:

JFrame frame=new JFrame();
frame.getContentPane().add(new JPanel());

2)更换面板:

frame.getContentPane().removeAll();
frame.getContentPane().add(new JPanel());

另请注意,您必须在Event的主题中执行此操作,以确保使用 SwingUtilities.invokeLater SwingWorker

frame.setContentPane(newContents());
frame.revalidate(); // frame.pack() if you want to resize.

请记住,Java使用'按值复制引用'参数传递。因此,更改变量不会更改传递给其他方法的引用的副本。

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

希望这段代码能让您了解如何更改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 的建议并只是替换它。虽然如果JPanel不是你的框架中我唯一会使用的东西 删除(java .awt.Component)而不是removeAll。

如果你介于这两种情况之间,它基本上是一个时空权衡。 CardLayout将节省您的时间,但是必须始终将整个其他面板保留在内存中以占用更多内存。但是如果你只需要在需要时更换面板并按需构建它,你就不必保持这种状态,但需要更多的时间来切换。

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

其他人回答了这个问题。我想建议您使用JTabbedPane而不是替换内容。作为一般规则,使应用程序的可视元素消失或被其他内容替换是不好的。当然,每条规则都有例外,只有您和您的用户社区才能决定最佳方法。

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

您需要调用重新验证重新粉饰 在您的容器中添加组件之后 >。

来源: http://docs.oracle.com/javase/教程/ uiswing /布局/ problems.html

我遇到了完全相同的问题!! 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。

layout.replace()答案仅存在于GroupLayout Manager上。

其他LayoutManagers(CardLayout,BoxLayout等)不支持此功能,但要求您首先删除PlaceLayoutComponent(然后再添加AddLayoutComponent(再次返回。:-) [直接设置记录]

我建议您在创建帧时添加两个面板,然后通过在两者上调用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

}

有时你可以在不使用重新验证的情况下完成工作,有时不使用重绘。我建议同时使用。

在设置 ContentPane 之后调用方法 pack(),( 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)

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top