【发布时间】:2012-07-29 14:52:32
【问题描述】:
对于 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();
}
}
再次感谢任何指针!
托马斯
【问题讨论】:
-
最简单的做法是设置一个繁忙的光标并在完成后重置为正常...
-
@user1235867 看看我下面的回答。它使用 SwingWorker,但这是你唯一的出路。我不能有更好的建议。此外,在 paintComponent 中,您应该只执行“绘画”操作,而不是修改 UI 或调用 invokeLater。
标签: java swing jfreechart