简体   繁体   中英

Java JTextField cannot be updated

when I run the following code, I have problem in the level of the TextField . It is not updated during the process. Only when all the calculations was made, it will be updated completely at once.

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 ….

Running the code will make the following :

  • Prints in the consol : Start….!!
  • Calculates Result1
  • Prints in the consol the value of Result1
  • Calculates Result2
  • Prints in the console the value of Result2
  • Calculates Result3
  • Prints in the console the value of Result3

After that it updates MyJTextField completely at once.

Thanks a lot for any useful help.

I'd call all Swing UI-related methods inside an anonymous java.lang.Runnable class and run it by passing it to SwingUtilities.invokeLater(Runnable runnable) . This ensures that the UI operations called inside of the Runnable's run() method will be called on the EDT (event dispatching thread). Never run Swing operations on eg the same thread that does for example longer running computations. See code below...

// 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 ….

shorter version using lambdas (Java8+):

SwingUtilities.invokeLater(() -> MyJTextField.setText("Result2 is calculated now….”));

If you're using Java swing library, then the UI is rendered by a specific thread, meaning a thread update the UI at a different time the calculation are made from the main thread.

You should try to use the validate() or repaint() methods over Swing components to update them properly as:

MyJTextField.setText("Result1 is calculated now….”); 
MyJTextField.validate();
// or MyJTextField.repaint();

it will be updated completely at once.

All the code is executing on the Event Dispatch Thread (EDT) , so the GUI can only repaint itself once the processing is finished.

If you have a long running task, then you need to execute that task on a separate Thread so you don't block he EDT and the GUI is able to repaint itself.

One way to do this is to use a SwingWorker . Read the section from the Swing tutorial on Concurrency for more information about the EDT and how to use a SwingWorker .

If you want to update the GUI while the database access is being done you can then "publish" the updates. This will make sure the GUI is updated on the EDT.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM