Yes*_*sha -1 java swing multithreading sleep timer
我正在尝试Thread.sleep()用java swing计时器替换,因为我听说这对于图形更好.
之前,我有这样的设置,但它干扰了图形.
while(counter < array.size){
Thread.sleep(array.get(counter).startTime);
//do first task
Thread.sleep(array.get(counter).secondTime);
//do second task
Thread.sleep(array.get(counter).thirdTime);
//do third task
counter++
}
Run Code Online (Sandbox Code Playgroud)
现在,我正在尝试Thread.sleep()用其中一个替换每个,然后我有在此之后发生的实际事件,但它似乎根本没有等待.
int test = array.get(counter).time;
ActionListener taskPerformer = new ActionListener(){
public void actionPerformed(ActionEvent evt){
}
};
Timer t = new Timer(test, taskPerformer);
t.setRepeats(false);
t.start();
Run Code Online (Sandbox Code Playgroud)
基本上,我如何确保程序等待而不给它任何代码在计时器内执行?谢谢!
答案归结为你想要实现的目标......
要记住的导入事项是,Swing是单线程环境,也就是说,期望UI的所有交互,更改,修改,更新和创建都是在事件调度线程的上下文中完成的.
任何行动阻止EDT(如sleep,wait等)将防止从EDT重绘UI或响应新事件.
实现这一目标的一种方法是通过使用 javax.swing.Timer
这是一个非常简单的例子,它使用3个链接在一起的定时器.就个人而言,我会使用一个单一的计时器配置为短暂的持续时间,并检查是否已发生所需的延迟,然后相应地更改状态,但这得到了...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SimpleTimer {
public static void main(String[] args) {
new SimpleTimer();
}
public SimpleTimer() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Timer red;
private Timer green;
private Timer yellow;
private Color color = Color.GREEN;
private Point spot;
public TestPane() {
red = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
color = Color.RED;
green.start();
repaint();
}
});
green = new Timer(2000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
color = Color.GREEN;
yellow.start();
repaint();
}
});
yellow = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
color = Color.YELLOW;
red.start();
repaint();
}
});
red.setRepeats(false);
green.setRepeats(false);
yellow.setRepeats(false);
green.start();
addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
spot = e.getPoint();
repaint();
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int radius = 20;
int x = (getWidth() - radius) / 2;
int y = (getHeight() - radius) / 2;
g2d.setColor(color);
g2d.fillOval(x, y, radius, radius);
if (spot != null) {
x = spot.x - 5;
y = spot.y - 5;
g2d.setColor(Color.RED);
g2d.drawOval(x, y, 10, 10);
g2d.setColor(Color.YELLOW);
g2d.fillOval(x, y, 10, 10);
}
g2d.dispose();
}
}
}
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用a SwingWorker,这允许在后台线程中进行某种处理(让EDT继续运行),但提供了一些方法,您可以通过这些方法将结果简单地同步回EDT.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SimpleTimer {
public static void main(String[] args) {
new SimpleTimer();
}
public SimpleTimer() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Color color = Color.GREEN;
private Point spot;
public TestPane() {
new Switcher().execute();
addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
spot = e.getPoint();
repaint();
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int radius = 20;
int x = (getWidth() - radius) / 2;
int y = (getHeight() - radius) / 2;
g2d.setColor(color);
g2d.fillOval(x, y, radius, radius);
if (spot != null) {
x = spot.x - 5;
y = spot.y - 5;
g2d.setColor(Color.RED);
g2d.drawOval(x, y, 10, 10);
g2d.setColor(Color.YELLOW);
g2d.fillOval(x, y, 10, 10);
}
g2d.dispose();
}
public class Switcher extends SwingWorker<Void, Color> {
@Override
protected void process(List<Color> chunks) {
color = chunks.get(chunks.size() - 1);
repaint();
}
@Override
protected Void doInBackground() throws Exception {
while (true) {
publish(Color.GREEN);
Thread.sleep(2000);
publish(Color.YELLOW);
Thread.sleep(500);
publish(Color.RED);
Thread.sleep(2000);
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
查看Swing中的Concurrency以获取更多详细信息