Swingはまだ比較的新しいですが、数時間検索した後、オンラインで答えを見つけることができなかったため、この投稿(すでに答えられていて見落としていた場合は申し訳ありません)。
SwingアプリケーションでJFreeChartを使用しています。一部のグラフは比較的重く(180kデータポイント)、JFreeChartのChartPanelは最初のpaintComponent()を実行するのに最大6秒かかります。
したがって、コンポーネントがペイントしている間、ダイアログに「お待ちください」というメッセージを表示したいと思います(SwingWorkerで進行状況を表示する必要はありません)。paintComponentメソッドをオーバーライドしようとしましたが、残念ながらメッセージが画面に表示されません(ダイアログをペイントする時間をとらずに、スレッドがチャートのペイントに直接入ると思います)。
私のコードは次のようになります。
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();
}
}
}
これ/ベストプラクティスを解決する方法についてのポインタは非常にありがたいです!
ありがとう、トーマス
アップデート:
ヒントと討論に感謝します:非常に役に立ちました。
JLayerソリューションはEDTでも実行されているため機能しないのではないかと心配しているため、invokeLater()を使用して提案されたソリューションの実装を開始しました。
残念ながら、paintComponent()がinvokeLater()によって呼び出されると、nullポインター例外が発生します。
私のコードは次のようになります。
@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)
}
そして、実行可能なクラスは次のとおりです。
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();
}
}
繰り返しになりますが、どんなポインタでも大歓迎です!
トーマス