SwingWorker Java Swing 中的定时器应用程序不工作
Timer application inside SwingWorker Java Swing does not work
尝试制作 Java Swing 应用程序的一部分,应该这样做:
- 单击按钮时,从中获取 "minutes" 的用户值(整数)
一些文本字段;
- 实例化和对象,它实际上是 SwingWorker 线程,它将启动一个计时器,计数回到零用户 "minutes",然后在 doInBackground() 完成后在 done() 中执行一些操作(启动另一个 JFrame) ;
我在代码中打印了一些点,代码似乎从 textField 中获取输入分钟数,将其传递给倒计时 class 中的构造函数,但随后只是执行 done(),没有 运行 doInBackground() 首先。
如果有人知道为什么会发生这种情况,我将不胜感激,我已经尝试了所有的想法,但没有任何效果。
这是第一部分,来自按钮的代码:
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
userCountTime = Integer.parseInt(jTextField2.getText());
userCountTime = userCountTime * 60;
System.out.println("Preuzeto iz dugmeta " + userCountTime);
if (jRadioButton2.isSelected()){
Countdown countDown= new Countdown (userCountTime);
}
这里是class倒计时:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.SwingWorker;
import javax.swing.Timer;
/**
*
* @author Glupko
*/
public class Countdown extends SwingWorker{
public Timer timer;
static int userCountTime;
static ActionListener timerListener;
//Constructor
public Countdown (int userCountTime){
Countdown.userCountTime = userCountTime;
System.out.println("In constructor: " + Countdown.userCountTime);
this.execute();
}
@Override
protected Object doInBackground() throws Exception {
//defining listener
timerListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
System.out.println("In action performed value is: " + userCountTime);
//for each tick we subtract 1, every second
while (userCountTime >= 0){
userCountTime--;
System.out.println("In actionPerformed there is number of seconds: " + userCountTime);}
timer = new Timer(1000, timerListener);
//start timer
timer.start();
}};}
@Override
protected void done(){
System.out.println("From done: timer elapsed");
ChangingWindow window = new ChangingWindow();
}
}
Many thanks in advance!
- 您不应该从 SwingWorker 的
doInBackground
方法中启动 Swing 计时器。这违背了所有目的,因为 Swing 计时器在 Swing 事件线程或 EDT 上应该是 运行。
- 您的 SwingWorker 的 done 方法将被立即调用,因为
timer.start()
是非阻塞的。
而是摆脱 SwingWorker 并单独使用 Timer。
如需更完整的代码帮助,请考虑创建并发布您的 minimal code example program 以供我们审查、测试并可能修复。
例如.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import javax.swing.*;
public class CountDownTest extends JPanel {
private static final Integer[] SECONDS = {1, 2, 3, 4, 5, 6, 7, 8, 9};
private JSpinner secondsSpinner = new JSpinner(new SpinnerListModel(Arrays.asList(SECONDS)));
public CountDownTest() {
add(secondsSpinner);
add(new JButton(new StartCountDownAction(this, "Start Count Down")));
}
public int getSecondsSpinnerValue() {
return (Integer) secondsSpinner.getValue();
}
private static void createAndShowGui() {
CountDownTest mainPanel = new CountDownTest();
JFrame frame = new JFrame("CountDownTest");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class StartCountDownAction extends AbstractAction {
private CountDownTest countDownTest;
private Timer timer;
public StartCountDownAction(CountDownTest countDownTest, String name) {
super(name);
this.countDownTest = countDownTest;
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
if (timer != null && timer.isRunning()) {
// don't start a new Timer when one is running
return;
}
int seconds = countDownTest.getSecondsSpinnerValue();
timer = new Timer(seconds * 1000, new TimerListener(countDownTest));
timer.setRepeats(false);
timer.start();
}
}
class TimerListener implements ActionListener {
private CountDownTest countDownTest;
public TimerListener(CountDownTest countDownTest) {
this.countDownTest = countDownTest;
}
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(countDownTest, "Timer Done!");
}
}
尝试制作 Java Swing 应用程序的一部分,应该这样做:
- 单击按钮时,从中获取 "minutes" 的用户值(整数) 一些文本字段;
- 实例化和对象,它实际上是 SwingWorker 线程,它将启动一个计时器,计数回到零用户 "minutes",然后在 doInBackground() 完成后在 done() 中执行一些操作(启动另一个 JFrame) ;
我在代码中打印了一些点,代码似乎从 textField 中获取输入分钟数,将其传递给倒计时 class 中的构造函数,但随后只是执行 done(),没有 运行 doInBackground() 首先。
如果有人知道为什么会发生这种情况,我将不胜感激,我已经尝试了所有的想法,但没有任何效果。
这是第一部分,来自按钮的代码:
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
userCountTime = Integer.parseInt(jTextField2.getText());
userCountTime = userCountTime * 60;
System.out.println("Preuzeto iz dugmeta " + userCountTime);
if (jRadioButton2.isSelected()){
Countdown countDown= new Countdown (userCountTime);
}
这里是class倒计时:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.SwingWorker;
import javax.swing.Timer;
/**
*
* @author Glupko
*/
public class Countdown extends SwingWorker{
public Timer timer;
static int userCountTime;
static ActionListener timerListener;
//Constructor
public Countdown (int userCountTime){
Countdown.userCountTime = userCountTime;
System.out.println("In constructor: " + Countdown.userCountTime);
this.execute();
}
@Override
protected Object doInBackground() throws Exception {
//defining listener
timerListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
System.out.println("In action performed value is: " + userCountTime);
//for each tick we subtract 1, every second
while (userCountTime >= 0){
userCountTime--;
System.out.println("In actionPerformed there is number of seconds: " + userCountTime);}
timer = new Timer(1000, timerListener);
//start timer
timer.start();
}};}
@Override
protected void done(){
System.out.println("From done: timer elapsed");
ChangingWindow window = new ChangingWindow();
}
}
Many thanks in advance!
- 您不应该从 SwingWorker 的
doInBackground
方法中启动 Swing 计时器。这违背了所有目的,因为 Swing 计时器在 Swing 事件线程或 EDT 上应该是 运行。 - 您的 SwingWorker 的 done 方法将被立即调用,因为
timer.start()
是非阻塞的。
而是摆脱 SwingWorker 并单独使用 Timer。
如需更完整的代码帮助,请考虑创建并发布您的 minimal code example program 以供我们审查、测试并可能修复。
例如.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import javax.swing.*;
public class CountDownTest extends JPanel {
private static final Integer[] SECONDS = {1, 2, 3, 4, 5, 6, 7, 8, 9};
private JSpinner secondsSpinner = new JSpinner(new SpinnerListModel(Arrays.asList(SECONDS)));
public CountDownTest() {
add(secondsSpinner);
add(new JButton(new StartCountDownAction(this, "Start Count Down")));
}
public int getSecondsSpinnerValue() {
return (Integer) secondsSpinner.getValue();
}
private static void createAndShowGui() {
CountDownTest mainPanel = new CountDownTest();
JFrame frame = new JFrame("CountDownTest");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class StartCountDownAction extends AbstractAction {
private CountDownTest countDownTest;
private Timer timer;
public StartCountDownAction(CountDownTest countDownTest, String name) {
super(name);
this.countDownTest = countDownTest;
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
if (timer != null && timer.isRunning()) {
// don't start a new Timer when one is running
return;
}
int seconds = countDownTest.getSecondsSpinnerValue();
timer = new Timer(seconds * 1000, new TimerListener(countDownTest));
timer.setRepeats(false);
timer.start();
}
}
class TimerListener implements ActionListener {
private CountDownTest countDownTest;
public TimerListener(CountDownTest countDownTest) {
this.countDownTest = countDownTest;
}
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(countDownTest, "Timer Done!");
}
}