Java: индикатор активности для чтения текстового файла в фоновом потоке

У меня есть приложение Swing GUI с классом фрейма MainFrame и классом PanelPlan, который расширяет JPanel. Я делаю манипуляции с текстовым файлом, читая его построчно с помощью BufferedReader и выполняя другие вычисления. Это делается в фоновом потоке. Я также создал метку с индикатором активности gif в MainFrame. Итак, что я пытаюсь сделать, так это заставить пользователя нажать кнопку, приложение читает файл в фоновом режиме, и пока это делается, индикатор вращения становится видимым (или «начинает вращаться»). Когда файл прочитан, приложение обновляет некоторые параметры и индикатор активности становится невидимым ("перестает крутиться").

Вот что у меня есть:

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

В классе MainFrame:

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

Хотя информация о println отображается в консоли, как и ожидалось, индикатор активности никогда не отображается. Я знаю, что он настроен правильно, так как, когда я делаю его постоянно видимым, индикатор крутится (хотя и не перестает крутиться, когда файл прочитан).

Интересно, это правильный подход, который я использую. Я читал, что графический интерфейс должен быть реализован в основном потоке. Как мне уведомить основной поток в моем случае о том, что работа в фоновом потоке завершена и метка индикатора должна быть установлена ​​видимой?

Большое спасибо!


person Leila Abirova    schedule 25.09.2016    source источник


Ответы (1)


Про индикатор активности мало что знаю, но похоже на отсутствие синхронизации.

Если вы не можете контролировать то, что находится внутри lblActivityIndicator, то это должно помочь:

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);
    }
}
person bashnesnos    schedule 28.09.2016