本文介绍了秋千重绘()不循环或线程工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的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);
}

这篇关于秋千重绘()不循环或线程工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 17:17