【问题标题】:How do I remove an old JPanel and add a new one?如何删除旧的 JPanel 并添加新的?
【发布时间】:2011-01-30 01:37:44
【问题描述】:

我想从窗口 (JFrame) 中删除一个旧的 JPanel 并添加一个新的。我该怎么做?

我尝试了以下方法:

public static void showGUI() {
    JFrame frame = new JFrame("Colored Trails");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       
    frame.add(partnerSelectionPanel);
    frame.setSize(600,400);
    frame.setVisible(true);
}

private static void updateGUI(final int i, final JLabel label, final JPanel partnerSelectionPanel) {
    SwingUtilities.invokeLater( 
        new Runnable() {
            public void run() {
                label.setText(i + " seconds left.");
            }
            partnerSelectionPanel.setVisible(false); \\ <------------
        }
    );
}

我的代码更新了“旧”JPanel,然后它使整个 JPanel 不可见,但它不起作用。编译器抱怨&lt;------------ 指示的行。它写道:&lt;identifier&gt; expected, illegal start of type

添加:

我已经成功完成了我需要做的事情,并且我通过以下方式做到了:

public static void showGUI() {
    frame = new JFrame("Colored Trails");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       
    frame.add(partnerSelectionPanel);
    //frame.add(selectionFinishedPanel);
    frame.setSize(600,400);
    frame.setVisible(true);
}

public static Thread counter = new Thread() {
    public void run() {
        for (int i=4; i>0; i=i-1) {
            updateGUI(i,label);
            try {Thread.sleep(1000);} catch(InterruptedException e) {};
        }
        partnerSelectionPanel.setVisible(false);
        frame.add(selectionFinishedPanel);
    }
};

它有效,但在我看来它不是一个安全的解决方案,原因如下:

  1. 我从另一个线程更改并添加元素到 JFrame。
  2. 在我已经“打包”了 JFrame 并使其可见之后,我向 JFrame 添加了一个新的 JPanel。

我应该这样做吗?

【问题讨论】:

    标签: java swing user-interface jpanel visibility


    【解决方案1】:

    你可以使用

      Frame.setContentPane(jPanel);
    

    【讨论】:

      【解决方案2】:

      不要忘记或忽略使用布局的方法,即 CardLayout 作为框架布局,以允许这种类型的行为(例如,这是一个“向导”的好策略)。这样做的一个优点是它不会导致任何奇怪的闪光或绘图效果,因为这就是这个布局的目的——允许一个面板被换出,假设它们具有专有的“房地产”或可以共享相同的区域(即类似“向导”的行为。)

      【讨论】:

        【解决方案3】:

        setVisible(false),即使在正确的位置,也不会真正从容器中移除面板。如果要更换面板,请执行以下操作:

        frame.getContentPane().remove(partnerSelectionPanel);
        frame.add(new JPanel());
        frame.getContentPane().invalidate();
        frame.getContentPane().validate();
        

        请注意,frame.getContentPane().add(Component) 与 frame.add(Component) 相同 - 组件实际上包含在内容窗格中。

        【讨论】:

        • Russ Hayward,在 JFrame 已经打包并设置为可见之后,是否可以删除和添加 JPanel?我应该在事件调度线程中添加和删除 JPanel 吗?
        • 在我用frame.getContentPane().remove(partnerSelectionPanel); 替换partnerSelectionPanel.setVisible(false); 后,我的程序停止删除旧框架(即使我最后使用invalidate)。
        • 是的,添加、删除和创建组件应该在 EDT 上进行。我错过了一个验证电话——我不记得那些了!如果您添加无效和验证应该可以工作。
        • 请记住 Visible 访问器,这些访问器有助于使用户看到“随机播放”或大量闪烁,因为任何特定组件不仅更新,而且更新某些组件同时它们是 setVisible(false) 可以显着提高性能——实际上,这种策略的有用性甚至成功似乎因组件而异,甚至在不同版本的 JDK 之间也有所不同,也不要忘记你可以在之后重新“打包”框架你已经交换了面板。
        【解决方案4】:
        partnerSelectionPanel.setVisible(false); \\ <------------
        

        这一行实际上是方法运行之外的。

        你可能想要这样的东西:

        public void run() {
           label.setText(i + " seconds left.");
           try {
              Thread.sleep (i * 1000);
           } catch (InterruptedException e) {
              handleException (e);
           }
           partnerSelectionPanel.setVisible(false);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-08-28
          • 2018-12-13
          • 2015-11-06
          • 1970-01-01
          • 1970-01-01
          • 2012-12-07
          • 1970-01-01
          相关资源
          最近更新 更多