Swing JPanel不会重绘

时间:2010-01-28 14:56:19

标签: 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();
    }

任何想法?

由于

修改

解决:

事实证明HoleCardsPanel未正确添加到其父框架。修复后,新JLabel的添加工作正常。我也是:

  • 使用update()
  • 将对SwingUtillities.invokeLater方法的调用添加到事件派发线程
  • 必须从最上面的组件(在本例中为validate())拨打JFrame作为Devon_C_Miller suggests in his answer

6 个答案:

答案 0 :(得分:22)

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

  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. 如果您的更改改变了容器的大小或位置,则已重新调整大小的容器将重新绘制,但它们不会删除用于占用的空间。在容器的父级上调用repaint()将使其重新绘制背景,从而纠正损坏。

答案 1 :(得分:13)

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

按照:

  

API文档

     

注意:如果已添加组件   一个已经显示的容器,   必须调用validate   容器显示新的   零件。如果是多个组件   被添加,你可以改善   通过仅调用验证来提高效率   一旦完成所有组件之后   已被添加。

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

请参阅this问题.....

答案 2 :(得分:5)

validate()的调用应该有效,但revalidate()可能就足够了;不应要求repaint()。您可以将自己正在做的事情与动态GridBagLayout的{​​{3}}进行比较。

答案 3 :(得分:2)

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

事实证明,HoleCardsPanel没有正确地添加到其父框架,一旦修复了,添加新的JLabels就可以了。我使用update()event dispatch thread添加了对SwingUtillities.invokeLater方法的调用我还需要从最上面的组件调用validate()(在本例中为JFrame)< / p>