Comment créer des “veuillez patienter” Swing dialogue tout en composant des peintures

Encore relativement nouveau pour Swing, mais après quelques heures de recherche, je ne pouvais pas trouver la réponse en ligne, d'où ce post (désolé si déjà répondu et j'ai oublié).

Je suis en utilisant JFreeChart dans une application Swing. Certains graphiques sont relativement lourds (180k points de données) et la JFreeChart est ChartPanel besoins ~6 secondes pour faire sa première paintComponent().

Donc je voudrais afficher un message "please wait" message dans une boîte de dialogue, tandis que la composante des peintures (pas besoin de montrer les progrès réalisés avec un SwingWorker). J'ai essayé de remplacer la méthode paintComponent, mais malheureusement, le message n'apparaît jamais à l'écran (je suppose que le thread va directement dans la peinture, le graphique, sans prendre le temps de peindre la boîte de dialogue).

Mon code ressemble à ceci:

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();
        }
}
}

Un pointeur sur la façon de résoudre ce /meilleures pratiques serait très apprécié!

Grâce,
Thomas


Mise à JOUR:

Merci pour les conseils & débat: très utile.

J'ai commencé la mise en œuvre de la solution proposée avec le invokeLater() que je suis, de peur que l'JLayer solution ne fonctionne pas puisqu'il est également en cours d'exécution sur l'EDT.

Malheureusement, je fais une exception de pointeur null lorsque le paintComponent() est appelée par le invokeLater().

Mon code ressemble à ceci:

    @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)
}

Et la classe runnable est:

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();
}
}

Encore une fois, tout pointeur serait bien apprécié !

Thomas

La chose la plus simple à faire est de simplement définir un curseur occupé et de réinitialisation à la normale lorsque vous avez terminé...
Jetez un oeil à ma réponse ci-dessous. Il utilise SwingWorker mais c'est votre seul moyen de sortir. Je ne peut pas avoir une meilleure suggestion. Aussi, dans paintComponent vous devriez effectuer seulement la "peinture" des opérations et de ne pas modifier l'INTERFACE utilisateur, ni appel invokeLater.

OriginalL'auteur Tom | 2012-07-31