强制立即布局并在Swing中绘制

强制立即布局并在Swing中绘制,swing,layout,paint,Swing,Layout,Paint,我似乎不能强迫一个布局处于摇摆状态。我在JLayeredPane中添加了JComponent,并在JComponent上设置了边框。然后,我想立即重新绘制所有内容-不是像invalidate()那样的“请尽快完成”,而是同步地、立即地绘制。有什么帮助吗?我似乎找不到正确的方法来做这件事,而我读到的所有关于invalidate()、validate()、repaint()、doLayout()等的文章都让我更加困惑 让Swing更新显示的最可靠方法是使用SwingUtilities.invokeL

我似乎不能强迫一个布局处于摇摆状态。我在
JLayeredPane
中添加了
JComponent
,并在
JComponent
上设置了边框。然后,我想立即重新绘制所有内容-不是像
invalidate()
那样的“请尽快完成”,而是同步地、立即地绘制。有什么帮助吗?我似乎找不到正确的方法来做这件事,而我读到的所有关于
invalidate()、validate()、repaint()、doLayout()等的文章都让我更加困惑

让Swing更新显示的最可靠方法是使用
SwingUtilities.invokeLater
。在你的情况下,它看起来像

SwingUtilities.invokeLater(new Runnable {
                             public void run() { 
                                somecomponent.repaint();
                             }
                           });
我意识到“invokelater”听起来并不像是立即执行任何操作,但实际上,以这种方式发布的事件往往比直接调用somecomponent.repaint()执行得非常快。如果您必须让您的控制代码等待GUI更新,那么还有
invokeAndWait
,但根据我的经验,这几乎没有必要


另请参见:在Swing中。

根据(请参见标题为“同步绘制”的部分),paintInstance()方法应该可以工作。

这是一个非常古老的方法,但我找到了一个简单的解决方案,我将用一个JPasswordField显示:

var pw = new JPasswordField();
...
pw.paint(pw.getGraphics()); // paints immediately

我已经尝试过这个-myComponent.paintInstance(myComponent.getBounds)。运气不好:(我认为这可能是因为更改边框需要一个新的布局过程,因为边框在ObjectPaintInstant的每一侧使用一些额外的像素,这可能是一种方法,但我认为您仍然需要使用invokeLater或invokeAndWait将其作为事件发布。@Hamy您是否尝试过在父组件上调用它,这可能会允许t布局更改。不幸的是,这两种方法都不适用于我的impl:/I我需要立即进行GUI更新,而不是在处理挂起的事件之后。这是由于我的设计中的一个缺陷,我需要这样做,但不幸的是,更改它会使我倒退近两周,明天我就有了可交付成果:/Ok试试这个:使用invokeAndWait,然后在外部容器上的runnable调用内立即绘制。我认为这是使用Swing可以得到的最接近的结果——如果我没有弄错的话,它将覆盖以前对“重新绘制”的调用。不幸的是,这也不起作用。要调用invokeAndWait,必须生成一个新线程。在正在绘制,它在启动runnable之前开始执行,导致GUI冻结,而没有执行此绘制调用Yet invokeAndWait调用不会生成新线程——它只是将runnable添加到事件队列,然后阻止当前线程,直到调用事件。如果您仍然没有看到使用invokeAndWait时,很可能是重新绘制了错误的对象。检查的一种方法是将调试输出添加到组件的(g)绘制方法中。