2013-07-07 9 views
5

Ok, quindi ho creato un semplice programma che aggiunge il valore da neutralizzare ogni volta che si fa clic su un pulsante. Ora, vorrei aggiungere la funzionalità del pulsante "Auto" per aumentare il valore del contatore quando si fa clic sul pulsante "Auto". Sto avendo problemi con esso, perché non renderà ogni valore contatore sullo schermo, invece gli aggiornamenti di valore quando il ciclo è fatto .. Qui è il mio codice: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)); 
        } 
        } 
     }); 
    } 
} 

tenere a mente che io sono un principiante ... Tutto l'aiuto apprezzato :)

+0

Qual è la domanda? – Sello

+1

Cosa * esattamente * è il pulsante auto dovrebbe fare? –

+3

Penso che [Swing Timer] (http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html) risolverà questo problema. – Azad

risposta

4

Date un'occhiata al tutorial su come utilizzare Swing Timer e poi guardare la mia soluzione:

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

il problema qui è che il sistema è nel ciclo, quindi non può dipingere le modifiche. per fare ciò è necessario aprire una nuova discussione. il nuovo thread farà il ciclo e il thread principale ridisegnerà il modulo.

un'altra cosa, non si dovrebbe dormire sul thread principale. è possibile utilizzare un timer che esegue un controllo ogni 10 millisecondi al posto di sleep(10) here è un esempio

+2

Un timer Swing non sarebbe un'opzione migliore? –

+1

Hai testato i tuoi consigli? 'repaint()' non farà nulla nel caso di un loop che lega l'EDT. Si prega di rimuovere questa raccomandazione in modo da poter rimuovere il down-vote. –

+0

Inoltre, il thread di pittura non è il thread principale. È il thread di invio dell'evento. –

0

vostro blocco di codice il filo GUI (EDT), quando entra all'interno di questo ciclo (GUI si bloccherà, il pulsante non verrà aggiornato fino al completamento), così si dovrebbe aggiungere il codice all'interno di un altro thread di lavoro:

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