私はかなり新しいスレッドで、長い時間Javaを書いていないので、ここで私に同行してください。私は非常にシンプルなGUIを持っています。それは、カウンター、ステータスラベル、開始と停止の2つのボタンをそれぞれ持っています。スレッドを使ったGUIの更新
私がしたいことは、counter
スレッドを使用してステータスラベルを更新することでした。私が起動すると、カウンタは0で始まり、毎回second
をインクリメントします。stop
を選択すると、現在のスレッドはsuspend
、開始ボタンはwait
になるはずです。しかし、私が停止するたびに、それはちょうど2秒待ってからカウントを再開します。現実には私はそれを中断したままにしたい。なぜそれがやっているのか分からず、ここに掲示する前にそれを探してみましたが、何も見つかりませんでした。また、あなたが好きなものを批判することも自由です。ここで
は、私が持っているものです。
はPER @ MadProgrammerの答えとして更新しました。基本的には
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class main extends JFrame
{
JLabel countLabel = new JLabel("0");
JLabel statusLabel = new JLabel("Task not completed.");
JButton startButton = new JButton("Start");
JButton stopButton = new JButton("Stop");
CounterThread worker = new CounterThread("worker", countLabel, statusLabel);
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Main("Counter Demo");
}
});
}
public Main(String title) {
super(title);
setLayout(new GridBagLayout());
countLabel.setFont(new Font("serif", Font.BOLD, 28));
GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.NONE;
gc.gridx = 0;
gc.gridy = 0;
gc.weightx = 1;
gc.weighty = 1;
add(countLabel, gc);
gc.gridx = 0;
gc.gridy = 1;
gc.weightx = 1;
gc.weighty = 1;
add(statusLabel, gc);
gc.gridx = 0;
gc.gridy = 2;
gc.weightx = 1;
gc.weighty = 1;
add(startButton, gc);
gc.gridx = 0;
gc.gridy = 3;
gc.weightx = 1;
gc.weighty = 1;
add(stopButton, gc);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
worker.start();
//notify();
}
});
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
worker.suspend();
}
});
setSize(200, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public class CounterThread implements Runnable {
public Thread t;
public String threadName;
boolean suspended = false;
JLabel countLabelName;
JLabel statusLabelName;
CounterThread(String name, JLabel cLabel, JLabel sLabel) {
this.threadName = name;
this.countLabelName = cLabel;
this.statusLabelName = sLabel;
}
public void run() {
try {
// Simulate doing something useful.
for (int i = 0; i <= 10; i++) {
synchronized (this) {
if (suspended)
{
wait();
}
}
final int count = i;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
countLabelName.setText(Integer.toString(count));
}
});
Thread.sleep(1000);
}
} catch (InterruptedException e) {
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
statusLabelName.setText("Completed.");
}
});
this.start();
}
public boolean getStatus() {
return t == null;
}
public void start() {
if (getStatus()) {
//t = new Thread(new CounterThread(this.threadName, this.countLabelName, this.statusLabelName));
t = new Thread(this);
t.start();
}
}
public void suspend() {
statusLabelName.setText("Task is paused");
suspended = true;
}
//create an object whose only purpose is to synchronize
synchronized void resume() {
statusLabelName.setText("Task has resumed");
suspended = false;
this.notify();
}
}
}
あなたの最善の策は、スイングとOracleのチュートリアルをスレッドを確認し、インポートしているそのうちのいくつかは、関連するスイングユーティリティクラスを、チェックアウトすることで、すべての世話の問題をオフに再開しますしかし、決して使用しないでください。同様に、あなたはjava.util.concurrentを認識しているように見えますが、それを使用していません。同期プリミティブ、 'notify'などを直接使うのは避けてください。コードとインデントを整理します。実行可能クラスを実装してスレッドを含み、スレッドを開始するクラスがあります。あなたも。 – pvg
バックグラウンドで特別な処理が必要な場合を除き、代わりにSwing 'Timer'を使ってみることをお勧めします。 – MadProgrammer
' boolean suspended = false; 'はおそらく' volatile'とマークされるべきです'' AtomicBoolean') – MadProgrammer