メソッドがイベントディスパッチスレッドのコンテキスト内で呼び出されていると仮定すると、メソッドが競合actionPerformed
するまでUIの更新は発生しません。メソッドが終了するまで、EDTはそれを変更できないため、使用しても変更されません。 (とりわけ)再描画要求の処理を続行します。actionPerformed
SwingUtilities#invokeLater
actionPerformed
最善の方法は、2番目のスレッドを開始し、そのスレッド内からUIコンポーネントを更新することです...ただし、SwingUtilities#invokeLater
EDT外のUIコンポーネントは絶対に更新しないため、使用を強制されます。
ただし、利点は、EDTが再描画要求の処理を開始するためにスレッドが競合する必要がないことです。
例で更新
public class SwingThreadUpdate {
public static void main(String[] args) {
new SwingThreadUpdate();
}
public SwingThreadUpdate() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new BlinkPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class BlinkPane extends JPanel {
private JLabel label;
private JButton button;
public BlinkPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridy = 0;
label = new JLabel("Blinky");
label.setBackground(Color.RED);
button = new JButton("Click me");
add(label, gbc);
gbc.gridy++;
add(button, gbc);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
button.setEnabled(false);
new Thread(new BlinkTask(BlinkPane.this)).start();
}
});
}
private void setBlink(boolean blink) {
label.setOpaque(blink);
}
private void reset() {
button.setEnabled(true);
label.setOpaque(false);
}
}
public class BlinkTask implements Runnable {
private BlinkPane blinkPane;
protected BlinkTask(BlinkPane blinkPane) {
this.blinkPane = blinkPane;
}
@Override
public void run() {
Blink blinkOn = new Blink(blinkPane, true);
Blink blinkOff = new Blink(blinkPane, false);
for (int index = 0; index < 10; index++) {
if (index % 2 == 0) {
SwingUtilities.invokeLater(blinkOn);
} else {
SwingUtilities.invokeLater(blinkOff);
}
try {
Thread.sleep(125);
} catch (InterruptedException ex) {
}
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
blinkPane.reset();
}
});
}
}
public class Blink implements Runnable {
private BlinkPane blinkPane;
private boolean blink;
public Blink(BlinkPane blinkPane, boolean blink) {
this.blinkPane = blinkPane;
this.blink = blink;
}
@Override
public void run() {
blinkPane.setBlink(blink);
blinkPane.repaint();
}
}
}
詳細については、AWTおよびSwingでのPaintingを一読してください。