Swing JPanel不会重新粉饰
我有一个扩展JPanel
的简单对象,当在此对象上调用update()
方法时,它意味着向面板添加一些标签然后重新绘制。 但是,调用update方法后标签不显示,下面是更新代码:
public void update(){ GridBagConstraints constraints = new GridBagConstraints(); if(cardsHidden){ for(int i = 0; i < 2; i++){ constraints.gridx = i; constraints.gridy = 0; JLabel card = new JLabel(PlayingCards.cardImages[PlayingCards.CARD_BACK_INDEX]); add(card, constraints); } } else{ Card[] holeCards = player.getHoleCards(); for(int i = 0; i < holeCards.length; i++){ constraints.gridx = i; constraints.gridy = 0; JLabel card = new JLabel(holeCards[i].getImageIcon()); add(card, constraints); } } validate(); repaint(); }
有任何想法吗?
谢谢
编辑
解决了:
事实certificate, HoleCardsPanel
没有正确添加到其父框架。 一旦修复了,添加新的JLabel
可以了。 我也:
- 使用
SwingUtillities.invokeLater
将对update()
方法的调用添加到事件派发线程 - 必须从最上面的组件(在本例中是
JFrame
)调用validate()
,如Devon_C_Miller 在他的回答中所建议的那样 。
这取决于您想要发生的事情以及正在使用的布局管理器,但基本规则是:
-
确保在EDT上调用
update
。 如果不是(SwingUtilities.isEventDispatchThread()
返回false),则需要使用SwingUtilities.invokeLater
在EDT上安排更新。 例如:SwingUtilities.invokeLater(new Runnable() { public void run() { update(); }});
-
调用
invalidate()
。 大多数改变组件的东西都会为你做这件事。 因此,如果以下内容不起作用,您只需要调用它。 -
在受影响最大的组件上调用
validate()
。 这可能是Java渲染周期中最混乱的部分。 对invalidate
的调用将组件及其所有祖先标记为需要布局。 对validate
的调用执行组件及其所有后代的布局。 一个工作“向上”,另一个工作“向下”。 您需要在树中受最大变化影响的最高组件上调用validate
。此外,在顶级组件(JWindow,JDialog,JFrame)上调用validate不一定会调整该组件的大小。 要实现这一点,您需要调用
pack()
或setSize()
。 -
如果您的更改改变了容器的大小或位置,则已resize的容器将重新绘制,但它们不会擦除以前占用的空间。 在容器的父级上调用
repaint()
将使其重新绘制背景,从而纠正损坏。
尝试调用revalidate(); 重画不是你想要的。
按照:
API文档
注意:如果已将组件添加到已显示的容器中,则必须在该容器上调用validate以显示新组件。 如果要添加多个组件,则可以在添加所有组件后仅调用一次validation来提高效率。
revalidate()基本上是一个invalidate(),后跟一个validate()。
看到这个问题…..
对validate()
的调用应该有效,尽管revalidate()
可能就足够了; 不应该要求repaint()
。 您可以将您正在做的事情与此动态GridBagLayout
示例进行比较。
您可以尝试调用updateUI()
方法。
你在标签上试过SetVisible()吗?
您是否尝试在初始化时添加对象而不进行任何更新? 如果他们没有出现在那里,他们将永远不会出现。
事实certificate, HoleCardsPanel
没有正确地添加到其父框架,一旦修复了新的JLabels
的添加工作正常。 我使用SwingUtillities.invokeLater
添加了对event dispatch thread
的update()
方法的调用我另外必须从最上面的组件调用validate()
(在本例中是JFrame
)