I have a swing GUI application with a frame class MainFrame and a class PanelPlan that extends JPanel. I do manipulations with a text file by reading it line by line using BufferedReader and doing other calculations. It is done in a background thread. I have also created a Label with a gif activity indicator in the MainFrame. So, what I am trying to do is to have a user click on a button, the application reads the file in the background, and while it is being done, a spinning indicator becomes visible (or "starts spinning"). When the file has been read, the application updates certain parameters and the activity indicator becomes invisible ("stops spinning").
This is what I have:
private void btnAddDepActionPerformed(java.awt.event.ActionEvent evt) {
MainFrame mainFrame = new MainFrame();
mainFrame.setIndicatorVisible(); // Activity indicator starts spinning
new Thread(() ->
{
//... code to read a text file and perform other operations;
// Activity indicator stops spinning
mainFrame.setIndicatorInvisible();
}).start();
}
In the MainFrame class:
public MainFrame() {
/* Initialize GUI components */
initComponents();
setIndicatorInvisible();
}
public void setIndicatorVisible()
{
System.out.println("\n\nCHECK ACTIVITY INDICATOR ON\n\n");
lblActivityIndicator.setVisible(true);
}
public void setIndicatorInvisible()
{
System.out.println("\n\nCHECK ACTIVITY INDICATOR OFF\n\n");
lblActivityIndicator.setVisible(false);
}
While, the println information is displayed in the console as expected, the activity indicator is never visible. I know that it is set up properly, since when I make it constantly visible, the indicator is spinning (although does not stop spinning when the file has been read).
I wonder if this is the correct approach that I use. I read that GUI should be implemented in the main thread. How would I notify the main thread in my case that the work in the background thread has been completed and the indicator label should be set visible?
Thanks a lot!
I don't know much about the activity indicator, but it looks like a lack of synchronization.
If you can't control what's inside the lblActivityIndicator
then this should do the trick:
public void setIndicatorVisible() {
System.out.println("\n\nCHECK ACTIVITY INDICATOR ON\n\n");
synchronized(lblActivityIndicator) {
lblActivityIndicator.setVisible(true);
}
}
public void setIndicatorInvisible() {
System.out.println("\n\nCHECK ACTIVITY INDICATOR OFF\n\n");
synchronized(lblActivityIndicator) {
lblActivityIndicator.setVisible(false);
}
}