web-dev-qa-db-ja.com

ボタン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));
                    }
                    }
        });
    }
}

私は初心者であることを覚えておいてください...

7
dev-cyprium

使用方法についてのチュートリアルをご覧ください 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);
            }
        });
    }
}
5
Azad

ここでの問題は、システムがループにあるため、変更をペイントできないことです。そのためには、新しいスレッドを開く必要があります。新しいスレッドがループを行い、メインスレッドがフォームを再描画します。

もう1つ、メインスレッドでスリープ状態にしないでください。 sleep(10)の代わりに10ミリ秒ごとに刻むタイマーを使用できます ここ は例です

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