Search code examples
javamultithreadingactivity-indicator

Java: activity indicator for reading text file in the background thread


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!


Solution

  • 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);
        }
    }