[英]SwingWorker - How to refresh a JTextfield during an ActionEvent
I have this: basic Application - JButton - JTextField 我有这个: 基本应用程序-JButton-JTextField
I want to display a counter in the JTextField (named tf1) (0->100) when I click on the JButton "Connect". 当我单击JButton“连接”时,我想在JTextField(名称为tf1)(0-> 100)中显示一个计数器。 BUT I want the GUI to display the counting during the event on the JButton.
但是我希望GUI在JButton事件期间显示计数。
So when I click on the JButton, I call : 因此,当我单击JButton时,我会调用:
public class Swing_Lab_2 {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
TestWindows tw = new TestWindows();
}
}
class TestWindows extends JFrame {
private final JPanel pnl;
private final JTextField tf1;
private final JButton btn;
TestWindows() {
super();
pnl = new JPanel(new GridLayout(2, 2));
tf1 = new JTextField();
btn = new JButton("Connect");
pnl.add(btn);
pnl.add(new JPanel());
pnl.add(tf1);
this.setContentPane(pnl);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
goSequenceTest();
}
});
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
private void goSequenceTest() {
CountWorker_TF cw = new CountWorker_TF();
cw.execute();
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(TestWindows.class.getName()).log(Level.SEVERE, null, ex);
}
}
boolean result = cw.getStatus();
System.out.print(String.format("in the interruption %b", result));
}
private class CountWorker_TF extends SwingWorker<Integer, String> {
boolean finished = false;
CountWorker_TF() {
}
@Override
protected Integer doInBackground() throws Exception {
for (int i = 0; i < 101; i++) {
publish(String.format("%d", i));
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(TestWindows.class.getName()).log(Level.SEVERE, null, ex);
}
}
finished = true;
System.out.print(String.format("in the swingWorker %b", finished));
return 1;
}
public boolean getStatus() {
return finished;
}
@Override
protected void process(List<String> strings) {
/* Affichage des publications reçues dans le textarea. */
for (String s : strings) {
tf1.setText(s);
}
}
}
To see if the swing worker worked, I put a breakpoint on boolean result = cw.getStatus(); 要查看秋千工作者是否工作,我在boolean result = cw.getStatus();上设置了一个断点。 , I observe that the counter was active but did not display the count in the Jtextfield.
,我观察到该计数器处于活动状态,但未在Jtextfield中显示该计数。
Could you tell me what I did wrong? 你能告诉我我做错了什么吗?
EDIT: Here, the test case. 编辑:在这里,测试用例。 I put a "Thread.sleep(1000)" to simulate a time consuming calculation (I don't know if it is a good idea) in the method goSequenceTest();
我在方法goSequenceTest()中放入了“ Thread.sleep(1000)”来模拟耗时的计算(我不知道这是否是个好主意); .
。 I observe that the counter was active but did not display the count in the Jtextfield.
我观察到该计数器处于活动状态,但未在Jtextfield中显示该计数。
Many Thanks! 非常感谢!
OC 超频
I understand what was wrong with the code. 我了解代码有什么问题。 It is impossible to modify the GUI during a GUI event!
在 GUI事件期间 无法修改GUI! It seems obvious now... The EDT has a stack, which is filled with actions to do.
现在看来很明显……EDT有一个堆栈,其中充满了要执行的操作。 When I click on the connect button, the EDT has a new action to do in its stack.
当我单击连接按钮时,EDT在其堆栈中有一个新操作要执行。 Until, this action is not completely processed, the EDT can not proceed to the next action on its stack.
直到该操作未完全处理,EDT才能继续执行其堆栈上的下一个操作。
What I tried to do with my Swingworker was not the good way to do it. 我尝试与Swingworker一起工作的方法不是很好的方法。 And add "Thread.sleep(1000)" in my method was stupid, since I block the EDT for 1000ms.
在我的方法中添加“ Thread.sleep(1000)”是愚蠢的,因为我将EDT阻止了1000ms。
I solved my issue by using two threads: 我通过使用两个线程解决了我的问题:
CalculationThread handles my time consuming calculation: CalculationThread处理我的耗时计算:
private class CalculationThread extends Thread {
public CalculationThread() {
super();
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(TestWindows.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(String.format("I am processing a calculation consuming time %d", i));
}
}
}
SwingWorkerThread handles my SwingWorker. SwingWorkerThread处理我的SwingWorker。 (The JOptionPane is here to see if the Thread which handles the consuming calculation task works properly):
(JOptionPane在这里查看处理消耗计算任务的线程是否正常工作):
private class SwingWorkerThread extends Thread {
boolean reloadFpga = false;
public SwingWorkerThread() {
super();
}
public void run() {
Object[] options = {"Yes", "No"};
String txt = "Would you like start counting ?";
int reload = JOptionPane.showOptionDialog(TestWindows.this.getFrame(), txt, "Counting ?", JOptionPane.WARNING_MESSAGE, JOptionPane.YES_NO_OPTION, null, options, null);
reloadFpga = (reload == 0);
if (reloadFpga) {
CountWorker_TF cw = new CountWorker_TF();
cw.execute();
boolean result = false;
while (!result) {
result = cw.getStatus();
System.out.print(String.format("In the SwingWorker %b \n", result));
}
}
}
}
The goSequenceTest() method looks like: goSequenceTest()方法如下所示:
private void goSequenceTest() {
SwingWorkerThread tt = new SwingWorkerThread();
tt.start();
CalculationThread tt2 = new CalculationThread();
tt2.start();
System.out.print(String.format("End EDT"));
}
Add the following getFrame() method in the class TestWindows to see the project works: 在类TestWindows中添加以下getFrame()方法以查看项目的工作情况:
private Component getFrame() {
return this;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.