Search code examples
javaactionsequencejlabel

have Jlabel appear right after click then disappear after code runs in Java, like a Java progress Loader, event sequence after a click action


I'm quite new to JAVA but am trying to create a bit of a progress loader and can't seem to find the proper way to have it appear and disappear at the right time. Basically I have a button that triggers a bunch of code. This code may take like a few minutes to run. During this time I would like to display an animated hour glass .gif and have it disapear when it is finished.

Basically, the hour glass is inside the jlabel and is set to invisible at first. When the Jbutton is clicked in the action event I first write to set it to visible then their goes like 50 if statements and a few functions that write to cmd and retrieve the output. Then once all that is finished I write to have it invisible again. The only problem is that it only appears after the progress of code is finished defeating the whole purpose of using it as a progress loader. Does anyone know how to achieve this effect? Here is the code:

    //The JLabel
    JLabel lblLoading = new JLabel("Loading");
    lblLoading.setIcon(new ImageIcon("hourglass.gif"));
    lblLoading.setBounds(407, 274, 132, 74);
    lblLoading.setVisible(false);
    // The Button Code
    btnCheckUpdates.setIcon(new ImageIcon("image/checkicon.png"));
    btnCheckUpdates.setBounds(216, 361, 148, 34);
    frame.getContentPane().add(btnCheckUpdates);
    // the action event on click
    btnCheckUpdates.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
        //I set visible to true in the begening
        lblLoading.setVisible(true);
        // Here goes like 50 if statements
        // call to function which writes to cmd.exe then returns info
        // info is checked  (like another 50 if statements)
        // call to cmd function again
        // Now after all the code is written i try to make it invisible again
        lblLoading.setVisible(false);
        }
    });

I'm sure I'm probably not understanding at all how something works. Does anybody know why this could be happening and how to make it work properly or at least use some simple tricks to make it seem like it's working? Any help is greatly appreciated!!!


Solution

  • From the looks of it you're doing everything on the main thread which causes the GUI to freeze up until the workload from the updating is complete. If you're going to make a progress bar in Swing your best bet is using a SwingWorker so you can perform background logic while safely updating the Swing components. In your case it might look something like this:

        private JLabel lblLoading;
        private UpdateTask task;
    
        ...
            lblLoading = new JLabel("Loading");
            lblLoading.setIcon(new ImageIcon("hourglass.gif"));
            lblLoading.setBounds(407, 274, 132, 74);
            lblLoading.setVisible(false);
            // The Button Code
            btnCheckUpdates.setIcon(new ImageIcon("image/checkicon.png"));
            btnCheckUpdates.setBounds(216, 361, 148, 34);
            frame.getContentPane().add(btnCheckUpdates);
            // the action event on click
            btnCheckUpdates.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {
                    task = new UpdateTask().execute();
                }
            });
         }
    
        private class UpdateTask extends SwingWorker<Void,Void> {
    
            @Override
            protected Void doInBackground() throws Exception {
                lblLoading.setVisible(true);
    
                // Initialize progress
                setProgress(0);
    
                // Background logic goes here
    
                // Progress can be updated as necessary
                setProgress(50);
    
                setProgress(100);
    
                return null;
            }
    
            @Override
            protected void done() {
                lblLoading.setVisible(false);
            }
        }
    

    There's also a fully functional ProgressBarDemo that can be found on Oracle's website.