假设您的actionPerformed
方法是在事件调度线程的上下文中调用的,在方法完成之前不会发生 UI 更新actionPerformed
,即使 usingSwingUtilities#invokeLater
也不会改变这一点,因为在actionPerformed
方法退出之前,EDT 将无法继续处理(除其他外)重绘请求。
您能做的最好的事情是启动第二个线程并从该线程内更新您的 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 中的绘画以获取更多信息。