对 Swing 来说仍然相对较新,但经过几个小时的搜索,我无法在网上找到答案,因此发表了这篇文章(抱歉,如果已经回答但我忽略了它)。
我在 Swing 应用程序中使用 JFreeChart。一些图表相对较重(180k 数据点),JFreeChart 的 ChartPanel 需要大约 6 秒来完成它的第一个 paintComponent()。
因此,我想在组件绘制时在对话框中显示“请稍候”消息(无需使用 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();
}
}
}
非常感谢任何有关如何解决此问题/最佳实践的指示!
谢谢,托马斯
更新:
感谢您的提示和辩论:非常有帮助。
我开始使用 invokeLater() 实施建议的解决方案,因为我担心 JLayer 解决方案将无法工作,因为它也在 EDT 上运行。
不幸的是,当invokeLater() 调用paintComponent() 时,我遇到了一个空指针异常。
我的代码如下所示:
@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();
}
}
再次,任何指针将不胜感激!
托马斯