2017-10-14 81 views
0

在這裏搜索了三天,發現了一些答案,但無法理解如何實現解決方案。於是,我將代碼恢復到第一個版本,並決定詢問。Java - 擺輪定時器在WHILE中,帶啓用/禁用按鈕

我的代碼有兩個問題,並且讀取線程和協議並沒有解釋如何多次使用swing定時器,如何啓動和停止定時器INSIDE LOOP,以及如何在定時器啓動時禁用按鈕,以及何時重新啓用停止。

當你點擊按鈕,它會滾死,定時器必須做它的序列號的時候停止,但如果骰子數爲6它必須再次啓動,在

「做{計時圈}而(模具== 6);」

在我的代碼按鈕不會被禁用。如果6滾動,計時器立即熄滅而不等待完成先前的移動,並且在完成所有事情之前可以單擊按鈕,使JLabel移動更加混亂。

有人請告訴我如何使這項工作?我有更多這樣的東西來寫,需要看這個例子,並從中學習。

請。

在此先感謝您的理解。

下面的代碼:

import java.awt.EventQueue; 
    import java.awt.Toolkit; 
    import java.awt.event.ActionEvent; 
    import java.awt.event.ActionListener; 
    import static java.lang.Math.random; 
    import javax.swing.JFrame; 
    import javax.swing.JLabel; 
    import javax.swing.JButton; 
    import javax.swing.Timer; 

    public class RunPhysics extends JFrame { 
     private final int waits = 200; 
     private JLabel blackBoard = new JLabel(); 
     private JLabel label = new JLabel("a=F/m -> O"); 
     private JButton roll = new JButton("Roll"); 
     private int labelX = 10; 
     private int labelY = 60; 
     private int die; 
     private Timer timer; 

     public static void main(String[] args) { 
      EventQueue.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        new RunPhysics(); 
       } 
      }); 
     } 

     public RunPhysics() { 
      setSize(1000, 200); 
      setTitle("Running Physics"); 
      setLayout(null); 
      setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
      setVisible(true); 
      getContentPane().add(blackBoard); 
      blackBoard.setBounds(10, 10, 980, 280); 
      blackBoard.add(label); 
      blackBoard.add(roll); 
      label.setBounds(30, 50, 100, 20); 
      roll.setBounds(10, 10, 60, 30); 


      roll.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent roller) { 
        do {labelX = 10; 
         die = (int)(random()*6+1); 
         roll.setEnabled(false); 
     System.out.println(die + " was rolled."); 
         timer = new Timer(waits, new ActionListener() { 
          @Override 
          public void actionPerformed(ActionEvent mover) { 
           Toolkit.getDefaultToolkit().beep(); 
           label.setLocation(labelX, labelY);  
           if (labelX >= 900) {((Timer)mover.getSource()).stop();} 
           else { labelX+=36; } 
          } 
         }); 
         timer.start(); 
        } while (die == 6); // 「Dice」 is the plural form of the singular noun 「Die」. 
        roll.setEnabled(true); 
     System.out.println("~~~~~~~~~~~~~~~~~~~~"); 
       } 
      }); 
     } 
    } 
+0

'閱讀有關線程和協議並沒有解釋如何多次使用擺動計時器,如何啓動和停止計時器INSIDE LOOP' - 這是因爲定時器'REPLACES'循環。擺脫循環。計時器將在您指定的時間段內生成一個事件。 – camickr

+0

是的,計時器是循環移動JLabel一步一步。它取代了原來的FOR循環。現在,如何把它放在另一個可以取代WHILE的計時器中? – Sinisa

+0

你不需要while循環!當某些事件發生時,您停止定時器。也許用戶點擊一個按鈕或鍵入一個特定的鍵。 – camickr

回答

1

該按鈕的ActionListener的負責啓動動畫。所以你所做的就是設置組件的屬性,然後開始動畫。因此,它可能看起來像:

roll.addActionListener(new ActionListener() 
{ 
    @Override 
    public void actionPerformed(ActionEvent roller) 
    { 
     // disable the roll button 
     // set the labelX to its start value 
     // set the label location 
     // start the timer 
    } 
}); 

定時器的ActionListener然後負責:

  1. 原創動漫
  2. 確定何時停止動畫
  3. 重新啓動動畫取決於卷骰子

所以代碼應該在你的構造函數中定義類(而不是在按鈕的ActionListener),並可能看起來像:

timer = new Timer(waits, new ActionListener() 
{ 
    @Override 
    public void actionPerformed(ActionEvent mover) 
    { 
     // do the basic animation 

     // 1. increment the labelX value 
     // 2. set the location of the label 

     // determine when to stop the animation 

     if (your stop condition is satisfied) 
     { 
      // stop the timeer 
      // enable the roll button 

      int die = (int)(random()*6+1); 
      System.out.println(die + " was rolled."); 

      // auto restart the animation 

      if (die > 4) // make it easier to test auto repeat 
      { 
       // Reset the component properties and restart the timer. 
       // The code here is the same as the code for the roll button 
       // that is why I suggested you create a method 
      } 
     } 
    } 
}); 

同樣這個答案的角度來理解的

  1. 用戶分離開始某種處理
  2. 定時器負責其動畫並知道何時停止/重新開始動畫。

它可能不是你想要的,但應該給你一個更好的結構來實現你的確切要求的基礎知識。

+0

謝謝。我正在試驗這個,並花了我時間去更好地理解它。要想從根本上改變思維方式,20歲的分步構建只是一種負擔。 Timer根據我們自己的指示循環,在我們指導它時動態分支,並在我們放置它們時循環下一個任務。 – Sinisa