0

こんにちは、更新ボタンを押した後に JPanel を再描画するのに苦労しています。私の実際のアプリでは、モデルのファイルのリストを表す Jlabels があり、更新ボタンが押されるたびに、Jpanel に表示される Jlabels のリストがそれに応じて更新され、私はそれを行うのに非常に苦労したので、ここでは単純でクリーンでコンパイル可能な例を作成しました。更新ボタンが押された後、JPanel がクリーンアップされるようにします (単純にするため)。そのため、更新が EDT で呼び出されることを確認し、変更された Jpanel (panConf) で手動で無効化を行い、最高のコンプである 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) につながるコンテナには追加しないため、それに対する変更は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を使用してビューを交換します。

SwingUtilities.invokeLaterまた、 EDT で Runnable キューを使用する必要はありません。コードは、イベント スレッドで既に呼び出されています。

于 2013-10-10T16:55:05.733 に答える