如何在java swing中在屏幕上显示球
这是我的棋盘类,我尝试在GameBoard类中调用ball对象,但我没有,我的问题是没有在屏幕上显示ball。 用于在给定延迟后执行代码 该属性是corePoolSize—要保留的线程数 游泳池,即使他们是空闲的如何在java swing中在屏幕上显示球,java,swing,Java,Swing,这是我的棋盘类,我尝试在GameBoard类中调用ball对象,但我没有,我的问题是没有在屏幕上显示ball。 用于在给定延迟后执行代码 该属性是corePoolSize—要保留的线程数 游泳池,即使他们是空闲的 package test2; public class Board extends JFrame{ public static int boardWidth = 800; public static int boardHeight = 800; publ
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);
}
}
}
包测试2;
公共类板扩展JFrame{
公共静态int boardWidth=800;
公共静态内板高度=800;
公共静态void main(字符串[]args){
新董事会();
}
公共委员会(){
此.setSize(板宽、板高);
这是一个标题(“球”);
此.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GameBoard gb=新GameBoard();
添加(gb,BorderLayout.CENTER);
ScheduledThreadPoolExecutor executor=新的ScheduledThreadPoolExecutor(5);
executor.scheduleAtFixedRate(新重新绘制板(此),0升,20升,时间单位为毫秒);
此.setVisible(true);
}
}
类重新绘制Board实现Runnable{
董事会;
公共重新绘制板(Board-theBoard){
this.theBoard=theBoard;
}
@凌驾
公开募捐{
//重新绘制游戏板
重新粉刷();
}
}
@抑制警告(“串行”)
//GameDrawingPanel是我们正在绘制的
类GameBoard扩展JComponent{
随机rnd=新随机();
public ArrayList balls=new ArrayList();
int width=Board.boardWidth;
int height=Board.boardHeight;
公共游戏局(){
用于(int i=0;i宽度-直径)
xDirection=-1;
如果(uLeftYPos+yDirection<0)
y方向=1;
如果(uLeftYPos+Y方向>高度-直径)
y方向=-1;
uLeftXPos=uLeftXPos+xDirection;
uLeftYPos=uLeftYPos+yDirection;
}
@凌驾
公共矩形2D getBounds2D(){
//TODO自动生成的方法存根
返回null;
}
@凌驾
公共双getX(){
//TODO自动生成的方法存根
返回0;
}
@凌驾
公共双盖{
//TODO自动生成的方法存根
返回0;
}
@凌驾
公共双getWidth(){
//TODO自动生成的方法存根
返回0;
}
@凌驾
公众双倍身高(){
//TODO自动生成的方法存根
返回0;
}
@凌驾
公共布尔值为空(){
//TODO自动生成的方法存根
返回false;
}
@凌驾
公共无效设置框(双x、双y、双w、双h){
//TODO自动生成的方法存根
}
}
您的主要问题是Ball类扩展了一个形状对象Ellipse2D,但扩展不完全,从而阻止了完整的Ellipse2D/Shape行为。我认为最好不要使用继承,而应该使用组合——让Ball包含一个有效且完整的Ellipse2D对象,它用来帮助自己绘制
其他问题:
- JComponent应该覆盖paintComponent,而不是paint
- 您应该始终在覆盖中调用super的绘制方法
- 在绘制方法中包含程序逻辑不是一个好主意,因为您永远无法完全控制该方法,也不想完全控制它。最好将移动方法分开,让绘制方法做一件事——绘制组件的状态,就是这样
- 您的代码使用Swing线程绕过了危险。考虑使用Swing定时器,而不是预定的执行器服务。<李>
- 使用
SwingUtilities.invokeLater(…)
- 由于Ball对象对大多数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);
}
}
班级舞会{
专用静态最终双椭圆W=20;
私有静态最终双椭圆_H=椭圆_W;
私有整数x=0;
私有整数y=0;
私有Ellipse2D椭圆=新的Ellipse2D.Double(x,y,椭圆W,椭圆H);
国际uLeftXPos、uLeftYPos;
int xDirection=1;
int-yDirection=1;
内径;
int width=Board.boardWidth;
int height=Board.boardHeight;
公共球(int-randomStartXPos、int-randomStartYPos、int-Diam){
超级();
this.xDirection=(int)(Math.random()*4+1);
this.yDirection=(int)(Math.random()*4+1);
//保持岩石的起始x&y位置
this.uLeftXPos=randomStartXPos;
this.uLeftYPos=randomStartYPos;
直径=直径;
x=uLeftXPos;
y=uLeftYPos;
椭圆=新椭圆2d.Double(x,y,椭圆W,椭圆H);
}
公共Ellipse2D getEllipse(){
返回椭圆;
}
公开作废动议(){
如果(uLeftXPos+xDirection<0)
xDirection=1;
如果(uLeftXPos+XD方向>宽度-直径)
xDirection=-1;
如果(uLeftYPos+yDirection<0)
y方向=1;
如果(uLeftYPos+Y方向>高度-直径)
y方向=-1;
uLeftXPos=uLeftXPos+xDirection;
uLeftYPos=uLeftYPos+yDirection;
x=uLeftXPos;
y=uLeftYPos;
椭圆=新椭圆2d.Double(x,y,椭圆W,椭圆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());
}
}
}
class GameBoard扩展了JComponent{
随机rnd=新随机();
public ArrayList balls=new ArrayList();
int width=Board.boardWidth;
int height=Board.boardHeight;
公共游戏局(){
对于(int i=0;i<50;i++){
int randomStartXPos=(int)(Math.random()*(Board.boardWidth-40)+1);
int randomStartYPos=(int)(Math.random()*(Board.boardHeight-40)+1);
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());
}
}
}