我有JFrame
和一些标签,当我按下按钮时,我想逐个显示这些标签(但延迟时间)。我尝试使用此代码:
label_1.setVisible(1000);
Thread.sleep(time);
label_2.setVisible(1000);
Thread.sleep(time);
label_3.setVisible(1000);
Thread.sleep(time);
label_4.setVisible(1000);
但应用程序会等待一段时间(4000毫秒),然后立即显示所有标签。
答案 0 :(得分:2)
这是使用swing计时器类的代码,它执行延迟以显示帧上的标签。您只需创建一个ActionListener
对象,其中包含您想要延迟执行的代码以及基本条件< / strong>用于停止计时器。然后创建一个像new Timer(Delay,ActionListenerObject)
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class LabelDelay {
JFrame frame;
JLabel label1;
JLabel label2;
JLabel label3;
JLabel label4;
JPanel contentPane;
Timer timer;
int count=0;
public LabelDelay() {
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JPanel(new GridLayout(1,4));
label1 = new JLabel("Label1");
contentPane.add(label1);
label2 = new JLabel("Label2");
contentPane.add(label2);
label3 = new JLabel("Label3");
contentPane.add(label3);
label4 = new JLabel("Label4");
contentPane.add(label4);
frame.setContentPane(contentPane);
frame.pack();
label1.setVisible(false);
label2.setVisible(false);
label3.setVisible(false);
label4.setVisible(false);
ActionListener action = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
switch(count) {
case 0:
label1.setVisible(true);
break;
case 1:
label2.setVisible(true);
break;
case 2:
label3.setVisible(true);
break;
case 3:
label4.setVisible(true);
break;
case 4:
timer.stop();//base criteria
break;
}
count++;
}
};
frame.setVisible(true);
timer = new Timer(1000, action);
timer.start();
}
public static void main(String args[]) {
new LabelDelay();
}
}
答案 1 :(得分:0)
睡眠UI线程冻结GUI,但程序在后台运行本身最终会给你结果睡眠。相反,您可以使用Executors
来实现此目的。否则,您需要使用.join()
方法创建单独的线程以等待先前的线程完成。
https://docs.oracle.com/javase/tutorial/essential/concurrency/join.html
Thread t1 = new Thread(() -> {label_1.setVisible(true); Thread.sleep(1000);});
Thread t2 = new Thread(() -> {label_2.setVisible(true); Thread.sleep(1000);});
Thread t3 = new Thread(() -> {label_3.setVisible(true); Thread.sleep(1000);});
Thread t4 = new Thread(() -> {label_4.setVisible(true); Thread.sleep(1000);});
t1.start();
t2.start();
t2.join();
t3.start();
t3.join();
t4.start();
t4.join();
此代码示例假设您使用的是Java 8
<强>更新强>
不管上面的例子,你可以使用下面的链接很好地理解Swing并发。
https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html
答案 2 :(得分:0)
此外,您可以简单地使用一个接一个地开始的四个Timer
对象
Timer timer4 = new Timer(500, e -> {
label_4.setVisible(true);
});
Timer timer3 = new Timer(500, e -> {
label_3.setVisible(true);
timer4.start();
});
Timer timer2 = new Timer(500, e -> {
label_2.setVisible(true);
timer3.start();
});
Timer timer1 = new Timer(500, e -> {
label_1.setVisible(true);
timer2.start();
});
timer1.start();
答案 3 :(得分:0)
试试这个:
public class TestFrame extends JFrame {
private JLabel labels[] = {
new JLabel("Label 1"),
new JLabel("Label 2"),
new JLabel("Label 3"),
new JLabel("Label 4")
};
private SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
@Override
protected Void doInBackground() throws Exception {
for(int i = 0; i < labels.length; i++) {
TimeUnit.MILLISECONDS.sleep(4000);
publish(i);
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
chunks.stream().forEach(i -> labels[i].setVisible(true));
}
};
public TestFrame() throws HeadlessException {
super("Test Frame");
createGUI();
}
private void createGUI() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setMinimumSize(new Dimension(300, 100));
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
Arrays.stream(labels).forEach(label -> {
label.setVisible(false);
panel.add(label);
});
add(panel, BorderLayout.CENTER);
pack();
setLocationRelativeTo(null);
addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
worker.execute();
}
});
}
}