2013-04-08 86 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

相關問題