有多种方法可以实现您想要的。
有很多问题你必须克服。第一个是,您绝不能在事件调度线程的上下文中执行任何耗时或阻塞的操作。这样做会阻止 Swing 处理重绘请求。
第二个是,您绝不能从除 EDT 之外的任何线程创建或修改任何 UI 组件。
最简单的方法是使用javax.swing.Timer
. 另一种方法是使用SwingWorker
.
以下示例提供了一种可以定义伪随机顺序的方法。
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestLabelDelay extends JFrame implements ActionListener {
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) {
}
TestLabelDelay frame = new TestLabelDelay();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
private List<JLabel> labels;
public TestLabelDelay() {
super("Timer");
setLayout(new GridLayout(3, 3));
labels = new ArrayList<>(25);
for (int index = 0; index < 5; index++) {
labels.add(createLabel(index));
}
add(labels.get(0));
add(labels.get(1));
add(labels.get(2));
add(labels.get(3));
add(labels.get(4));
JButton show = new JButton("Show");
add(show);
show.addActionListener(this);
}
protected JLabel createLabel(int index) {
JLabel label = new JLabel(String.valueOf(index));
label.setVisible(false);
return label;
}
public void actionPerformed(ActionEvent a) {
List<Integer> order = new ArrayList<>(5);
order.add(2);
order.add(4);
order.add(0);
order.add(3);
order.add(1);
new ShowWorker(labels, order).execute();
}
public class ShowWorker extends SwingWorker<Void, Integer> {
private List<JLabel> labels;
private List<Integer> order;
private ShowWorker(List<JLabel> labels, List<Integer> order) {
this.labels = labels;
this.order = order;
}
@Override
protected void process(List<Integer> chunks) {
for (Integer index : chunks) {
JLabel label = labels.get(order.get(index));
label.setVisible(true);
label.repaint();
}
}
@Override
protected Void doInBackground() throws Exception {
for (int index = 0; index < labels.size(); index++) {
Thread.sleep(500);
publish(index);
}
return null;
}
}
}