无法更新Java JTextField
运行以下代码时,无法更新Java JTextField,java,swing,Java,Swing,运行以下代码时,TextField的级别出现问题。在此过程中不会更新仅完成所有计算后,将立即完全更新 System.out.println("Start....!!"); MyJTextField.setText("Start....!!"); MyJTextField.setText("Result1 is calculated now….”); /* here : Connect a DataBase and Make Calculations of the Var : Result1
TextField
的级别出现问题。在此过程中不会更新仅完成所有计算后,将立即完全更新
System.out.println("Start....!!");
MyJTextField.setText("Start....!!");
MyJTextField.setText("Result1 is calculated now….”);
/* here : Connect a DataBase and Make Calculations of the Var : Result1 */
System.out.println(Result1);
MyJTextField.setText("Result2 is calculated now….”);
/* here : Connect a DataBase and Make Calculations of the Var : Result2 */
System.out.println(Result2);
MyJTextField.setText("Result3 is calculated now….”);
/* here : Connect a DataBase and Make Calculations of the Var : Result3 */
System.out.println(Result3);
// and so ….
运行该代码将使以下各项:
- 控制台中的打印:开始李>
- 计算结果1
- 在控制台中打印Result1的值
- 计算结果2
- 在控制台中打印Result2的值
- 计算结果3
- 在控制台中打印Result3的值
MyJTextField
非常感谢您提供的有用帮助。如果您使用的是Java swing库,则UI由特定线程呈现,这意味着线程会在与主线程不同的时间更新UI 您应该尝试在Swing组件上使用
validate()
或repaint()
方法来正确更新它们,如下所示:
MyJTextField.setText("Result1 is calculated now….”);
MyJTextField.validate();
// or MyJTextField.repaint();
它将立即完全更新
所有代码都在事件调度线程(EDT)
上执行,因此GUI只能在处理完成后重新绘制自身
如果您有一个长时间运行的任务,那么您需要在一个单独的线程上执行该任务,这样您就不会阻塞EDT
,GUI就能够重新绘制自己
一种方法是使用SwingWorker
。有关EDT和如何使用SwingWorker
的更多信息,请阅读上Swing教程的部分
如果要在数据库访问完成时更新GUI,则可以“发布”更新。这将确保GUI在EDT上更新。我将调用匿名java.lang.Runnable
类中所有与Swing UI相关的方法,并通过将其传递给SwingUtilities.invokeLater(Runnable Runnable)
来运行它。这确保在可运行的run()
方法内部调用的UI操作将在EDT(事件调度线程)上调用。切勿在执行长时间运行计算的同一线程上运行Swing操作。请参阅下面的代码
// non-ui thread
System.out.println("Start....!!");
// call on ui-thread (event dispatching thread)
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MyJTextField.setText("Start....!!");
MyJTextField.setText("Result1 is calculated now….”);
}
}
// non ui-thread again...
/* here : Connect a DataBase and Make Calculations of the Var : Result1 */
System.out.println(Result1);
// call on ui-thread again (event dispatching thread)
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MyJTextField.setText("Result2 is calculated now….”);
}
}
// and so ….
使用lambdas(Java8+)的较短版本:
(1-)不需要调用validate()或repaint()。当组件的属性更改时,Swing组件将自动在其自身上调用revalidate()和repaint()。问题是代码已经在EDT上运行。这个答案并没有明确说明在开始添加invokeLater()逻辑之前,长时间运行的任务必须移动到单独的线程。虽然在代码的注释中提到了这一点,但从口头描述来看问题并不明显。不幸的是,它不起作用。。。另外,我不明白最后两行。。。谢谢你看起来很完美。。。你能不能写一个示例代码,说明如何重新编写我的代码???非常感谢…本教程提供了一个工作示例。您将代码移动到SwingWorker。或者创建一个线程,将所有代码移动到线程的run()方法(Tommy向您展示了这种方法的代码)。我们不是来为您编写代码的。
SwingUtilities.invokeLater(() -> MyJTextField.setText("Result2 is calculated now….”));