您
while (true)正在阻止Swing事件线程使应用程序进入睡眠状态。
对于简单的动画和游戏循环,请使用Swing计时器。如果需要长时间运行的代码需要在后台运行,请使用后台线程(例如SwingWorker),但要确保所有更改Swing组件状态的调用都应在Swing事件线程上进行。
例如,您可以更改以下内容:
while(true) { System.out.println("x ->"+ x); System.out.println("y ->" + y); x = randomposition(x); y = randomposition(y); this.repaint(); }使用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的评论:
- 确实,您不是应该在Swing事件线程上运行GUI的,但是您的while真正循环仍会冻结绘画,因为无限循环会阻止组件完全创建自身。
- 如上所述,您实际上应该在Swing事件线程上启动所有Swing GUI,您可以通过将Swing创建代码放入Runnable并通过SwingUtilities方法invokeLater对事件线程上的Runnable排队来完成。
- 您需要在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()); } });}并更改此:
@Overridepublic void paintComponent(Graphics g) { //super.paintComponent(g); g.setColor(Color.green); g.fillRect(x, y, 20, 20);}对此:
@Overridepublic void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.green); g.fillRect(x, y, 20, 20);}


