-2

我有一个 Circle 类,每个圆形元素都有一个用于在 jpanel 中移动圆圈的线程。CirclePanel 类与实际的 GUI 是分开的,并且有一个圆形元素的向量。我需要一种方法来重新绘制 jpanel,而无需每次都创建新面板。CirclePanel 在创建包含 CirclePanel 的框架的 GUI 类中实例化。每次圆圈移动时如何重绘面板?谢谢 !

编辑:输入一些代码

圈类:

    public class Circle extends Thread {

    public Ellipse2D.Double thisCircle;
    public int size=30,xPoz,yPoz;
    Random r=new Random();
    int red=r.nextInt(255),green=r.nextInt(255),blue=r.nextInt(255);
    int deltax,deltay;
    public boolean ballStarted;


    public Circle()
    {xPoz=(int)Math.random()*300;
     yPoz=(int)Math.random()*300;
     ballStarted = true;
     deltax=-10+(int)(Math.random()*21);
     deltay=-10+(int)(Math.random()*21);
     if ((deltax == 0) && (deltay == 0)) { deltax = 1; }
     thisCircle=new Ellipse2D.Double(xPoz,yPoz,size,size);

    }


    public void draw(Graphics2D g2d){
    if(thisCircle!=null)
    {g2d.setColor(new Color(red,green,blue,80));
     g2d.fill(thisCircle);

    }  
    }

    public int PozX(){return xPoz;}
    public int PozY(){return yPoz;}
    public int radius(){return size*2;}

    public void grow(){
    size++;
    thisCircle.setFrame(xPoz,yPoz,size,size);
    }

    public void move(){
        int oldx=xPoz;
        int oldy=yPoz;

        int newx=oldx+deltax;
        int newy=oldy+deltay;

        if(newx+size>800 || newx<0)
            deltax=-deltax;
        if(newy+size>600 || newy<0)
            deltay=-deltay;

        thisCircle.setFrame(newx,newy,size,size);
    }

    public void run(){

        try {
               Thread.sleep(100); 
            }
            catch (InterruptedException e)
            {  System.out.println("Thread Halted");}
        while(ballStarted)
        {move(); }

    }

}

这是圆形面板类:

public class CirclePanel extends JPanel {

    private int prefwid, prefht;
    public ArrayList<Circle> Circles = new ArrayList<Circle>();

    public ShapePanel(int pwid, int pht) {
        prefwid = pwid;
        prefht = pht;
        createCircles();
    }

    public void createCircles() {
        for (int i = 1; i <= 20; i++) {
            Circle nextCircle = new Circle();
            Circles.add(nextCircle);
            nextCircle.start();

        }
    }

    public Dimension getPreferredSize() {
        return new Dimension(prefwid, prefht);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        for (int i = 0; i < Circles.size(); i++) {
            (Circles.get(i)).draw(g2d);
        }

    }
}
4

1 回答 1

0

我看不到从发布的代码中获取所需位置的明确方法,这可能就是您被卡住的原因。如果所有Circle线程都可以访问JPanel(它们有一个引用包含的字段变量JPanel),那么您可以让它们在移动后要求 JPanel 重新绘制。但我不认为这是去这里的方式。

您可能想要做的是创建一个每 100 毫秒触发一次的javax.swing.Timer ,并且计时器指示所有圆圈移动。除非有其他需要让每个 Circle 在自己的线程中运行,否则我认为这更简单,并且会产生更流畅的动画。一旦所有圈子都改变了它们的位置或大小或它们正在做的任何事情,那么计时器可以要求 JPanel 进行repaint().

这是我的意思的一个例子:

import java.awt.Dimension;
import javax.swing.*;
import java.util.ArrayList;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
*
* @author LLASPINA
*/
public class CirclePanel extends JPanel implements ActionListener {

  Timer timer;
  private int prefwid, prefht;
  ArrayList<Circle> circleList;

  public CirclePanel(int pwid, int pht) {
     prefwid = pwid;
     prefht = pht;
     createCircles();
     timer = new Timer(300, this);
     timer.start();
  }

  public void createCircles() {
     circleList = new ArrayList<Circle>();
     for (int i = 1; i <= 20; i++) {
        Circle nextCircle = new Circle();
        circleList.add(nextCircle);
     }
  }

  public Dimension getPreferredSize() {
     return new Dimension(prefwid, prefht);
  }

  public void paintComponent(Graphics g) {
     super.paintComponent(g);
     Graphics2D g2d = (Graphics2D) g;
     for (Circle c : circleList) {
        c.draw(g2d);
     }

  }

  public static void main(String[] args) {
     JFrame frame = new JFrame();
     CirclePanel panel = new CirclePanel(400,500);
     frame.add(panel);
     frame.setSize(400,500);
     //frame.pack();
     frame.setVisible(true);
  }

  @Override
  public void actionPerformed(ActionEvent e) {
     //move those circles and then redraw them.
  }
  class Circle {

     int x, y;
     int radius;

     public Circle() {
        this.x = (int) (Math.random() * (prefwid-10));
        this.y = (int) (Math.random() * (prefht-10));
        this.radius = (int) (Math.random() * 50) + 10;
     }

     public Circle(int x, int y, int r) {
        this.x = x;
        this.y = y;
        this.radius = r;
     }

     public void draw(Graphics2D g) {
        g.drawOval(x, y, radius, radius);
     }
  }   
}
于 2013-04-08T17:44:27.207 回答