问题描述
我有以下的code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.text.View;
public class ex10 extends JPanel {
private int x=1;
int y=1;
//Constructor
public ex10() {
while(true) {
System.out.println("x ->"+ x);
System.out.println("y ->" + y);
x = randomposition(x);
y = randomposition(y);
this.repaint();
}
}
public int randomposition(int value) {
Random random = new Random();
if (random.nextBoolean() == true) {
if (value+1 != 500) {
value++;
}
}
else {
if (value-1 != 0) {
value--;
}
}
return value;
}
@Override
public void paintComponent(Graphics g) {
//super.paintComponent(g);
g.setColor(Color.green);
g.fillRect(x, y, 20, 20);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(new ex10());
}
}
不幸的是,当 this.repaint()
之称,是不显示的问题,但我还是得到了的System.out。的println
。我试着separatedly设置一个新的线程,但无济于事。
我尝试了一些其他的解决方案(的invokeLater
和 paintimmediately
),也无济于事。
Unfortunately, when this.repaint()
is called, the point isn't being displayed, but I still got the System.out.println
. I tried setting a new thread separatedly, but to no avail.I tried out some other solution (invokelater
, and paintimmediately
), also to no avail.
我的目标是建立一个绿色的点,这飘荡在屏幕上。
你有什么解决办法吗?
My goal is to set a green point which wanders on the screen.Do you have any solution?
推荐答案
您,而(真)
阻塞Swing事件线程将睡眠应用程序。
Your while (true)
is blocking the Swing event thread putting the application to sleep.
对于简单的动画和游戏循环,使用一个Swing计时器。如果你长时间运行code,需要在后台,然后使用一个后台线程,如SwingWorker的,但照顾,以确保该改变你的Swing组件的状态,所有调用应在摆动来完成事件线程。
For simple animation and game loop, use a Swing Timer. If you have long running code that needs to be in the background, then use a background thread such as a SwingWorker, but taking care to make sure that all calls that change the state of your Swing components should be done on the Swing event thread.
例如,你可以改变这一点:
For example, you could change this:
while(true) {
System.out.println("x ->"+ x);
System.out.println("y ->" + y);
x = randomposition(x);
y = randomposition(y);
this.repaint();
}
这个使用一个Swing定时器(javax.swing.Timer中):
to this that uses a Swing Timer (javax.swing.Timer):
int timerDelay = 20;
new Timer(timerDelay, new ActionListener(){
public void actionPerformed(ActionEvent e) {
x = randomposition(x);
y = randomposition(y);
repaint();
}
}).start();
关于DSquare的评论:
Regarding DSquare's comments:
- 事实上,你是不是在Swing事件线程上运行的GUI,是你应该做的,但你的,而真正的循环仍在冻结你的画,因为你的无限循环prevents完成创建自己的组件。
- 如上所述,你其实应该开始Swing事件线程,你可以通过通过SwingUtilities的方法放置了Swing创作code到一个Runnable和排队了Runnable在事件线程上做所有Swing GUI的,的invokeLater 。
- 您需要调用超类的paintComponent方法在你的paintComponent覆盖,这样在JPanel可以做它的看家作品的图形包括清除脏的像素。
例如,更改此:
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(new ex10());
}
这样:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(new Ex10());
}
});
}
和更改此:
@Override
public void paintComponent(Graphics g) {
//super.paintComponent(g);
g.setColor(Color.green);
g.fillRect(x, y, 20, 20);
}
这样:
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.green);
g.fillRect(x, y, 20, 20);
}
这篇关于秋千重绘()不循环或线程工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!