2016-11-19 69 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,因为你正在使用类的默认方法不要这样做(正如我在我的回答中解释的那样)。 –