[英]move a pixel in Jframe and crash JFrame when use Thread.Sleep(1000)
I want to move a pixel in a JFrame but use of Thread.Sleep(1000) method eventuate to crash my JFrame. 我想在JFrame中移动像素,但是使用Thread.Sleep(1000)方法最终会导致JFrame崩溃。 why this problem happen?
为什么会出现这个问题? and how solve it?
以及如何解决? Thank You
谢谢
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
. Thread.sleep
。 Even if you were to use it, you never want to use it in the paintComponent
method. paintComponent
方法中使用它。 Instead use a javax.swing.Timer
, that will update some variables and repaint every so many milliseconds 而是使用
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(); }
See more at How to use Swing Timers 在如何使用Swing计时器中查看更多信息
Here a simple runnable example 这是一个简单的可运行示例
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);
}
}
Side Note 边注
SwingUtilities.invokeLater
. SwingUtilities.invokeLater
从EDT运行Swing应用程序。 paintComponent
should be protected
not public
paintComponent
应该被protected
而不是public
Don't set the background from with the paintComonent
method. 不要使用
paintComonent
方法设置背景。 You can either do it from the constructor or instead you can paint the background in the paintComponent
method by doing this 您可以从构造函数中执行此操作,也可以通过执行以下操作在
paintComponent
方法中绘制背景
g.setColor(Color.WHITE); g.fillRect(0, 0, getWidth(), getHeight());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.