2015-03-27 2 views
0

это мой первый пост, так что простите мне ошибки начинающего.swing animation start stop

структура моей программы следующие:

У меня есть класс, который основно создает массив объектов:

class fieldCreator extends JPanel 
{ 
    ... 
    fieldCell[] fieldArray; 
    ... 
    public fieldCreator() 
    { 
     while (counterVar < arraySize) 
     { 
      // fill the array randomly with one object out of three different classes 
      if ((int)(Math.random()) == 0) 
       this.fieldArray[counterVar] == new cellType0(); 
      ... 
      counterVar++; 
     } 
    } 
    public moveMethod() 
    { 
     // rearange the content of the array by a certain algorithm 
     ... 
     try 
     { 
      Thread.sleep(150L); // this is to slow down the loop frequency 
     } 
     catch (Exception e) {} 
    } 
    public void paintComponent (Graphics g) 
    { 
     while (counterVar < arraySize) 
     { 
      // draw a rectangle for each object in the array in a specific color 
      // create the illusion of a 2D field 
      counterVar++; 
     } 
    } 
} 

Основной класс создает рамочное конец выполняет методы:

class Main extends JPanel 
{ 
    ... 
    public static fieldCreator myField; 
    ... 
    public static void main (String[] args) 
    { 

     main myMain = new main(); 
     myField = new fieldCreator(); 

     main.framework(); 

     // !!! this loop is what i want to start/stop by a button bash !!! 
     while(true) 
     { 
      myField.moveMethod(); 
      myField.repaint(); 
     } 
    } 
    public void frameWork() 
    { 
     JFrame myFrame = new JFrame(); 
     JButton startButton = new JButton ("Start"); 
     JButton stopButton = new JButton ("Stop"); 
     startButton.addActionListener(new startListener()); 
     stopButton.addActionListener(new stopListener()); 
     myFrame.getContentPane().add(BorderLayout.NORTH, startButton); 
     myFrame.getContentPane().add(BorderLayout.CENTER, myField); 
     myFrame.getContentPane().add(BorderLayout.SOUTH, stopButton); 
     ... 
    } 

    class startListener implements ActionListener 
    { 
     public void actionPerformed(ActionEvent e) 
     { 
      //this does not work!!! 
      //while(true) 
      //{ 
      // myField.moveMethod(); 
      // myField.repaint(); 
      //} 
     } 
    } 

    class stopListener implements ActionListener 
    { 
     public void actionPerformed(ActionEvent e) 
     { 
      // ---- this needs to be implemented ---- 
     } 
    } 
} 

Программа отлично работает, пуская и останавливая ее с помощью IDE, поле обновляется в каждом цикле и отображается правильно. Но когда дело доходит до реализации кнопок, оно совсем не обновляется.

Надеюсь, что сокращение кода не влияет на понятность :) Я ценю каждую помощь!

ответ

2

Причина, по которой начинается анимация с ActionListener, не работает, является то, что цикл блокирует event dispatch thread. Причина, по которой код работает, когда выполняется от main(), заключается в том, что main() запускается в другом потоке.

Для простых, приуроченных повторных вызовов, как и у вас, самый простой способ - использовать колебание Timer.

В качестве примечания стороны должны быть также created в EDT.

+0

@ kiheru: THx много для ваших подсказок. Это действительно помогло мне найти решение, хотя мне действительно нужно работать над моим пониманием обработки потоков JAVA. Я не мог понять, где создавать компоненты в потоке. – hurdygurdyman

0

Я решил эту проблему следующим образом:

class Main extends JPanel 
{ 
    public static void main(String[] args) 
    { 
     ... 
     timer = new Timer(timerDelay, main.new timerListener()); 
     ... 
    } 

    class timerListener implements ActionListener 
    { 
     public void actionPerformed(ActionEvent e) 
     { 
      myField.moveMethod(); 
      myField.repaint(); 
     } 
    } 

    class startButtonListener implements ActionListener 
    { 
     public void actionPerformed(ActionEvent e) 
     { 
      timer.start(); 
      startButton.setText("RUNNING..."); 
     } 
    } 

    class stopButtonListener implements ActionListener 
    { 
     public void actionPerformed(ActionEvent e) 
     { 
      timer.stop(); 
      startButton.setText("START"); 
     } 
    } 
}