Ardel Ardel - 3 months ago 8
Java Question

JPanel not showing image on the second time loading

I am creating a project that pulls data from an SQL data base. While that data loads I want the end user to see a loading frame. On the first run it shows the frame with the image. The second time, when the user changes what zones he sees, the frame comes up again but this time doesn't show the image until after the function inside the action finishes. Could you take a look at my code and point me to what i am doing wrong?

confirm.addActionListener(new ActionListener()
{
ArrayList<String> newZones = new ArrayList<String>();
public void actionPerformed(ActionEvent e)
{
JFrame loadingFrame = new JFrame();
JPanel loadingPanel = new JPanel();

loadingFrame.setSize(500, 500);
JLabel loadingL = new JLabel(new ImageIcon("C:/Users/gria/Desktop/Images/Loading.png"));
loadingPanel.add(loadingL);
loadingFrame.add(loadingPanel);

loadingFrame.validate();
loadingFrame.repaint();
loadingFrame.pack();

loadingFrame.setVisible(true);

// The Image will not show until this function finishes which is where all the data base connections take place.
Console.SetZones(newZones);
}
});

Answer

The Image will not show until this function finishes which is where all the data base connections take place.

Swing is single threaded, which means calling any task that may take a significant amount of time will prevent Swing from performing its normal tasks (painting, event dispatching, etc...) until that task completes. Your code calls the following:

// The Image will not show until this function finishes which is where all the data base connections take place. 
Console.SetZones(newZones);

...from within an ActionListener implementation, which means it is being called on the Event Dispatch Thread (the EDT). To avoid this, call this method in a new Thread or use a SwingWorker. Either way, be sure any calls to Swing from a different thread get dispatched to the EDT using SwingUtilities.invoke* or if using SwingWorker its methods