8

わかりましたので、ボタンがクリックされるたびにカウンターに値を追加する簡単なプログラムを作成しました。ここで、「自動」ボタンがクリックされたときにカウンターの値を増やす「自動」ボタン機能を追加したいと思います。画面に各カウンター値をレンダリングせず、代わりにループが完了すると値が更新されるため、問題が発生しています.ここに私のコードがあります:

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

私は初心者であることを覚えておいてください...すべての助けに感謝します:)

4

3 に答える 3

6

スイングタイマーの使用方法に関するチュートリアルを見てから、私の解決策を見てください。

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);
            }
        });
    }
}
于 2013-07-07T11:59:36.270 に答える
1

このループ内に入ると、コードは 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();
            }
        });
于 2013-07-07T11:46:39.997 に答える
0

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

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

于 2013-07-07T11:40:55.647 に答える