无法更新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….”));