Still relatively new to Swing but after a couple of hours of search, I couldn't find the answer online, hence this post (sorry if already answered and I overlooked it).
I'm using JFreeChart in a Swing application. Some charts are relatively heavy (180k data points) and the JFreeChart's ChartPanel needs ~6 seconds to do its first paintComponent().
Hence I would like to show a "Please wait" message in a dialog while the component paints (no need to show progress with a SwingWorker). I tried to override the paintComponent method but unfortunately the message never appears on screen (I guess the thread directly goes into painting the chart, without taking the time to paint the dialog).
My code looks like this:
public class CustomizedChartPanel extends ChartPanel{
private static final long serialVersionUID = 1L;
private JDialog dialog = null;
boolean isPainted = false;
public CustomizedChartPanel(JFreeChart chart) { super(chart); }
@Override
public void paintComponent(Graphics g) {
//At first paint (which can be lengthy for large charts), show "please wait" message
if (! isPainted){
dialog = new JDialog();
dialog.setUndecorated(true);
JPanel panel = new JPanel();
panel.add(new JLabel("Please wait"));
dialog.add(panel);
dialog.pack();
GuiHelper.centerDialog(dialog); //Custom code to center the dialog on the screen
dialog.setVisible(true);
dialog.repaint();
}
super.paintComponent(g);
if (! isPainted){
isPainted = true;
dialog.dispose();
super.repaint();
}
}
}
Any pointer on how to solve this / best practices would be very much appreciated!
Thanks, Thomas
UPDATE:
Thanks for the hints & debate: very helpful.
I started implementing the suggested solution with the invokeLater() as I'm fearing that the JLayer solution won't work since it's also running on the EDT.
Unfortunately I'm having a null pointer exception when the paintComponent() is called by the invokeLater().
My code looks like this:
@Override
public void paintComponent(Graphics graph) {
//At first paint (which can be lengthy for large charts), show "please wait" message
if (! isPainted){
isPainted = true;
dialog = new JDialog();
dialog.setUndecorated(true);
JPanel panel = new JPanel();
panel.add(new JLabel("Please wait"));
panel.add(new JLabel("Please wait !!!!!!!!!!!!!!!!!!!!!!!!!!!!!"));
dialog.add(panel);
dialog.pack();
GuiHelper.centerDialog(dialog); //Custom code to center the dialog on the screen
dialog.setVisible(true);
dialog.repaint();
RunnableRepaintCaller r = new RunnableRepaintCaller(this, graph, dialog);
SwingUtilities.invokeLater(r);
}
else super.paintComponent(graph); //NULL POINTER EXCEPTION HERE (invoked by runnable class)
}
And the runnable class is:
public class RunnableRepaintCaller implements Runnable{
private ChartPanel target;
private Graphics g;
private JDialog dialog;
public RunnableRepaintCaller(ChartPanel target, Graphics g, JDialog dialog){
this.target = target;
this.g = g;
this.dialog = dialog;
}
@Override
public void run() {
System.out.println(g);
target.paintComponent(g);
dialog.dispose();
}
}
Again, any pointer would be much appreciated !
Thomas