验证或重新绘制此案例?

时间:2013-10-10 16:53:13

标签: java swing jpanel

嗨我在点击刷新按钮后重绘JPanel有很多麻烦,在我的真实应用程序中我有Jlabels表示模型的文件列表,每次刷新按钮被点击的Jlabels列表Jpanel必须相应地更新,我在做这件事时遇到了很多麻烦,所以在这里我做了一个简单干净且可编译的例子,我希望在点击刷新按钮之后,清理JPanel(只是为了让事情变得简单)。所以我确保在EDT中调用更新,我在chnaged Jpanel(panConf)上手动执行了无效,并且我将revalidate调用到最高的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();
    }
}

1 个答案:

答案 0 :(得分:3)

您在ActionListener的actionPerformed方法中创建了一个新的JPanel,但是将其添加到任何内容,特别是您将其添加到容器层次结构通向顶级窗口(此处为您的JFrame)的容器中,因此对它的更改不会是反映在GUI中。

我怀疑你是在谬论下,如果你有一个变量引用一个新对象并改变新对象的状态,这里是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 来交换视图。

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