2013-04-08 93 views
-2

我有一个Circle类,每个圆圈元素都有一个线程来移动jpanel中的圆。 CirclePanel类与实际的GUI是分开的,并且有一个圆形元素的向量。我需要一种重新绘制jpanel的方式,而不必每次都创建一个新的面板。 CirclePanel在GUI类中实例化,创建一个包含CirclePanel的框架。每次圆圈移动时如何重新绘制面板?谢谢 !我怎样才能引用一个扩展JPanel从另一个类的类

编辑:把一些代码

Circle类:

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(); } 

    } 

} 

这是Circle面板类:

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); 
     } 

    } 
} 
+3

没有代码,我们就像贝多芬没有耳朵...... – 2013-04-08 16:55:46

+2

你有什么迄今所做?没有表现出一点点努力的问题很少引起SO的反应。 – 2013-04-08 16:56:19

+0

为什么你需要每个圈子的线程? – Aboutblank 2013-04-08 17:16:29

回答

0

我没有看到一个明确的方法来得到你希望从发布的代码,这可能是为什么你卡住了。如果所有Circle线程都可以访问JPanel(它们有一个字段变量引用了包含JPanel的字段变量),那么您可以让它们在移动之后请求JPanel重新绘制。但我不认为这是去这里的路。

你可能想要做的是创建一个每100毫秒触发一次的javax.swing.Timer,定时器指示所有的圆圈移动。除非有其他需要让每个Circle运行在自己的Thread中,否则我认为这更简单,并且会导致更平滑的动画。一旦所有圈子都改变了他们的位置或大小,或者他们正在做的任何事情,那么定时器可以让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); 
    } 
    } 
} 
+0

感谢您的意见,但我需要在单独的java文件中创建圈子类,并且我有义务使用线程来让圈子四处移动。 – Dubioz 2013-04-08 18:17:20

+0

使Circle成为一个单独的类是微不足道的;为了简单起见,我将它变成了一个内部类只需在Circle类构造函数中传递对JPanel的引用,然后该圆就可以告诉Jpanel重绘。更好的是,你可以像我一样做事情。图形由计时器处理,但每个圆在其自己的线程中移动或修改其属性,然后当面板调用圆形绘制方法时,这些更改将变为可见。通过使Circles运行代码在自己的线程中,它们可以在没有JPanel的输入或参与的情况下进行修改。但JPanel仍然需要每隔100 ms重绘一次。 – Thorn 2013-04-08 18:39:04

相关问题