0

そこで、スレッドの使用方法を学ぼうとしているので、スレッドを追加してから 1/2 秒待機するプログラムを作成することにしました。スレッド(私が正しく作成したと思います)が進行状況バーの値を更新している間。そのため、プログラムが間違っているのか、それともどこかで動かなくなっているのかわかりません。printlnスレッドに a を入れると、次のようになります。

thred
0
1
2
3
4
5
6
7
8
9
10
11 (ect...)

ここに私のフレームコードがあります:

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.border.EmptyBorder;

public class frame extends JFrame implements ActionListener{

    private static final long serialVersionUID = 1L;
    private JPanel contentPane;

    public static void main(String[] args) {
        frame f = new frame();
        f.setVisible(true);
        f.setSize(450,120);
    }

    /**
     * Create the frame.
     */

    public JProgressBar bar;

    public frame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 449, 120);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        bar = new JProgressBar();
        bar.setStringPainted(true);
        bar.setBounds(6, 50, 438, 32);
        contentPane.add(bar);

        JLabel lblNewLabel = new JLabel(
                "Percent of for loop completion");
        lblNewLabel.setBounds(6, 6, 279, 16);
        contentPane.add(lblNewLabel);

        JButton btnStart = new JButton("START");
        btnStart.setBounds(327, 1, 117, 29);
        btnStart.addActionListener(this);
        contentPane.add(btnStart);
    }

    public int i, progress;
    public void actionPerformed(ActionEvent e) {
        updater u = new updater();

        u.start();
        for( i =0; i < 100; i++){
            progress = i;
            try {
                Thread.sleep(500);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            System.out.println(i);
        }

    }

}

そして、これが私のスレッドクラスだと思います:

public class updater extends Thread {

    public void run() {
        System.out.println("thred");
        frame f = new frame();

        int p = f.progress;
        while (p != 100) {

            f.bar.setValue(p);
        }
    }
}
4

2 に答える 2

1

イベント ディスパッチ スレッドをブロックしています。これは、とりわけ、ペイントの更新の処理を担当します。スレッドをブロックしている間、更新が発生する方法はありません。つまり、プログラムが停止したように見えます...

public void actionPerformed(ActionEvent e) {
    updater u = new updater();
    u.start();
    // Now blocking, no more repaints or event notifications until you finish...
    for( i =0; i < 100; i++){
        progress = i;
        try {
            Thread.sleep(500);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        System.out.println(i);
    }

}

もう 1 つの問題は、Swing (ほとんどの場合) がスレッドセーフではないという事実です。つまり、すべての更新と UI との対話は、EDT のコンテキスト内からのみ発生することが期待されます。

これを回避する方法はいくつかありますが、最も簡単なのは を使用するSwingWorkerことです。これは、バックグラウンド スレッドでコードを実行し、更新を UI に安全に再同期できるように設計されています。

を見てみましょう...

いくつかの例について。

詳細については、Swing での同時実行も参照してください。

于 2013-08-01T03:02:22.470 に答える