Swing JPanel不会重绘

Aly*_*Aly 8 java user-interface swing repaint

我有一个简单的对象扩展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();
    }
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

谢谢

编辑

解决了:

事实证明,HoleCardsPanel没有正确添加到其父框架.一旦修复了,添加新JLabel的工作正常.我也:

  • 将调用update()方法添加到事件调度线程中SwingUtillities.invokeLater
  • 不得不validate()从最上面的组件(在这种情况下JFrame)调用Devon_C_Miller 在他的回答中建议.

Dev*_*ler 22

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

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

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

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

    此外,在顶级组件(JWindow,JDialog,JFrame)上调用validate不一定会调整该组件的大小.要做到这一点,你需要打电话pack()setSize().

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


Chr*_*non 14

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

按照:

API文档

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

revalidate()基本上是invalidate(),后跟validate().

看到这个问题.....


tra*_*god 5

呼吁validate()应该工作,虽然revalidate()可能就足够了; repaint()不应该被要求.您可以将您正在做的事情与此动态示例进行比较GridBagLayout.


Phi*_*ere 0

您是否在标签上尝试过 SetVisible() ?

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