Java Swing - paintComponent()没有绘制我的线程

时间:2016-04-12 14:57:02

标签: java multithreading swing jpanel paintcomponent

我想添加ArrayList Thread个代表带有(x,y)协调球的球,move()方法代表新球{{1}每5秒钟。 因此,Thread实施了JPanel,并在那里向Runnable添加了一个新球ArrayList。 在Thread方法中,我使用paintComponent()循环来迭代球foreach的{​​{1}}并启动他们移动它们的ArrayList并呼叫Thread。问题是我根本没有看到任何绘图(只有玩家绘图)。

MyPanel.java

Thread

Ball.java

repaint()

我省略了一个简单的public class MyPanel extends JPanel implements KeyListener,Runnable { private static final long serialVersionUID = 1L; private static final Color BACKGROUND_COLOR = Color.WHITE; private static final Color NPC_BALLS_COLOR = Color.RED; // The player is an oval private int playerRadius = 20; private int playerX; private int playerY; // True - first player position, false - otherwise private boolean playerPosition = true; // Array of all the balls threads private ArrayList<BallThread> balls = new ArrayList<BallThread>(); private Thread generateBallsThread; public MyPanel() { this.setBackground(MyPanel.BACKGROUND_COLOR); this.setFocusable(true); this.addKeyListener(this); this.generateBallsThread = new Thread(); generateBallsThread.start(); } // Drawing @Override protected void paintComponent(Graphics g) { super.paintComponent(g); final double PANEL_WIDTH = this.getWidth(); final double PANEL_HEIGHT = this.getHeight(); if (this.playerPosition) { this.playerX = (int)(PANEL_WIDTH / 2 - this.playerRadius); this.playerY = (int)(PANEL_HEIGHT / 2 - this.playerRadius); this.playerPosition = false; } // Drawing the player g.setColor(Color.BLACK); g.fillOval(playerX,playerY, this.playerRadius * 2, this.playerRadius * 2); // Drawing npc's balls g.setColor(MyPanel.NPC_BALLS_COLOR); for (BallThread ball: this.balls) { ball.start(); g.fillOval(ball.getBall().getX(), ball.getBall().getY(), ball.getBall().radius, ball.getBall().radius); repaint(); } } // Keyboard listeners @Override public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_W: // Up { this.playerY -= 5; repaint(); break; } case KeyEvent.VK_S: // Down { this.playerY += 5; repaint(); break; } case KeyEvent.VK_D: // Right { this.playerX += 5; repaint(); break; } case KeyEvent.VK_A: // Left { this.playerX -= 5; repaint(); break; } } } @Override public void keyReleased(KeyEvent e) { } @Override public void keyTyped(KeyEvent e) { } public int getBallXStartingPositionFromTop() { return (int) Math.random() * 101; // 0 - 100 } //public int getBallYStartingPositionFromLeft() //{ // return (int) Math.random() * 101; // 0 - 100 //} /** * * * * Class for the balls threads. * */ public class BallThread extends Thread { private Ball ball; public BallThread(Ball ball) { this.ball.setX(ball.getX()); this.ball.setY(ball.getY()); } @Override public void run() { try { this.ball.move(); Thread.sleep(4000); repaint(); // Execute paintComponent() method } catch (InterruptedException e) { e.printStackTrace(); } } public Ball getBall() { return this.ball; } public void setBall(Ball ball) { this.ball = ball; } } @Override public void run() { try { Thread.sleep(5000); // 5 seconds this.balls.add(new BallThread(new Ball(20,20))); } catch (InterruptedException e) { e.printStackTrace(); } } } // End of MyPanel class 类和一个public class Ball { int x; int y; int velocity = 1; public int radius = 10; public boolean directionX = true; // True - right, false - left public boolean directionY = false; // True - up, false - down public static final int Y_STARTING_POSITION_FROM_TOP = 0; public Ball(int x, int y) { this.x = x; this.y = y; } public Ball() { } public int getX() { return this.x; } public void setX(int x) { this.x = x; } public int getY() { return this.y; } public void setY(int y) { this.y = y; } public void move() { if (this.directionX) // Right { this.x += this.velocity; } else // Left { this.x -= this.velocity; } if (this.directionY) // Up { this.y -= this.velocity; } else { this.y += this.velocity; } } } ,他们生成了JFrame并添加了main()

任何想法为什么我都不能看到球的绘制JFrame

1 个答案:

答案 0 :(得分:5)

    this.generateBallsThread = new Thread();
    generateBallsThread.start();

这没有任何作用。它是一个没有逻辑的空线程。

我想你想要

    this.generateBallsThread = new BallsThread();
    generateBallThread.start();

此外,您不应该使用Thread进行动画制作。您应该使用Swing Timer。任何更新Swing组件状态的逻辑都应该在Event Dispatch Thread上执行。有关详细信息,请阅读Concurrency上Swing教程中的部分。本教程还有一个关于How to Use Swing Timers的部分。