1

所以我有这个问题。我有一个创建和加载文件的程序。

当我将文件加载到我的程序中时,我依靠一个组件侦听器来告诉我特定组件何时“满”,然后根据它移动所有组件。

我在顶部添加每个组件,然后在父组件“填充”时注册侦听器并将底部组件移动到它也创建的新父级。可以把它想象成在一个百页的 MSWord 文档的开头添加一个新的文本行。

该侦听器还依赖于 GUI 设置 - 如果内存中的所有内容都没有绘制到屏幕上,它会抓取错误的组件高度(通常为 0)并在计算中使用它们,然后结果就会出错,一切都会变得一团糟。

这是我的程序那部分的流程图:

(everytning 发生在 JFrame 中的 JPanel 上)

trigger opening method:
{
    repeat this x (lets say e.g. 100) times:
    {
        trigger addComponent method
        {
            add component
            {
                adding component triggers the component listner 8if there is no more room in parent)
                {
                    move all of the components one place down, move the ones out of bounds to next "page"
                    repaint and revalidate whole JFrame (inside listener)
                }
            }
            repaint and revalidate whole JFrame (part of addComponent method)
        }
        repaint and revalidate whole JFrame(part of opening methid, after component addition)       
    }
    repaint and revalidate whole JFrame (as a part of opening method, final repaint/validate)
}

这样做的原因可能是重绘/验证是 addComponent 方法以及侦听器具有其他功能,并且在其他地方被调用,而这是重绘/验证的唯一(最佳)位置。

问题是 JFrame 在 opeoning 方法中的最后一次(最终)验证/重绘调用之前不会被重绘。我尝试将 Thread.sleep(1000) 添加到代码中的几个位置(在验证/重绘之后)来证明这一点。

另外,据我所知,当触发组件侦听器时,它会停在触发它的行,然后执行自身,然后从该行继续,对吗?

我该如何解决?在添加每个新组件之后,如何强制我的程序重新绘制/验证,然后在监听器完成它的工作之后再次?

回复前两条评论:首先,Thread.sleep(1000) 只是为了诊断问题。就在 Thread.sleep(1000) 方法是 repaint/validate 方法之前,所以我想如果我在调用 reapint() 之后立即暂停程序,每次暂停后,GUI 都会重新绘制广告,我会看到添加了新元素,这不是案子。

其次,对于冗长的计算,这些计算并没有那么长(使用 20 个组件执行此操作会得到暂时的结果,尽管不是所需的结果)。此外,该计算需要经常(每 10-20 行)向 GUI 中删除和添加组件,因此将 SwingWorker 纳入其中几乎是不可能的,也不需要。

第三,我认为你没有抓住重点。执行时间不是这里真正的问题,也不是 GUI 的冻结(这并没有真正发生,无论如何都不足以引起注意)。问题是每个组件在循环中调用了 repaint/validate 总共 3-4 次(如果我打开一个包含 20 个组件的文件,cca. 60-80 次),我唯一看到它被执行的时间是最后一次调用它,在循环之后......

我什至在重绘/验证之前和之后放置了 System.out.println("something") 方法。它两次打印出“某事”,但从未发生过重新绘制/验证。

4

1 回答 1

2
  • 我可以看到容器中 /e / JComponents 的任何add问题removmodify--JFrame > JPanelei)

  • 取决于容器(JPanelei)是否放置在JScrollPane

  • 取决于您是否需要在容器中调用pack()/ adde remov/ modify JComponents,然后JFram在屏幕上更改 e 的大小(例如)

于 2012-09-29T14:00:13.177 回答