有什么方法可以延迟PaintComponent?

时间:2015-03-25 02:22:22

标签: java swing paintcomponent event-dispatch-thread

我在这里阅读了paintComponent上的大量线程,其中大部分内容都指出,当调用paintComponent时,它要么永远也要几乎不需要(或可能)。

然而,在我的程序中,有时(仅有时)paintComponent在它需要绘制的一些对象完成初始化之前被调用,甚至有时在它们被创建之前被调用,触发警告 - JOptionPane弹出窗口,这令人惊讶地做没有显示任何硬编码的文字显示在他们的“消息”区域。我在其他地方读到这与EDT有关,我已经研究了一些部分,但我只是感到困惑。如果EDT的主要目的是更新gui,并且默认情况下几乎所有内容都将在EDT中运行,那么我可以告诉程序在不同的线程中运行所有初始化和更新函数,我不知怎的在EDT运行之前强行运行?

我想要发生的事情是paintComponent要等到我的代码中的某个点运行(在一堆更新函数之后,无论屏幕发生了什么。在它被调用之后,它之后是暂停,其中相对较少(我在while循环中使用Thread.sleep())并且持续到用户点击某些东西 - 此时所有必要的函数再次运行,然后是paintComponent之后,然后是sleep()while while等。

根据我的理解,我认为我想要的并不是真的可能,所以我的问题是:你们有什么想法可以解决这个问题吗?

编辑: 所以基本上这个课程是一个大学课程规划师,旨在让人们更容易按学期规划他们毕业前必须学习的所有课程,移动这些课程(如果可能的话),看看所有课程是如何连接的(先决条件等)。程序启动时,它会从文本文件中加载必要课程列表,然后从一堆单独的文本文件中加载有关每门课程的信息,并根据其先决条件进行排列。没有先决条件的课程在第一学期进行,其中先修课程全部被添加到第一学期的课程被添加到第二学期,依此类推,直到所有课程都被添加为止。当paintComponent运行时,它会调用一个函数,该函数假定计划中存在所有每个课程的先决条件,如果发现其他情况,则会抛出错误并显示JOptionPane消息框。当在程序的正常运行期间发生这种情况时(例如,如果我在添加其先决条件之前手动添加课程),那么所有工作和正确显示。但有时只有一些课程被加载时弹出消息框(意味着控件仍然在主构造函数中),当它这样做时,实际的字符串消息不会显示 - 只有实际的窗格,标题和确定按钮做。下面是我显示错误框的行,所以你可以知道我不是要显示一个可能为空的字符串变量。

  

JOptionPane.showMessageDialog(此,                         “课程无法加载,部分>已加载\ n课程已删除。”,                         “错误”,                         JOptionPane.OK_OPTION);

这是“课程无法......被删除”。没有显示的部分。这是我唯一显示标题为“Error”的JOptionPane。 这篇文章提到了听起来像是发生了同样的事情,除了我没有使用海报必须解决的任何事情。所以可能它是无关紧要的,但我会添加它以防万一。 JOptionPane.showMessageDialog() shows but without any message?

但要退一步,因为在添加所有课程之前弹出了该框,这意味着在初始化一堆东西之前,在相关JPanel的构造函数中间以某种方式调用了paintComponent。我添加了一堆println()语句以确保这是真的。发生这种情况是否正常,如果是这样,有没有办法解决它而不仅仅使用Andrew Thompson的建议?

在考虑了一下后,我认为因为该项目长度为3200行并且在很大程度上依赖于文本文件,所以我真的不确定如何(或者如果可以)为它制作SSCCE。

如果任何特定的部分会有所帮助,我很乐意添加这些,但如果这个问题不明显是一些标准问题,那我就错了,那么我只是添加那个标志并继续寻找错误。

感谢您的帮助

1 个答案:

答案 0 :(得分:2)

将标志声明为类属性。在paint方法中检查它。在初始化结束时更改它。

class XandYandZ extends JComponent {

  boolean initializationFinished = false;

  public XandYandZ() {
    // long initialisation..
    initializationFinished = true;
  }

  public void paintComponent(Graphics g) {
    if (!initializationFinished) return;
    // .. paint ..