JFrame移除JPanel并添加新的JPanel

6
我目前有一个SwingWorker,它发送HTTP请求,我重写了SwingWorker的done()方法来更改JFrame中的内容。根据从服务器返回的值,我想基本上删除所有内容并在JFrame上添加新的成员面板。
现在,我面临的问题是,当我在JFrame上调用以下方法时,它不会从JFrame中删除任何内容,也不会更改其包含在框架内的内容。
//TODO: Investigate why JFrame content pane won't repaint.
f.removeAll();
//Pass the frame f reference only into MainDisplay, it doesn't actually do anything apart from allowing a class to add a JMenuBar on the JFrame.
f.add(new MainDisplay(f)); 
f.getContentPane().invalidate();
f.getContentPane().validate();
f.getContentPane().repaint();

我目前的解决方案如下,但我宁愿更改JFrame的内容而不是加载一个新的JFrame。

f.dispose();
f=new ApplicationFrame();

我已经查看了之前在这里和Google上的答案,有些人建议使用validate()或invalidate()来调用repaint()以重绘JFrame。

任何建议/帮助将不胜感激。

编辑:我认为我需要更多地调试,因为肯定还有其他问题。


有人知道使用remove或removeAll是否会删除Frame上Panel/Panels所在的实际内存,还是只是从Frame中删除它? - unleashed
它只是从框架中移除组件。由JVM垃圾收集器“删除”内存...或者说是释放内存。GC不能保证这将在程序的生命周期内发生。此外,如果已删除的组件在程序的其他位置被引用,则它们将不会被GC回收(除非使用弱引用的特殊情况)。 - Jason
4个回答

9
例如
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MyFrame extends JFrame {

    private static final long serialVersionUID = 1L;

    public MyFrame() {
        final JPanel parentPanel = new JPanel();
        parentPanel.setLayout(new BorderLayout(10, 10));

        final JPanel childPanel1 = new JPanel();
        childPanel1.setBackground(Color.red);
        childPanel1.setPreferredSize(new Dimension(300, 40));

        final JPanel childPanel2 = new JPanel();
        childPanel2.setBackground(Color.blue);
        childPanel2.setPreferredSize(new Dimension(800, 600));

        JButton myButton = new JButton("Add Component ");
        myButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                parentPanel.remove(childPanel1);
                parentPanel.add(childPanel2, BorderLayout.CENTER);
                parentPanel.revalidate();
                parentPanel.repaint();
                pack();
            }
        });
        setTitle("My Empty Frame");
        setLocation(10, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        parentPanel.add(childPanel1, BorderLayout.CENTER);
        parentPanel.add(myButton, BorderLayout.SOUTH);
        add(parentPanel);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                MyFrame myFrame = new MyFrame();
            }
        });
    }
}

1

您正在尝试repaint()/validate() ContentPane。您是否尝试在JFrame上执行相同操作? 您还可以尝试使用JFrame#pack()


1
您可以尝试再次使用Frame.pack(),这对我有效。或者尝试以下方法之一:
Frame.setOpaque(false);
Frame.setEnabled(false);
Frame.setVisible(false);
Frame.removeAll();

1
希望这能对某人有所帮助,当时对我很有用。 - Alex

1

修改您的代码

f.setContentPane(new MainDisplay(f)); 
f.getContentPane().invalidate();
f.getContentPane().validate();
f.getContentPane().repaint();

2
嗨,isograph 你在这里发布的代码和你修改后的代码之间唯一的区别就是f.removeAll()这一行。如果你认为这对代码有重大影响,请考虑扩展你的答案并解释原因。如果你只是删除了那一行因为它是不必要的,也许可以在问题下留下评论。答案应该提出解决问题的方案。评论更适合建议改进问题或其他答案。 - Crippledsmurf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接