2014-12-01 5 views
0

Я пытаюсь создать программу, которая решает популярные игры Towers of Hanoi. Мне удалось распечатать диски и привязки, но я хочу, чтобы диски печатались с задержкой. Например, я хочу, чтобы диск 7 печатался, а затем диск 6 для печати через 1 секунду позже. Я попробовал это, поставив его в спящий режим, но все, что он делает, это задержка отображения всего кадра, как заставить его отображать форму с задержкой. Я прикрепил свой код, спасибо за любую помощь!Печать форм Java с задержкой

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); 
    } 
} 
+0

Вы не можете использовать 'Thread.sleep' с Swing. Это заставит ваш пользовательский интерфейс перестать работать. Вместо этого используйте 'javax.swing.Timer'. – TNT

+1

Вы можете использовать метод java.util.Timer.schedule. Вот пример: http://www.tutorialspoint.com/java/util/timer_schedule_period.htm – Sybren

+0

Таймер качания может соответствовать этому: https://docs.oracle .com/javase/tutorial/uiswing/misc/timer.html –

ответ

2

Моя рекомендация

  • выделить рисунок в paintComponent() в 3 составляющие части, они были предварительно разделены заявления сна
  • Использование состояния внутри объекта TowersOfHanoi, чтобы контролировать то, что должно быть нарисовано, я ve использовал простой счетчик
  • Используйте javax.swing.Timer, чтобы обновить счетчик и запросить перерисовку.

Примечание

  • Вы не можете спать в потоке пользовательского интерфейса. Качание однопоточное, и это остановит обрабатываемые события.
  • javax.swing.Timer автоматически запускает обратный вызов, который вы передаете ему в потоке пользовательского интерфейса.
  • 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); 
    } 

} 
+0

Спасибо за помощь! Как очистить фигуру после ее рисования? Есть ли функция «удалить», чтобы стереть ее с экрана, кроме clearRect? – MK4

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; 
    } 
} 

И теперь нарисуйте свою графику.

+1

Вы не захотите делать это в потоке диспетчера интерфейса/события, это будет не лучше, чем спать –

0

Возможно, вы должны перестроить код, чтобы компонент краски рисовал текущее состояние системы колышек и колец. Затем используйте таймер Swing для вызова метода, который перемещает состояние системы, а затем вызывает repaint().

Смежные вопросы