2013-07-07 12 views
5

Ok, also habe ich ein einfaches Programm erstellt, das den Wert jedes Mal, wenn auf eine Schaltfläche geklickt wird, addiert. Jetzt möchte ich hinzufügen "Auto" Taste Funktion, um den Wert des Zählers zu erhöhen, wenn die Schaltfläche "Auto" angeklickt wird. Ich habe Probleme mit ihm habe, weil es nicht jeden Zählerwert auf dem Bildschirm machen, anstatt das Wert-Updates, wenn die Schleife durchgeführt wird .. Hier ist mein Code: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)); 
        } 
        } 
     }); 
    } 
} 

Beachten Sie, dass ich bin ein Anfänger ... Alle Hilfe geschätzt :)

+0

Was ist die Frage? – Sello

+1

Was * genau * soll die Auto-Taste tun? –

+3

Ich denke, [Swing Timer] (http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html) wird dies lösen. – Azad

Antwort

4

im Tutorial Werfen Sie einen Blick über Wie Swing Timer verwenden und dann auf meiner Lösung aussehen:

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

Das Problem hier ist, dass das System in der Schleife ist, so dass es die Änderungen nicht malen kann. Um dies zu tun, müssen Sie einen neuen Thread öffnen. Der neue Thread führt die Schleife aus, und der Haupt-Thread wird das Formular neu streichen.

noch eine Sache, sollten Sie nicht schlafen auf dem Hauptthread. Sie können einen Timer verwenden, die alle 10 Millisekunden statt sleep(10) here ist ein Beispiel

+2

Wäre kein Swing Timer eine bessere Option? –

+1

Haben Sie Ihre Empfehlungen getestet? 'repaint()' wird im Falle einer Schleife, die den EDT bindet, nichts tun. Bitte entfernen Sie diese Empfehlung, damit ich die Down-Vote entfernen kann. –

+0

Auch der Malfaden ist nicht der Hauptfaden. Es ist der Ereignisversand-Thread. –

0

Ihr Codeblock der GUI-Thread (EDT), wenn geben Sie innerhalb dieser Schleife kreuzen wird (GUI hängen wird, nicht die Taste aktualisieren, bis Sie fertig sind), so sollten Sie Ihren Code in einem anderen Arbeitsthread hinzufügen:

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