延迟打印Java形状

时间:2014-12-01 15:08:24

标签: java swing user-interface delay java-2d

我正在尝试创建一个解决流行的河内塔游戏的程序。我已成功打印磁盘和挂钉,但我希望磁盘能够延迟打印。例如,我想要打印磁盘7,然后在1秒后打印磁盘6。我通过让它进入睡眠状态来尝试这个,但它所做的就是延迟整个帧的显示,如何让它显示延迟的形状。我附上了我的代码,感谢您的帮助!

package towersofhanoi;
import javax.swing.*;
import java.awt.*;

/*g.fillOval(60 = horizontal distance , 540= vertical distance, 400 = width, 60 = height) */

public class TowersOfHanoi extends JPanel {
    public static void main(String[]args){
        //Print the shapes and frame
        TowersOfHanoi drawRectangle = new TowersOfHanoi();
        JFrame frame = new JFrame("Towers of Hanoi");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(drawRectangle);
        frame.setSize(1250, 800);
        frame.setVisible(true);
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Color pegs = new Color (251, 129, 56);
        g.setColor(pegs);

        //peg 1
        g.fillRect(250, 300, 25, 450);
        //peg 2
        g.fillRect(600, 300, 25, 450);
        //peg 3
        g.fillRect(950, 300, 25, 450);
        //bottom
        g.fillRect(200, 700, 825, 50);
        //create a color for circles
        Color circles = new Color (176,56, 251);
        //cirle 7 (Labeled from bottom to top)
        g.setColor(circles);
        g.fillOval(60, 640, 400, 60);
        g.setColor(Color.BLACK);
        g.drawOval(60, 640, 400, 60);
        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException ie) {

        }
        //circle 6
        g.setColor(circles);
        g.fillOval(85, 580, 350, 60);
        g.setColor(Color.BLACK);
        g.drawOval(85, 580, 350, 60);
        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException ie) {

        }
        //circle 5
        g.setColor(circles);
        g.fillOval(110, 520, 300, 60);
        g.setColor(Color.BLACK);
        g.drawOval(110, 520, 300, 60);
        //circle 4
        g.setColor(circles);
        g.fillOval(135, 465, 250, 55);
        g.setColor(Color.BLACK);
        g.drawOval(135, 465, 250, 55);
        //circle 3
        g.setColor(circles);
        g.fillOval(160, 420, 200, 45);
        g.setColor(Color.BLACK);
        g.drawOval(160, 420, 200, 45);
        //circle 2
        g.setColor(circles);
        g.fillOval(185, 380, 150, 40);
        g.setColor(Color.BLACK);
        g.drawOval(185, 380, 150, 40);
        //circle 1
        g.setColor(circles);
        g.fillOval(210, 345, 100, 35);
        g.setColor(Color.BLACK);
        g.drawOval(210, 345, 100, 35);
    }
}

3 个答案:

答案 0 :(得分:2)

我的推荐

  • 将paintComponent()中的绘图分成3个构成部分,这些部分先前由sleep语句分隔
  • 使用TowersOfHanoi对象内的状态来控制应该绘制的内容,我使用了一个简单的计数器
  • 使用javax.swing.Timer更新计数器并请求重新绘制。

注释

  • 你无法在UI线程上睡觉。 Swing是单线程的,这将阻止正在处理的事件。
  • javax.swing.Timer会自动触发您在UI线程上提供的回调。
  • 如果调整窗口大小等,可以多次调用
  • paintComponent(),因此重要的是使其独立,因此我使用了计数器。

工作示例

public class TowersOfHanoi extends JPanel {

    private int clock = 0;
    private Color circles = new Color(176, 56, 251);

    public static void main(String[] args) {
        // Print the shapes and frame
        TowersOfHanoi drawRectangle = new TowersOfHanoi();
        JFrame frame = new JFrame("Towers of Hanoi");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(drawRectangle);
        frame.setSize(1250, 800);
        frame.setVisible(true);

        Timer timer = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                drawRectangle.nextFrame();
                drawRectangle.repaint();
            }
        });
        timer.setRepeats(true);
        timer.start();
    }

    public void nextFrame() {
        clock++;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        frame1(g);
        if (clock >= 1) {
            frame2(g);
        }
        if (clock >= 2) {
            frame3(g);
        }
    }

    private Color frame1(Graphics g) {
        Color pegs = new Color(251, 129, 56);
        g.setColor(pegs);

        // peg 1
        g.fillRect(250, 300, 25, 450);
        // peg 2
        g.fillRect(600, 300, 25, 450);
        // peg 3
        g.fillRect(950, 300, 25, 450);
        // bottom
        g.fillRect(200, 700, 825, 50);
        // create a color for circles
        // cirle 7 (Labeled from bottom to top)
        g.setColor(circles);
        g.fillOval(60, 640, 400, 60);
        g.setColor(Color.BLACK);
        g.drawOval(60, 640, 400, 60);
        return circles;
    }

    private void frame2(Graphics g) {
        // circle 6
        g.setColor(circles);
        g.fillOval(85, 580, 350, 60);
        g.setColor(Color.BLACK);
        g.drawOval(85, 580, 350, 60);
    }

    private void frame3(Graphics g) {
        // circle 5
        g.setColor(circles);
        g.fillOval(110, 520, 300, 60);
        g.setColor(Color.BLACK);
        g.drawOval(110, 520, 300, 60);
        // circle 4
        g.setColor(circles);
        g.fillOval(135, 465, 250, 55);
        g.setColor(Color.BLACK);
        g.drawOval(135, 465, 250, 55);
        // circle 3
        g.setColor(circles);
        g.fillOval(160, 420, 200, 45);
        g.setColor(Color.BLACK);
        g.drawOval(160, 420, 200, 45);
        // circle 2
        g.setColor(circles);
        g.fillOval(185, 380, 150, 40);
        g.setColor(Color.BLACK);
        g.drawOval(185, 380, 150, 40);
        // circle 1
        g.setColor(circles);
        g.fillOval(210, 345, 100, 35);
        g.setColor(Color.BLACK);
        g.drawOval(210, 345, 100, 35);
    }

}

答案 1 :(得分:0)

您是否尝试过使用Caldender()System.currentTimeMillis()?如果这样做,您可以获得当前时间。在你有时间之后,做一个while循环来检查现在的时间。执行LastTime - Now时,请检查已经过了多长时间。

此代码未经过测试,(但它应该可以使用)。

long lastTime = System.currentTimeMillis();

while(true){

   long now = System.currentTimeMillis();

   if(lastTime - now == [YOUR PREFFERD WAITING TIME IN MS]){
      break;
   }
}

现在绘制图形。

答案 2 :(得分:0)

您可能应该对代码进行重组,以便绘制组件绘制栓钉和环系统的当前状态。然后使用Swing计时器调用移动系统状态的方法,然后调用repaint()。