【问题标题】:JFrame removing JPanels and adding a new JPanelJFrame 删除 JPanel 并添加新的 JPanel
【发布时间】:2011-11-23 19:44:53
【问题描述】:

我目前有一个发送 HTTP 请求的 SwingWorker,我重写了 SwingWorker 的 done() 方法来更改 JFrame 中的内容。我想基本上删除所有内容并根据从服务器返回的值在 JFrame 上添加一个新成员面板。

现在,我面临的问题是,当我在 JFrame 上调用以下方法时,它不会从 JFrame 中删除任何内容,也不会更改其包含在 Frame 中的内容。

//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 的内容,而不是加载一个新的。

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

我在此处和 Google 上查看了以前的答案,并且某些状态使用 validate() 或 invalidate() 同时调用 repaint() 来重绘 JFrame。

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

编辑:我想我会进行更多调试,因为肯定还有其他问题。

【问题讨论】:

  • 有谁知道使用 remove 或 removeAll 是否会删除框架上的面板/面板的实际内存?还是只是将其从框架中删除?
  • 它只是从框架中删除组件。由 JVM 垃圾收集器来“删除”内存……或者更确切地说,释放内存。 GC 不保证这会在程序的生命周期内发生。此外,如果被删除的组件在程序的其他地方被引用,那么它们将不会被 GC(除非在特殊情况下使用弱引用)。

标签: java swing jframe repaint


【解决方案1】:

例如

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();
            }
        });
    }
}

【讨论】:

    【解决方案2】:

    您正在尝试repaint()/validate() ContentPane。您是否尝试在JFrame 上做同样的事情? 你也可以试试JFrame#pack()

    【讨论】:

      【解决方案3】:

      修改你的代码

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

      【讨论】:

      • 您好 isograph 您在此处发布的代码与您修改的代码之间的区别仅在于f.removeAll() 这一行。如果您觉得这对代码有重大影响,请考虑扩展您的答案以解释原因。如果您只是因为没有必要而删除了该行,则可以对问题发表评论。答案应该提出问题的解决方案。评论更适合建议对问题或其他答案的改进。
      【解决方案4】:

      您可以尝试再次使用Frame.pack(),它对我有用。或尝试以下一种方法:

      Frame.setOpaque(false);
      Frame.setEnabled(false);
      Frame.setVisible(false);
      Frame.removeAll();
      

      【讨论】:

      • 希望对某人有所帮助,当时对我很有用
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-30
      • 2013-08-08
      • 1970-01-01
      相关资源
      最近更新 更多