[英]Java Swing - paintComponent() not drawing my Threads
我要添加到ArrayList
的Thread
配位的代表用(X,Y)球和move()
方法的新球Thread
每5秒。 因此,我的JPanel
實現了Runnable
並在其中向ArrayList
添加了一個新的Ball Thread
。 在paintComponent()
方法,我使用foreach
循環遍歷該ArrayList
球Thread
的,並開始他們的Thread
,其移動它們,並呼吁repaint()
問題是ii根本看不到任何繪圖(僅播放器繪圖)。
MyPanel.java :
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
Ball.java :
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()
,后者通過添加JPanel
來生成JFrame
。
有什么想法為什么我看不到Thread
球的圖嗎?
this.generateBallsThread = new Thread();
generateBallsThread.start();
那什么也沒做。 這是一個沒有邏輯的空線程。
我想你要
this.generateBallsThread = new BallsThread();
generateBallThread.start();
同樣,您不應該將線程用於動畫。 您應該使用Swing Timer
。 任何更新Swing組件狀態的邏輯都應在事件調度線程上執行。 閱讀Swing 並發教程中的有關更多信息的部分。 本教程還包含有關How to Use Swing Timers
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.