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 在他的回答中所建议的那样 。

这取决于您想要发生的事情以及正在使用的布局管理器,但基本规则是:

  1. 确保在EDT上调用update 。 如果不是( SwingUtilities.isEventDispatchThread()返回false),则需要使用SwingUtilities.invokeLater在EDT上安排更新。 例如:

     SwingUtilities.invokeLater(new Runnable() { public void run() { update(); }}); 
  2. 调用invalidate() 。 大多数改变组件的东西都会为你做这件事。 因此,如果以下内容不起作用,您只需要调用它。

  3. 在受影响最大的组件上调用validate() 。 这可能是Java渲染周期中最混乱的部分。 对invalidate的调用将组件及其所有祖先标记为需要布局。 对validate的调用执行组件及其所有后代的布局。 一个工作“向上”,另一个工作“向下”。 您需要在树中受最大变化影响的最高组件上调用validate

    此外,在顶级组件(JWindow,JDialog,JFrame)上调用validate不一定会调整该组件的大小。 要实现这一点,您需要调用pack()setSize()

  4. 如果您的更改改变了容器的大小或位置,则已resize的容器将重新绘制,但它们不会擦除以前占用的空间。 在容器的父级上调用repaint()将使其重新绘制背景,从而纠正损坏。

尝试调用revalidate(); 重画不是你想要的。

按照:

API文档

注意:如果已将组件添加到已显示的容器中,则必须在该容器上调用validate以显示新组件。 如果要添加多个组件,则可以在添加所有组件后仅调用一次validation来提高效率。

revalidate()基本上是一个invalidate(),后跟一个validate()。

看到这个问题…..

validate()的调用应该有效,尽管revalidate()可能就足够了; 不应该要求repaint() 。 您可以将您正在做的事情与此动态GridBagLayout 示例进行比较。

您可以尝试调用updateUI()方法。

你在标签上试过SetVisible()吗?

您是否尝试在初始化时添加对象而不进行任何更新? 如果他们没有出现在那里,他们将永远不会出现。

事实certificate, HoleCardsPanel没有正确地添加到其父框架,一旦修复了新的JLabels的添加工作正常。 我使用SwingUtillities.invokeLater添加了对event dispatch threadupdate()方法的调用我另外必须从最上面的组件调用validate() (在本例中是JFrame