Reputation: 955
This is my code:
public MyClass() {
JButton btnNext;
private void initComponents() {
btnNext = new javax.swing.JButton();
btnNext.setText("Lanjut");
btnNext.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnNextActionPerformed(evt);
}
});
}
private void btnNextActionPerformed(java.awt.event.ActionEvent evt) {
btnNext.setText("Loading...");
callingFunction();
}
}
Note: callingFunction() is a function which takes a long time to execute.
My problem is my button text will change to "Loading..." only after callingFunction() is done.
How do I change the btnNext text to "Loading..." immediately?
Upvotes: 0
Views: 90
Reputation: 50041
The button won't be repainted until control returns to the Swing event queue. Calling that function on the event dispatch thread is blocking the event queue.
As a workaround, tell it to run the function later (as soon as it's done repainting things):
In Java 8+:
EventQueue.invokeLater(() -> callingFunction());
In old Java:
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
callingFunction();
}
});
Note that this will still have the side-effect of blocking further interaction with the GUI while that function is running. If you want to run a long task in a background thread to keep the GUI interactive, use a SwingWorker
. A minimal example, assuming callingFunction
returns some result of type String
(or whatever) that you want to use to update the display:
new SwingWorker<String,Void>() {
@Override
protected String doInBackground() throws Exception {
// called on a background thread
return callingFunction();
}
@Override
protected void done() {
// called on the event dispatch thread after the work is done
String result;
try {
result = get();
} catch (Exception e) {
throw new RuntimeException(e);
}
// do something with the result ...
someTextField.setText(result);
}
}.execute();
Upvotes: 5