0

嗨,我在点击刷新按钮后重新绘制 JPanel 时遇到了很多麻烦,在我的真实应用程序中,我有代表模型文件列表的 Jlabels,每次点击刷新按钮时,Jpanel 中显示的 Jlabels 列表必须是相应地更新,我在做这件事时遇到了很多麻烦,所以在这里我做了一个简单的干净和可编译的例子,我希望在点击刷新按钮后,JPanel 被清理(只是为了让事情变得简单)。因此,我确保在 EDT 中调用了更新,我在 chnaged Jpanel (panConf) 上手动进行了无效,并将重新验证调用到最高的 comp,即 JFrame。没有任何效果,所以我添加了重绘,但它也没有奏效。请问你能帮帮我吗 ?

    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;

    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    public class PanRepaint extends JFrame {
        private JPanel pan1;
        private JPanel mainPanel;
        private JPanel panConf;
        private JFrame dis;
    public PanRepaint() {
        JLabel label1 = new JLabel("ZAZAZA");
        JLabel label2 = new JLabel("Label 2");
        JButton btn = new JButton("Update");
        dis = this;
        btn.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        panConf = new JPanel();
                        panConf.invalidate();
                        //dis.invalidate();
                        dis.validate();
                        dis.repaint();
                    }
                });

            }
        });
        panConf = new JPanel();
        pan1 = new JPanel();
        mainPanel = new JPanel();
        panConf.add(label1);
        panConf.add(label2);
        pan1.add(btn);
        mainPanel.add(panConf);
        mainPanel.add(pan1);
        setContentPane(mainPanel);
        this.setSize(400, 400);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args) {
        PanRepaint pr = new PanRepaint();
    }
}
4

1 回答 1

3

您在 ActionListener 的 actionPerformed 方法中创建了一个新的 JPanel,但将其添加到任何内容中,特别是您将其添加到没有容器层次结构导致顶级窗口(这里是您的 JFrame)的容器中,因此对它的更改不会反映在图形用户界面。

我怀疑你犯了一个谬误,即如果你有一个变量引用一个新对象并改变新对象的状态,这里是 panConf,你会以某种方式改变变量先前引用的原始对象的状态,但这不是Java 是如何工作的。panConf 在程序启动时引用的原始 JPanel 仍然存在,并且仍然在 GUI 中保持不变。关键是您必须了解引用变量和对象(或引用)之间的区别。这是一个关键的 Java 概念,可能需要一些努力才能完全理解,但值得付出努力。

相反,只需删除原始 panConf JPanel 持有的组件:

  btn.addActionListener(new ActionListener() {
     @Override
     public void actionPerformed(ActionEvent e) {
        // do not create a new JPanel here
        panConf.removeAll();
        panConf.revalidate();
        panConf.repaint();
     }
  });

或者更好的是,使用CardLayout交换视图。

此外,无需SwingUtilities.invokeLater在 EDT 上使用 Runnable 队列。代码已经在事件线程上被调用。

于 2013-10-10T16:55:05.733 回答