我想在JFrame中移动一个像素,但使用Thread.Sleep(1000)方法最终导致我的JFrame崩溃。 为什么会出现这个问题? 以及如何解决它?谢谢
public class Main {
public static void main(String[] args) throws InterruptedException {
JFrame mainFrame = new JFrame("Sadra Graphics");
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SadraGraphics sadraGraphics = new SadraGraphics();
sadraGraphics.setPreferredSize((new Dimension(640,480)));
mainFrame.getContentPane().add( sadraGraphics );
mainFrame.pack();
mainFrame.setVisible(true); }}
public class SadraGraphics extends JPanel {
public void paintComponent (Graphics g){
super.paintComponent(g);
this.setBackground(Color.white);
for (int i = 0; i <=639; i++) {
g.setColor(Color.red);
g.drawLine(i, i * 3 / 4, i, i * 3 / 4);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
g.setColor(Color.white);
g.drawLine(i,i*3/4,i,i*3/4);
}
}
}
- 不要使用
Thread.sleep
.即使您要使用它,也永远不想在paintComponent
方法中使用它。 -
而是使用
javax.swing.Timer
,它将更新一些变量并每隔几毫秒重新绘制一次public SadraGraphics() { Timer timer = new Timer(1000, new ActionListener(){ public void actionPerformed(ActionEvent e) { // do something here that will refresh some variables that you // are using to paint, then call repaint() repaint(); } }); timer.start(); }
查看更多信息,请参阅如何使用摆动计时器
这里有一个简单的可运行示例
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame mainFrame = new JFrame("Sadra Graphics");
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SadraGraphics sadraGraphics = new SadraGraphics();
sadraGraphics.setPreferredSize((new Dimension(640, 480)));
mainFrame.getContentPane().add(sadraGraphics);
mainFrame.pack();
mainFrame.setVisible(true);
}
});
}
}
class SadraGraphics extends JPanel {
int x1 = 0;
int y1 = 50;
int x2 = 0;
int y2 = 200;
public SadraGraphics() {
Timer timer = new Timer(30, new ActionListener() {
public void actionPerformed(ActionEvent e) {
x1 += 2;
x2 += 2;
repaint();
}
});
timer.start();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(x1, y1, x2, y2);
}
}
旁注
- 使用
SwingUtilities.invokeLater
从 EDT 运行 Swing 应用程序。 -
paintComponent
应该protected
而不是public
不要使用
paintComonent
方法设置背景。您可以从构造函数中执行此操作,也可以通过执行此操作在paintComponent
方法中绘制背景g.setColor(Color.WHITE); g.fillRect(0, 0, getWidth(), getHeight());