-2

少し複雑なコンポーネントリスナーがあります。GUIの現在の状態(具体的にはコンポーネントの高さ)に応じて多くの計算が行われます。

私の知る限り、リスナーはGUIを処理するEDTとは別のスレッドで実行されるため、repaintメソッドとvalidateメソッドは、リスナーがコードを実行した後にのみ実行されます。リスナースレッドからimmedatleyを再描画する方法はありますか?

リスナーが複雑なため、SwingWorkerはオプションではありません...

4

1 に答える 1

1

あなたの理解に欠陥があると思います。システムによってトリガーされたすべてのイベントは、トリガーされたスレッドからディスパッチされます。つまりfireXxxEvent、別のスレッドから手動で呼び出すと、そのスレッド コンテキストからリスナーに通知されます。ただし、すべてのシステム トリガー イベント (マウスおよびキー イベントなど) は、EDT 内から発生します。

ここで簡単なテストを...

public static void main(String[] args) {

    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {

            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException ex) {
            } catch (InstantiationException ex) {
            } catch (IllegalAccessException ex) {
            } catch (UnsupportedLookAndFeelException ex) {
            }

            JButton button =  new JButton("Click me");
            button.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Am I on the EDT = " + EventQueue.isDispatchThread());
                }
            });

            JLabel label = new JLabel("Click me");
            label.addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    System.out.println("Am I on the EDT = " + EventQueue.isDispatchThread());
                }

            });

            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            frame.add(label, gbc);
            gbc.gridy++;
            frame.add(button, gbc);

            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);

        }
    });

}

ホバークラフトポイントは有効です。時間のかかるタスクは、EDT のバックグラウンドで実行する必要があります。

必要に応じて SwingUtilities.invokeLater/invokeAndWait を使用して EDT と再同期する必要があります。

于 2012-09-29T19:20:12.180 に答える