0

I have a Java program that's using ProcessBuilder to set up some Servers. I have also made a Form, that displays a JProgressBar, a JLabel and a JTextArea. The Progressbar is set to be indeterminate, since there doesn't seem to be a way for easy calculation of the workload. The Label is regularly updated to show the User at which step the programm currently is, and the TextArea displays extra information about the current step.

However, when I start the setup, the Window opens and displays nothing. Just a blank white window with a title. That is until the setup is either done, or when I'm debugging, where it will sometimes actually display something for a short time.

I have tried calling panel.revalidate() together with panel.repaint() everytime I update a property, but this hasn't changed anything. I remember faintly that there's a specific way to update components while the program is doing stuff in the background, but cannot remember how, and wasn't able to find anything helpful so far.

public void shutdownSystems() throws IOException, InterruptedException {
    for (String ip : ipArray) {
        if (isWindows) builder.command(ipmitool, ip, "ADMIN", "ADMIN", "ipmi", "power", "down");
        loadingForm.setProgressInfo("Shutting down System " + ip);
        startProcess();
        loadingForm.setProgressInfo(streamGobbler.getResult());
        refreshLoadingWindow();
    }
}

Here's a piece of code to showcase how I'm trying to do it currently. loadingForm refers to the window which is supposed to have it's components updated. startProcess(); is a local method that executes the command set by the ProcessBuilder builder and compiles the output to also add this information to the window. Last but not least, I call refreshLoadingWindow(); which basically just gets the panel of loadingForm and executes .revalidate(); and .repaint();

The main thing that is confusing me is, while I understand that there's probably a different approach to updating GUIs, it doesn't even show the components at all. Not even when first opening the window.

Can anyone tell me what I'm supposed to be doing instead?

Korlimann
  • 147
  • 14
  • 4
    During your loop you probably execute long-time operations. This prevents repainting of your UI. To avoid this problem you should move all your long-running tasks into a [SwingWorker](https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html). Please also read about [Concurrency in Swing](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html). – Sergiy Medvynskyy Jun 17 '21 at 09:12
  • @SergiyMedvynskyy thank you very much! I've been reading up on `SwingWorker` but am still unsure how to update my GUI. There is an option to `publish()` or `process()` output, but there is also the option to use `PropertyChangeListener` and `firePropertyChange`. Do I need both? If not, how do I determine which would be the better solution for me? Also, I already have a class that handles the whole logic/execution. Can I hand this class to my SwingWorker and have it call the methods from the `doInBackground()` method, like `setup.restartSystems()` for example? – Korlimann Jun 17 '21 at 10:24
  • 1
    https://stackoverflow.com/a/11546203/5784265 should help, in short: to update the UI while doing work in doInBackground, call publish(V...), which calls process(List) (you have to overwrite that one), which then updates the GUI based on the data passed. – Lahzey Jun 17 '21 at 10:34
  • @Lahzey awesome, thanks! Just one more question, I have 2 different outputs (JLabel and JTextArea), is there a way for the publish command to distinguish between the two? – Korlimann Jun 17 '21 at 11:31
  • 1
    The way I understand it the publish method is just to inform that progress has been made (for example when finishing a step and continuing to the next), so it is more business logic oriented and does not really care about the UI Components individually. The process method is then responsible of updating the UI accordingly, so it should know when to update which component (you can also update both at the same time if necessary). – Lahzey Jun 17 '21 at 11:46

0 Answers0