gpt4 book ai didi

java - Swing repaint() 在循环或线程中不起作用

转载 作者:行者123 更新时间:2023-11-29 10:14:00 26 4
gpt4 key购买 nike

我有以下代码:

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。我尝试单独设置一个新线程,但无济于事。我尝试了一些其他解决方案(invokelaterpaintimmediately),也无济于事。

我的目标是设置一个在屏幕上徘徊的绿点。你有什么解决办法吗?

最佳答案

您的 while (true) 正在阻止 Swing 事件线程,使应用程序进入休眠状态。

对于简单的动画和游戏循环,请使用 Swing Timer。如果您有需要在后台运行的长时间运行的代码,则使用后台线程(例如 SwingWorker),但要注意确保所有更改 Swing 组件状态的调用都应在 Swing 事件线程上完成。

例如,您可以更改为:

    while(true) {

System.out.println("x ->"+ x);
System.out.println("y ->" + y);


x = randomposition(x);
y = randomposition(y);

this.repaint();
}

为此使用了 Swing 定时器 (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的评论:

  • 事实上,您没有在 Swing 事件线程上运行 GUI,这是您应该做的事情,但您的 while true 循环仍在卡住您的绘画,因为您的无限循环阻止组件完全创建自己。
  • 如上所述,实际上您应该在 Swing 事件线程上启动所有 Swing GUI,您可以通过将 Swing 创建代码放入 Runnable 并通过 SwingUtilities 方法 invokeLater 将 Runnable 在事件线程上排队来实现。
  • 您需要在 paintComponent 覆盖中调用 super 的 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);
}

关于java - Swing repaint() 在循环或线程中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23393664/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com