2014-10-17 29 views
1

我正在爲下週六做一個java任務。在Java中做動畫

它很好,但我正在努力與一節。

在這裏我想揭示一個字符串中的一組數字,一次一個。 我試圖用'Thread.sleep(1000)'減慢循環;'

但沒有什麼顯示,直到線程完成

以下是哪裏的問題是發生 圖形類的部分是有什麼我失蹤?

public void paint(Graphics g) 
    { 
     setSize(550, 300); 

     //this draws all the random numbers, revealing the ans to the user 
     if (revealNum == 0) 
     { 
      g.setColor(Color.BLUE); 

      g.drawString(randomNumber, 20, 20); //draw String ("the String", x, y) 
     } 
     //this reveals the numbers 1 by 1 to the user at the start of the game 
     if (revealNum==1) 
     { 
      for (int x = 0; x < limit; x++) 
      { 
       g.setColor(Color.BLUE); 
       g.drawString(""+x, 20, 20); //draw String ("the String", x, y) 

       try{ 
        Thread.sleep(1000); 
       }catch(InterruptedException ex){ 
        System.out.print("Error"); 
       } 

       repaint(); 
      } 

      //slow down the loop to show the user 

     } 
+0

看看[這裏](http://stackoverflow.com/questions/9270632/java-wait-for -thread-result-without-blocking-ui)問題。 – Linus 2014-10-17 20:00:14

回答

2

既然你是一個GUI,調用Thread.sleep將把整個應用程序睡覺。而是使用擺動計時器。在定時器的ActionListener內部,向顯示的字符串中添加另一個字母,然後在String完成後通過stop()方法停止定時器。

例如,

import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import javax.swing.*; 

public class SimpleAnimation extends JPanel { 
    public static final int TIMER_DELAY = 1000; 
    private JTextField textField = new JTextField(10); 
    private JLabel displayLabel = new JLabel("", SwingConstants.CENTER); 

    public SimpleAnimation() { 
     Action btnAction = new DoItBtnAction("Do It!", KeyEvent.VK_D); 
     JPanel topPanel = new JPanel(); 
     topPanel.add(textField); 
     topPanel.add(new JButton(btnAction)); 
     textField.addActionListener(btnAction); 

     setLayout(new GridLayout(2, 1)); 
     add(topPanel); 
     add(displayLabel); 
    } 

    private class DoItBtnAction extends AbstractAction { 
     private String textFieldText = ""; 
     public DoItBtnAction(String name, int mnemonic) { 
     super(name); 
     putValue(MNEMONIC_KEY, mnemonic); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
     displayLabel.setText(""); 
     setEnabled(false); 
     textFieldText = textField.getText(); 
     new Timer(TIMER_DELAY, new ActionListener() { 
      private int i = 0; 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       if (i >= textFieldText.length()) { 
        ((Timer) e.getSource()).stop(); 
        DoItBtnAction.this.setEnabled(true); 
       } else { 
        displayLabel.setText(displayLabel.getText() + textFieldText.charAt(i)); 
        i++; 
       } 
      } 
     }).start(); 
     } 
    } 

    private static void createAndShowGui() { 
     JFrame frame = new JFrame("SimpleAnimation"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(new SimpleAnimation()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

此外,

  • 如果你是一個Swing GUI,它會更容易顯示在JLabel或JTextField的文本,而不是試圖把它漆成上GUI。
  • 如果這是Swing,請不要覆蓋paint(Graphics g),而是覆蓋JPanel或JComponent的paintComponent(Graphics g)方法。
+0

很酷,謝謝! – 2014-10-17 22:48:18

0

您應該使用javax.swing.Timer

下面是一個例子

JLabel l = ...; 
Timer t = new Timer(1000, new ActionListener() { 
    public void actionPerformed(ActionEvent ae) { 
    if (l.getText().equals("1")) l.setText("2"); 
    else if (l.getText().equals("2)) l.setText("1"); 
    } 
});