簡體   English   中英

Java Swing-paintComponent()無法繪制我的線程

[英]Java Swing - paintComponent() not drawing my Threads

我要添加到ArrayListThread配位的代表用(X,Y)球和move()方法的新球Thread每5秒。 因此,我的JPanel實現了Runnable並在其中向ArrayList添加了一個新的Ball Thread paintComponent()方法,我使用foreach循環遍歷該ArrayListThread的,並開始他們的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM