web-dev-qa-db-fra.com

Button ActionListener

Ok, j'ai donc créé un programme simple qui ajoute la valeur à contrer chaque fois qu'un bouton est cliqué. Maintenant, je voudrais ajouter la fonction du bouton "Auto" pour augmenter la valeur du compteur lorsque le bouton "Auto" est cliqué. J'ai des problèmes avec cela car il ne rendra pas chaque valeur de compteur à l'écran, mais la valeur est mise à jour lorsque la boucle est terminée. Voici mon code:

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

Gardez à l'esprit que je suis un débutant ... Toute aide appréciée :)

7
dev-cyprium

Jetez un oeil au tutoriel sur la façon d'utiliser Swing Timer puis regardez ma solution:

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);
            }
        });
    }
}
5
Azad

le problème ici est que le système est dans la boucle, donc il ne peut pas peindre les modifications. pour ce faire, vous devez ouvrir un nouveau thread. le nouveau thread fera la boucle et le thread principal repeindra le formulaire.

encore une chose, vous ne devriez pas dormir sur le thread principal. vous pouvez utiliser une minuterie qui coche toutes les 10 millisecondes au lieu de sleep(10)ici est un exemple

0
No Idea For Name

votre code bloque le thread GUI (EDT) lorsque vous entrez dans cette boucle (l'interface graphique se bloque, le bouton ne se met pas à jour tant que vous n'avez pas terminé), vous devez donc ajouter votre code dans un autre thread de travail:

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