繁体   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