2013-07-07 2 views
5

Итак, я сделал простую программу, которая добавляет значение к счетчику каждый раз, когда нажимается кнопка. Теперь я хотел бы добавить функцию «Авто», чтобы увеличить значение счетчика при нажатии кнопки «Авто». У меня возникли проблемы с ним, потому что он не будет оказывать каждое значение счетчика на экране, вместо обновления значений, когда цикл закончен .. Вот мой код:Button ActionListener

import java.awt.FlowLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.concurrent.TimeUnit; 
import javax.swing.JButton; 
import javax.swing.JFrame; 


public class Gui extends JFrame{ 

    private static final long serialVersionUID = 1L; 

    private JButton uselesButton; 

    private JButton autoButton; 

    private FlowLayout layout; 
    private long counter = 0; 

    public Gui() { 
     super("Button"); 
     layout = new FlowLayout(FlowLayout.CENTER); 
     this.setLayout(layout); 

     uselesButton = new JButton(String.format("Pressed %d times", counter)); 
     add(uselesButton); 
     uselesButton.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       counter++; 
       uselesButton.setText(String.format("Pressed %d times", counter)); 
      } 

     }); 

     autoButton = new JButton("Auto"); 
     add(autoButton); 
     autoButton.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
         for(long i =0; i < 99999999;i++) { 
         try { 
          TimeUnit.MILLISECONDS.sleep(10); 
         } catch (InterruptedException e1) { 
          System.out.println("ERROR"); 
         } 
         counter = i; 
         uselesButton.setText(String.format("Pressed %d times", counter)); 
        } 
        } 
     }); 
    } 
} 

Имейте в виду, что я новичок ... Вся помощь оценивалась :)

+0

Что вопрос? – Sello

+1

Что такое * точно * - кнопка авто, которая должна быть? –

+3

Я думаю, что [Swing Timer] (http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html) решит это. – Azad

ответ

4

посмотрите на учебник о том, как использовать Swing Timer, а затем посмотреть на мое решение:

import java.awt.FlowLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 

public class Gui extends JFrame { 

    private static final long serialVersionUID = 1L; 
    private JButton uselesButton; 
    private JButton autoButton; 
    private FlowLayout layout; 
    private long counter = 0; 
    private javax.swing.Timer timer; 

    public Gui() { 
     super("Button"); 
     layout = new FlowLayout(FlowLayout.CENTER); 
     setLayout(layout); 
     setDefaultCloseOperation(3); 
     setSize(300, 300); 
     setLocationRelativeTo(null); 

     //initialing swing timer 
     timer = new javax.swing.Timer(100, getButtonAction()); 

     autoButton = new JButton("Auto"); 
     add(autoButton); 
     autoButton.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       if (!timer.isRunning()) { 
        timer.start(); 
       } else { 
        timer.stop(); 
       } 
      } 
     }); 
    } 

    private ActionListener getButtonAction() { 
     ActionListener action = new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       autoButton.setText(String.format("Pressed %d times", ++counter)); 
       if (counter > 1000) { 
        timer.stop(); 
       } 
      } 
     }; 
     return action; 
    } 

    public static void main(String... args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Gui().setVisible(true); 
      } 
     }); 
    } 
} 
0

проблема в том, что система находится в цикле, поэтому она не может рисовать изменения. , чтобы сделать это, вам нужно открыть новую тему. новый поток выполнит цикл, а основной поток перекрасит форму.

еще одна вещь, вы не должны спать на основной теме. Вы можете использовать таймер, который будет тикать каждые 10 миллисекунд вместо sleep(10) here является примером

+2

Не был бы лучшим вариантом? –

+1

Вы проверили свои рекомендации? 'repaint()' не будет делать ничего в случае цикла, связывающего EDT. Пожалуйста, удалите эту рекомендацию, чтобы я мог удалить голос. –

+0

Кроме того, нить для рисования не является основной нитью. Это потоки отправки событий. –

0

кода блокировать GUI поток (EDT), если ввести в этом цикле (GUI будет висеть, кнопка не будет обновляться, пока вы не закончите), так что вы должны добавить код в другой рабочий поток:

autoButton.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
        new Thread(new Runnable() { 
         @Override 
         public void run() { 
          for(long i =0; i < 99999999;i++) { 
           try { 
            TimeUnit.MILLISECONDS.sleep(10); 
           } catch (InterruptedException e1) { 
            System.out.println("ERROR"); 
           } 
           counter = i; 

           java.awt.EventQueue.invokeLater(new Runnable() { 
             public void run() { 
             uselesButton.setText(String.format("Pressed %d times", counter)); 
             } 
           }); 
          } 
         } 
        }).start(); 
      } 
     }); 
Смежные вопросы