使用可运行线程时,循环不连续

时间:2016-02-29 05:45:43

标签: java multithreading swing swingworker

我有这个小项目,在运行程序时会自动生成动画。在这种情况下,椭圆形应该使用线连续动画。然而,在我的程序中,它将停止第五个方向 - 意味着遵循某个路径。任何人都可以建议我一个更好的解决方案或帮助我让椭圆形状持续移动,直到用户关闭程序。

    package movingball;

    import java.awt.Color;
    import java.awt.Graphics;
    import javax.swing.JFrame;
    import javax.swing.JPanel;

    public class MovingBall extends JPanel{


    private int ballX = 30;
    private int ballY = 30;
    private int pattern = 1;
    private int limitHeight;
    private int limitWidth;
    boolean horizontalBoundary = true;
    boolean verticalBoundary = true;

    public MovingBall(){
        setBackground(Color.BLACK);
    }
    public MovingBall(int x, int y){
        x = this.ballX;
        y = this.ballY;  
        repaint();
    }
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500,700);

        MovingBall movingBall = new MovingBall();
        frame.add(movingBall);       
        frame.setVisible(true);

        BallUsingThread ball =  new BallUsingThread(movingBall);
        Thread first = new Thread(ball);

        first.start();

    }
    @Override
    public void paintComponent(Graphics canvas){
        super.paintComponent(canvas);

        canvas.setColor(Color.BLUE);
        canvas.fillOval(ballX, ballY, 100, 100);
    }

    public void animateBall(){

        if(horizontalBoundary && verticalBoundary){
            if(pattern == 1){
               diagonalDown(getWidth()-100,365); 

            }else if(pattern == 2){
               diagonalDown(getWidth(),150); 
            }
        }
        if(!horizontalBoundary && !verticalBoundary){          
            diagonalDownLeft(150, getHeight());
            pattern = 4;             
        } 
        if(horizontalBoundary && !verticalBoundary){           
            if(pattern == 4){
                diagonalUp(0, 490);
            } 
            if(pattern == 5){
                System.out.print("helo");
                diagonalUp(500,10);
            }
            System.out.print("last move" + pattern);
        }
        if(!horizontalBoundary && verticalBoundary){
            diagonalUpRight(getWidth(),100);
            pattern = 5;
            System.out.print(pattern);
        }
        repaint();
    }
    public void diagonalDown(int limitWidth, int limitHeight){
        this.limitWidth = limitWidth;
        this.limitHeight = limitHeight;

        if((ballX += 30) >= limitWidth){
            horizontalBoundary = false; 
        } 
        if((ballY += 30) >= limitHeight){
            verticalBoundary = false; 
        } 

    }
    public void diagonalUp(int limitWidth, int limitHeight){
        this.limitWidth = limitWidth;
        this.limitHeight = limitHeight;

        if((ballX -= 30) <= limitWidth) {
            horizontalBoundary = false;
        } 
        if((ballY -= 30) <= limitHeight){
            verticalBoundary = true;   
        } 
    }
    public void diagonalUpRight(int limitWidth, int limitHeight){
        this.limitWidth = limitWidth;
        this.limitHeight = limitHeight;

        if((ballX += 30) >= limitWidth) {
            horizontalBoundary = true;
        } 
        if((ballY -= 30) <= limitHeight){
            verticalBoundary = false;   
        }

    }
    public void diagonalDownLeft(int limitWidth, int limitHeight){
        this.limitWidth = limitWidth;
        this.limitHeight = limitHeight;

        if((ballX -= 30) <= limitWidth){
            horizontalBoundary = true;
        }
        if((ballY += 30) >= limitHeight){
            verticalBoundary = false;

        }
        //System.out.print("downleft");
    }

}

        class BallUsingThread implements Runnable{

        private final MovingBall movingBall;
        public BallUsingThread(MovingBall mb){
           movingBall = mb;
        }
        @Override
        public void run() {
            for(;;){
                movingBall.animateBall();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                    System.out.printf("Error",ex);
                }
            }      
        }   
    }

2 个答案:

答案 0 :(得分:0)

这不是循环的问题,如果你System.out.println("loop running");你会看到循环正在运行,但你的绘图球逻辑存在问题,这部分代码

if(!horizontalBoundary && verticalBoundary){
    diagonalUpRight(getWidth(),100);
    pattern = 5;
    System.out.print(pattern);
}

你试图diagonalUpRight()所以在调用这个方法之后,没有if子句会被执行,因为条件不满足,所以球仍然在同一个地方每个循环,似乎循环停止工作。

一个小建议:在这种情况下,最好使用while(tru /*some condition*/)循环代替for(;;)

解决方案:如果仔细检查逻辑,您会发现没有if子句用于以下条件:

horizontalBoundary = true
verticalBoundary = true

pattern = 5当这两个变量变为truepattern = 5时,球位置不会发生任何变化,因此您可以编写一个用于检查这两个变量的条件true值。

Eidt Eidt代码的下方部分,您将看到循环未停止的结果,我刚刚初始化了球的位置,值变为true和{{1 }}

pattern = 5

答案 1 :(得分:0)

覆盖paintComponent(Graphics)并在此方法中实现所有绘画(但不是动画)。

然后使用Swing timer每100毫秒安排一次定期事件,在此事件的处理程序中实现更改图片的所有内容,并从那里调用repaint()刷新图片。