少し複雑なコンポーネントリスナーがあります。GUIの現在の状態(具体的にはコンポーネントの高さ)に応じて多くの計算が行われます。
私の知る限り、リスナーはGUIを処理するEDTとは別のスレッドで実行されるため、repaintメソッドとvalidateメソッドは、リスナーがコードを実行した後にのみ実行されます。リスナースレッドからimmedatleyを再描画する方法はありますか?
リスナーが複雑なため、SwingWorkerはオプションではありません...
少し複雑なコンポーネントリスナーがあります。GUIの現在の状態(具体的にはコンポーネントの高さ)に応じて多くの計算が行われます。
私の知る限り、リスナーはGUIを処理するEDTとは別のスレッドで実行されるため、repaintメソッドとvalidateメソッドは、リスナーがコードを実行した後にのみ実行されます。リスナースレッドからimmedatleyを再描画する方法はありますか?
リスナーが複雑なため、SwingWorkerはオプションではありません...
あなたの理解に欠陥があると思います。システムによってトリガーされたすべてのイベントは、トリガーされたスレッドからディスパッチされます。つまり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 と再同期する必要があります。