gpt4 book ai didi

java - SwingWorker 没有响应

转载 作者:搜寻专家 更新时间:2023-11-01 01:43:56 26 4
gpt4 key购买 nike

我想做什么?

单击Start JButton 时,SwingWorker 将执行。在 doInBackground() 方法中,我将 arrNames 的每个索引传递给 publish() 方法,以便它可以在内部显示JTextArea

发生了什么?

如果我保留行 System.out.format("Counter : %d%n", counter); 作为注释,在 SwingWorkerdoInBackground() 方法中,SwingWorker 按预期工作。不过,如果我将其注释掉,那么 SwingWorker 将停止响应

我做错了什么吗?


Java 版本:

java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b16)
Java HotSpot(TM) Client VM (build 23.25-b01, mixed mode, sharing)

这是我使用的代码:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SwingWorkerExample1
{
private JLabel statusLabel;
private JTextArea tArea;
private JButton startButton;
private JButton stopButton;

private BackgroundTask backgroundTask;

private ActionListener buttonActions =
new ActionListener()
{
@Override
public void actionPerformed(ActionEvent ae)
{
JButton source = (JButton) ae.getSource();
if (source == startButton)
{
startButton.setEnabled(false);
stopButton.setEnabled(true);
backgroundTask = new BackgroundTask();
backgroundTask.execute();
}
else if (source == stopButton)
{
backgroundTask.cancel(true);
stopButton.setEnabled(false);
startButton.setEnabled(true);
}
}
};

private void displayGUI()
{
JFrame frame = new JFrame("Swing Worker Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

JPanel contentPane = new JPanel();
contentPane.setBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(5, 5));

statusLabel = new JLabel("Status Bar", JLabel.CENTER);

tArea = new JTextArea(20, 20);
tArea.setWrapStyleWord(true);
tArea.setLineWrap(true);
JScrollPane textScroller = new JScrollPane();
textScroller.setBorder(
BorderFactory.createTitledBorder("Textual OUTPUT : "));
textScroller.setViewportView(tArea);

startButton = new JButton("Start");
startButton.addActionListener(buttonActions);
stopButton = new JButton("Stop");
stopButton.setEnabled(false);
stopButton.addActionListener(buttonActions);
JPanel buttonPanel = new JPanel();
buttonPanel.add(startButton);
buttonPanel.add(stopButton);

contentPane.add(statusLabel, BorderLayout.PAGE_START);
contentPane.add(textScroller, BorderLayout.CENTER);
contentPane.add(buttonPanel, BorderLayout.PAGE_END);

frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}

private class BackgroundTask extends SwingWorker<Void, String>
{
private int counter = 0;

private String[] arrNames = { "US Rates Strategy Cash",
"Pavan Wadhwa(1-212) 844-4597", "Srini Ramaswamy(1-212) 844-4983",
"Meera Chandan(1-212) 855-4555", "Kimberly Harano(1-212) 823-4996",
"Feng Deng(1-212) 855-2555", "US Rates Strategy Derivatives",
"Srini Ramaswamy(1-212) 811-4999",
"Alberto Iglesias(1-212) 898-5442",
"Praveen Korapaty(1-212) 812-3444", "Feng Deng(1-212) 812-2456",
"US Rates Strategy Derivatives", "Srini Ramaswamy(1-212) 822-4999",
"Alberto Iglesias(1-212) 822-5098",
"Praveen Korapaty(1-212) 812-3655", "Feng Deng(1-212) 899-2222" };

public BackgroundTask()
{
statusLabel.setText((this.getState()).toString());
System.out.println(this.getState());
}

@Override
protected Void doInBackground()
{
statusLabel.setText((this.getState()).toString());
System.out.println(this.getState());
while (!isCancelled())
{
counter %= arrNames.length;
//System.out.format("Counter : %d%n", counter);
publish(arrNames[counter]);
counter++;
}
statusLabel.setText((this.getState()).toString());
System.out.println(this.getState());
return null;
}

@Override
protected void process(java.util.List<String> messages)
{
for (String message : messages)
tArea.append(String.format(message + "%n"));
}
}

public static void main(String[] args)
{
Runnable runnable = new Runnable()
{
@Override
public void run()
{
new SwingWorkerExample1().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}

编辑 1:

如建议的那样,如果我添加 Thread.sleep(...),它确实有效,但它会抛出一个 InterruptedException,如下所示。所以这个技巧奏效了。但这是执行它的合法方式吗?

C:\Mine\JAVA\J2SE\classes>java SwingWorkerExample1
PENDING
STARTED
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at SwingWorkerExample1$BackgroundTask.doInBackground(SwingWorkerExample1.java:108)
at SwingWorkerExample1$BackgroundTask.doInBackground(SwingWorkerExample1.java:76)
at javax.swing.SwingWorker$1.call(SwingWorker.java:296)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at javax.swing.SwingWorker.run(SwingWorker.java:335)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
DONE

编辑 2:

只有 doInBackground() 发生了变化,引发了上述异常:

@Override
protected Void doInBackground()
{
Runnable runnable = new Runnable()
{
@Override
public void run()
{
statusLabel.setText((BackgroundTask.this.getState()).toString());
}
};
EventQueue.invokeLater(runnable);

System.out.println(this.getState());
while (!isCancelled())
{
counter %= arrNames.length;
//System.out.format("Counter : %d%n", counter);
publish(arrNames[counter]);
try
{Thread.sleep(30);}
catch(InterruptedException ie)
{ie.printStackTrace();}
counter++;
}
runnable = new Runnable()
{
@Override
public void run()
{
statusLabel.setText((BackgroundTask.this.getState()).toString());
}
};
EventQueue.invokeLater(runnable);
System.out.println(this.getState());
return null;
}

最佳答案

if I add Thread.sleep(...), it does work, though, it throws a InterruptedException

显然产生异常的代码(从 OP 的编辑中复制):

while (!isCancelled()) {
counter %= arrNames.length;
// System.out.format("Counter : %d%n", counter);
publish(arrNames[counter]);
try {
Thread.sleep(30); // throws
} catch (InterruptedException ie) {
ie.printStackTrace();
}
counter++;
}

不过,原因在于取消 worker 的代码(在 actionListener 中):

backgroundTask.cancel(true);

它明确地告诉工作人员通过..中断线程来取消。从它的 api 文档:

mayInterruptIfRunning - true if the thread executing this task should be interrupted; otherwise, in-progress tasks are allowed to complete

顺便说一句:捕获异常并且什么都不做(从而有效地忽略中断)并不是最好的主意。在这种情况下可能不会造成太大破坏 - 由于检查已取消状态。典型的 worker 实现要么在需要时进行一些内部清理后捕获并返回,要么根本不处理它。

关于java - SwingWorker 没有响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17759287/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com