I have a swing application. I'm trying show a loading glass pane while reading the data from the database. But the behavior is not what i was expecting.
public class Sample {
JFrame frame;
JPanel loadingPanel;
JLabel iconLabel;
JPanel glassPane;
private PropertyChangeSupport changeListeners = new PropertyChangeSupport(this);
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Sample window = new Sample ();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Sample () {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setSize(new Dimension(500,500));
frame.getContentPane().add(panel);
panel.setLayout(null);
// ---------Select button--------------------------------
JButton btnSelect = new JButton("Select");
btnSelect.addActionListener(loadDataActionListner);
btnSelect.setBounds(132, 7, 137, 32);
btnSelect.setFocusPainted(false);
panel.add(btnSelect);
glassPane = new GlassPanel();
glassPane.setOpaque(false);
glassPane.setLayout(new GridBagLayout());
glassPane.add(new JLabel("loading... "));
frame.setGlassPane(glassPane);
ChangeListener listener = new ChangeListener(this);
changeListeners.addPropertyChangeListener(listener);
}
public void changeVisibility(boolean visibility){
glassPane.setVisible(visibility);
frame.validate();
frame.repaint();
}
ActionListener loadDataActionListner = new ActionListener() {
public void actionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
changeListeners.firePropertyChange("visibility", false, true); //Line 01
Response response = DataManager.getInstance().loadData("myfile.txt");
changeListeners.firePropertyChange("visibility", true, false);
}
}
});
}
};
}
public class GlassPaneUpdateWorker extends SwingWorker<Object, Boolean> {
private boolean visibility;
private Sample sample;
public GlassPaneUpdateWorker(Sample sample) {
this.sample = sample;
}
@Override
protected Object doInBackground() throws Exception {
publish(visibility);
return null;
}
@Override
protected void process(List<Boolean> chunks) {
if (chunks != null && !chunks.isEmpty()) {
sample.changeVisibility(chunks.get(0));
}
}
protected void changeVisibility(boolean visibility) {
this.visibility = visibility;
}
}
public class ChangeListener implements PropertyChangeListener{
private Sample sample;
public ChangeListener(Sample sample) {
this.sample = sample;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
GlassPaneUpdateWorker glassPaneUpdater = new GlassPaneUpdateWorker(sample);
glassPaneUpdater.changeVisibility((Boolean)evt.getNewValue());
glassPaneUpdater.execute();
}
}
Loading glass panel appear after all the code block is executed in the actionPerformed method. How can i change this, so that UI is updated just after "Line 01" execution.?