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

여기서 문제는 시스템이 루프에 있으므로 변경 사항을 칠할 수 없다는 것입니다. 새 스레드를 열어야 할 필요가 있습니다. 새 스레드가 루프를 수행하고 주 스레드가 양식을 다시 칠합니다.

한 가지 더 주 스레드에서 잠을 자면 안됩니다. 당신이 완료 할 때까지 sleep(10) here가 GUI 스레드 (EDT)이이 루프 내에서 입력

+2

스윙 타이머가 더 좋은 옵션이 아니겠습니까? –

+1

권장 사항을 테스트 했습니까? 'repaint()'는 EDT를 묶는 루프의 경우에는 아무 것도하지 않습니다. 아래 추천을 삭제할 수 있도록이 추천을 삭제하십시오. –

+0

또한 그림 스레드는 주 스레드가 아닙니다. 이벤트 발송 스레드입니다. –

0

코드 블록 (GUI가 중단됩니다 예입니다 대신에 매 10 밀리 초를 체크하는 타이머를 사용할 수있는 버튼이 업데이트되지 않습니다), 그래서 당신은 다른 작업자 스레드 내부에 코드를 추가해야합니다

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