0

JFramea 中有一个名为 a的面板,WatchPanel extends JPanel它使用 aGroupLayout并包含 a WatchListPanel extends JPanel。使用WatchListPanelanull LayoutManager并包含 的几个实例WatchItemPanel extends JPanelWatchItemPanelGridBagLayout. _

当我加载框架并实例化 时WatchPanel,我预加载了WatchListPanel三个WatchItemPanel带有数据的实例。这些工作正常。我的实现允许通过拖放(因此null布局)对这些进行重新排序,并且效果也很好。上面WatchPanel是一个添加新手表的按钮,它会弹出一个自己的新面板,JFrame可以在其中添加手表。当在这个新面板上按下“保存”按钮时,它会将新手表添加到 ,它会WatchPanel向下滴入WatchListPanel并关闭JFrame以添加新手表。

问题是当这个新WatchItemPanel的被添加时,它不会被绘制,除非我调整JFrame包含WatchPanel. 我可以通过拖放与它进行交互。我什至可以拖动那个特定的面板——但它是空白的。我调整大小的那一刻WatchPanel,它出现并正确绘制。

现在,我已经在列表中的每个实例上重写了调用setBounds方法,但是我在添加它时已经调用了新方法。我已经尝试在每个可以想象的地方添加和调用,我想也许我错过了一些东西,但没有运气。我绝对已经在新面板上添加了,和,和。WatchListPanelsetSizerepaintWatchItemPanelsetBoundsrepaintWatchItemPanelrepaintinvalidateWatchItemPanelWatchListPanelsetBoundssetVisible(true)repaint

以下是 上的addWatchupdatePositions方法WatchListPanel

公共无效addWatch(手表手表){
    WatchItemPanel watchPanel = new WatchItemPanel(watch);
    同步(this.watches){
        this.watches.add(watch);
    }
    this.watchPanels.put(watch, watchPanel);
    this.add(watchPanel);
    watchPanel.setOpaque(false);
    watchPanel.setForeground(this.getForeground());
    watchPanel.setBackground(this.getBackground());
    watchPanel.setVisible(true);
    watchPanel.setSize(this.getWidth(), WatchItemPanel.PANEL_HEIGHT);
    for (MouseListener l: this.mouseListeners)
        watchPanel.addMouseListener(l);
    for (MouseMotionListener l: this.mouseMotionListeners)
        watchPanel.addMouseMotionListener(l);
    this.updatePositions();
}

私人无效更新位置(){
    整数计数 = 0;
    同步(this.watches){
        对于(手表手表:this.watches){
            if ((this.selectedWatchPanel != null) && (count == this.selectedWatchPanelPosition))
                计数++;
            WatchItemPanel 面板 = this.watchPanels.get(watch);
            如果(面板 == this.selectedWatchPanel)
                继续;
            panel.setBounds(0, count * WatchItemPanel.PANEL_HEIGHT, this.getWidth(), WatchItemPanel.PANEL_HEIGHT);
            计数++;
        }
    }
    如果(this.selectedWatchPanel!= null)
        this.selectedWatchPanel.setBounds(0, (this.selectedWatchPanelPosition * WatchItemPanel.PANEL_HEIGHT) + this.selectedWatchPanelDragOffset, this.getWidth(), WatchItemPanel.PANEL_HEIGHT);
    this.repaint();
}

以下是有关的setBounds方法WatchListPanel

@覆盖
公共无效 setBounds(矩形 r){
    super.setBounds(r);
    for (WatchItemPanel 面板: this.watchPanels.values()) {
        panel.setSize(r.width, WatchItemPanel.PANEL_HEIGHT);
        panel.repaint();
    }
}

@覆盖
公共无效setBounds(int x,int y,int宽度,int高度){
    super.setBounds(x, y, width, height);
    for (WatchItemPanel 面板: this.watchPanels.values()) {
        panel.setSize(宽度, WatchItemPanel.PANEL_HEIGHT);
        panel.repaint();
    }
}

这里的另一条信息 - 所有四个面板都在涂漆。我覆盖paintComponentWatchItemPanel添加了一个System.out.println并得到了这个结果:

WatchItemPanel[,0,66,366x22,invalid,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]
WatchItemPanel[,0,44,366x22,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]
WatchItemPanel[,0,22,366x22,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]
WatchItemPanel[,0,0,366x22,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]

面板中那个额外的“无效”列是什么?当我调整大小时WatchPanel,“无效”消失了。不过,它看起来像一个额外的列。其他行没有相应的非无效值。JPanel.toString()(这是删除了包名的默认输出。

4

1 回答 1

0

添加组件后,调用this.revalidate(). 这会导致容器被标记为重新布局其组件。一旦添加了这行代码,它就可以完美运行。

于 2010-09-13T15:39:00.473 回答