2016-11-19 66 views
0

這是我的板類,我嘗試在GameBoard類中調用球對象,但我沒有,我的問題是沒有在屏幕上顯示球。 使用的給定延遲 屬性是corePoolSize後執行代碼 - 線程數在 保持池,即使它們是空閒如何在java swing中的屏幕上顯示球

package test2; 

public class Board extends JFrame{ 


    public static int boardWidth = 800; 
    public static int boardHeight = 800; 

    public static void main(String[] args){ 
     new Board(); 
    } 
    public Board() { 

     this.setSize(boardWidth, boardHeight); 
     this.setTitle("Ball"); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     GameBoard gb = new GameBoard(); 

     this.add(gb, BorderLayout.CENTER); 

     ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5); 

     executor.scheduleAtFixedRate(new RepaintTheBoard(this), 0L, 20L, TimeUnit.MILLISECONDS); 

     this.setVisible(true); 
    } 

} 

class RepaintTheBoard implements Runnable{ 

    Board theBoard; 

    public RepaintTheBoard(Board theBoard){ 
     this.theBoard = theBoard; 
    } 

    @Override 
    public void run() { 

     // Redraws the game board 

     theBoard.repaint(); 

    } 

} 

@SuppressWarnings("serial") 

//GameDrawingPanel is what we are drawing on 

class GameBoard extends JComponent { 

    Random rnd=new Random(); 

    public ArrayList<Ball> balls = new ArrayList<Ball>(); 

    int width = Board.boardWidth; 
    int height = Board.boardHeight; 

    public GameBoard(){ 
     for(int i=0; i<50; i++){ 

      int randomStartXPos = (int) (Math.random() * (Board.boardWidth - 40) + 1); 
      int randomStartYPos = (int) (Math.random() * (Board.boardHeight - 40) + 1); 

      balls.add(new Ball(randomStartXPos,randomStartYPos,30)); 
     } 
    } 



    public void paint(Graphics g) { 


     // Allows me to make many settings changes in regards to graphics 

     Graphics2D g2d = (Graphics2D)g; 
     g2d.setColor(Color.BLACK); 
     g2d.fillRect(0, 0, getWidth(), getHeight()); 



     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

     g2d.setPaint(new Color(rnd.nextInt(255),rnd.nextInt(255),rnd.nextInt(255))); 


     for(Ball ball : balls){ 
      ball.move(); 

      g2d.draw(ball); 

     } 



    } 

} 

這場球類,我想,我有招的問題()類

package test2; 

import java.awt.geom.Ellipse2D; 
import java.awt.geom.Rectangle2D; 

public class Ball extends Ellipse2D{ 

    int uLeftXPos, uLeftYPos; 

    int xDirection = 1; 
    int yDirection = 1; 

    int diameter; 
    int width = Board.boardWidth; 
    int height = Board.boardHeight; 

    public Ball(int randomStartXPos, int randomStartYPos, int Diam) { 
     super(); 

     this.xDirection = (int) (Math.random() * 4 + 1); 

     this.yDirection = (int) (Math.random() * 4 + 1); 

     // Holds the starting x & y position for the Rock 

     this.uLeftXPos = randomStartXPos; 

     this.uLeftYPos = randomStartYPos; 
     this.diameter = Diam; 

    } 
    public void move(){ 
     if (uLeftXPos + xDirection < 0) 
      xDirection = 1; 
     if (uLeftXPos + xDirection > width - diameter) 
      xDirection = -1; 
     if (uLeftYPos + yDirection < 0) 
      yDirection = 1; 
     if (uLeftYPos + yDirection > height - diameter) 
      yDirection = -1; 

     uLeftXPos = uLeftXPos + xDirection; 
     uLeftYPos = uLeftYPos + yDirection; 

    } 
    @Override 
    public Rectangle2D getBounds2D() { 
     // TODO Auto-generated method stub 
     return null; 
    } 
    @Override 
    public double getX() { 
     // TODO Auto-generated method stub 
     return 0; 
    } 
    @Override 
    public double getY() { 
     // TODO Auto-generated method stub 
     return 0; 
    } 
    @Override 
    public double getWidth() { 
     // TODO Auto-generated method stub 
     return 0; 
    } 
    @Override 
    public double getHeight() { 
     // TODO Auto-generated method stub 
     return 0; 
    } 
    @Override 
    public boolean isEmpty() { 
     // TODO Auto-generated method stub 
     return false; 
    } 
    @Override 
    public void setFrame(double x, double y, double w, double h) { 
     // TODO Auto-generated method stub 

    } 
} 

回答

2

你的主要問題是,你的球類擴展Shape對象,並Ellipse2D的這樣做不完全,防止全Ellipse2D的/形狀行爲。我認爲,如果不使用繼承,而是使用組合,會更好 - 讓Ball包含一個有效且完整的Ellipse2D對象,它用於幫助它繪製自己。

其他問題:

  • 你的JComponent應該的paintComponent覆蓋,不畫
  • 你應該總是打電話給你的覆蓋
  • 這不是一個好主意內超的畫法有內的程序邏輯繪畫方法,因爲你永遠無法完全控制這種方法,你也不想。最好讓你的移動方法分開,並讓繪畫方法做一件事 - 繪製組件的狀態,就是這樣。
  • 你的代碼在Swing線程中處於危險之中。考慮使用一個Swing Timer而不是一個調度執行器服務。
  • 使用SwingUtilities.invokeLater(...)

  • Swing線程上啓動GUI因爲你的球對象使用默認覆蓋大部分的方法Ellipse2D的,將自該確定形狀的位置,這些方法返回不發生移動。

  • 但是,你不想真的重寫這個對象,而是使用合成。

喜歡的東西:

class Ball { 
    private static final double ELLIPSE_W = 20; 
    private static final double ELLIPSE_H = ELLIPSE_W; 
    private int x = 0; 
    private int y = 0; 
    private Ellipse2D ellipse = new Ellipse2D.Double(x, y, ELLIPSE_W, ELLIPSE_H); 
    int uLeftXPos, uLeftYPos; 
    int xDirection = 1; 
    int yDirection = 1; 
    int diameter; 
    int width = Board.boardWidth; 
    int height = Board.boardHeight; 

    public Ball(int randomStartXPos, int randomStartYPos, int Diam) { 
     super(); 
     this.xDirection = (int) (Math.random() * 4 + 1); 
     this.yDirection = (int) (Math.random() * 4 + 1); 
     // Holds the starting x & y position for the Rock 
     this.uLeftXPos = randomStartXPos; 
     this.uLeftYPos = randomStartYPos; 
     this.diameter = Diam; 

     x = uLeftXPos; 
     y = uLeftYPos; 
     ellipse = new Ellipse2D.Double(x, y, ELLIPSE_W, ELLIPSE_H); 
    } 

    public Ellipse2D getEllipse() { 
     return ellipse; 
    } 

    public void move() { 
     if (uLeftXPos + xDirection < 0) 
      xDirection = 1; 
     if (uLeftXPos + xDirection > width - diameter) 
      xDirection = -1; 
     if (uLeftYPos + yDirection < 0) 
      yDirection = 1; 
     if (uLeftYPos + yDirection > height - diameter) 
      yDirection = -1; 
     uLeftXPos = uLeftXPos + xDirection; 
     uLeftYPos = uLeftYPos + yDirection; 
     x = uLeftXPos; 
     y = uLeftYPos; 
     ellipse = new Ellipse2D.Double(x, y, ELLIPSE_W, ELLIPSE_H); 
    } 
} 

而且在遊戲板:

class GameBoard extends JComponent { 
    Random rnd = new Random(); 
    public ArrayList<Ball> balls = new ArrayList<Ball>(); 
    int width = Board.boardWidth; 
    int height = Board.boardHeight; 

    public GameBoard() { 
     for (int i = 0; i < 50; i++) { 
      int randomStartXPos = (int) (Math.random() * (Board.boardWidth - 40) + 1); 
      int randomStartYPos = (int) (Math.random() * (Board.boardHeight - 40) + 1); 
      balls.add(new Ball(randomStartXPos, randomStartYPos, 30)); 
     } 
    } 

    public void move() { 
     for (Ball ball : balls) { 
      ball.move(); 
     } 
    } 

    @Override 
    protected void paintComponent(java.awt.Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setColor(Color.BLACK); 
     g2d.fillRect(0, 0, getWidth(), getHeight()); 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.setPaint(new Color(rnd.nextInt(255), rnd.nextInt(255), rnd.nextInt(255))); 
     for (Ball ball : balls) { 
      // ball.move(); 
      g2d.draw(ball.getEllipse()); 
     } 
    } 
} 
+0

感謝您的幫助,但我不明白爲什麼球不動? – muco

+0

OP:作爲旁邊..'int width = Board.boardWidth;'我覺得'boardWidth'(&height)應該在這裏定義並返回爲首選大小。然後,它可以簡單地添加到框架和框架打包成爲正確的大小(這將***大於板的大小,以適應框架'鍍鉻物'或裝飾)。如果沒有對代碼做出足夠的修改並解釋,我希望HFoE能夠實現這一點。 *'我不明白爲什麼球沒有移動「*你是說即使這個答案建議的變化仍然如此嗎? –

+0

@muco:因爲你的方式,球不移動擴展Ellipse2D。你的類是愚蠢的,我不是說這是一種侮辱性的方式,但是你的Ball類只知道它位於0,0的大小爲0,0,因爲你正在使用類的默認方法不要這樣做(正如我在我的回答中解釋的那樣)。 –