JFrame
中有一个名为WatchPanel extends JPanel
的小组使用GroupLayout
并包含WatchListPanel extends JPanel
。 WatchListPanel
使用null
LayoutManager
并包含WatchItemPanel extends JPanel
的多个实例。 WatchItemPanel
使用GridBagLayout
列出其内容。
当我加载框架并实例化WatchPanel
时,我使用数据预加载WatchListPanel
三个WatchItemPanel
个实例。这些工作正常。我的实现允许通过拖放(因此null
布局)重新排序这些,并且也可以。 WatchPanel
上有一个添加新手表的按钮,可在其自己的JFrame
中弹出一个可添加手表的新面板。在此新面板上按下“保存”按钮后,它会将新手表添加到WatchPanel
,然后向WatchListPanel
逐渐进入,并关闭JFrame
以添加新手表。
问题在于,添加此新WatchItemPanel
时,除非我调整包含JFrame
的{{1}}的大小,否则不会对其进行绘制。我可以通过拖放来与它进行交互。我甚至可以拖动那个特定的面板 - 但它是空白的。当我调整WatchPanel
的大小时,它会显示并正确绘制。
现在,我已覆盖WatchPanel
上的setBounds
方法,在列表中的每个WatchListPanel
个实例上调用setSize
和repaint
,但我我在添加它时已在新WatchItemPanel
上调用setBounds
和repaint
。我尝试在每个可以想象的地方添加WatchItemPanel
和repaint
来电,以为我可能错过了一些东西,但没有运气。我绝对已将invalidate
添加到WatchItemPanel
,并在新面板上调用WatchListPanel
,setBounds
和setVisible(true)
。
以下是repaint
上的addWatch
和updatePositions
方法:
public void addWatch(Watch watch) { WatchItemPanel watchPanel = new WatchItemPanel(watch); synchronized (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(); } private void updatePositions() { int count = 0; synchronized (this.watches) { for (Watch watch: this.watches) { if ((this.selectedWatchPanel != null) && (count == this.selectedWatchPanelPosition)) count++; WatchItemPanel panel = this.watchPanels.get(watch); if (panel == this.selectedWatchPanel) continue; panel.setBounds(0, count * WatchItemPanel.PANEL_HEIGHT, this.getWidth(), WatchItemPanel.PANEL_HEIGHT); count++; } } if (this.selectedWatchPanel != null) this.selectedWatchPanel.setBounds(0, (this.selectedWatchPanelPosition * WatchItemPanel.PANEL_HEIGHT) + this.selectedWatchPanelDragOffset, this.getWidth(), WatchItemPanel.PANEL_HEIGHT); this.repaint(); }
以下是WatchListPanel
上的setBounds
方法:
@Override public void setBounds(Rectangle r) { super.setBounds(r); for (WatchItemPanel panel: this.watchPanels.values()) { panel.setSize(r.width, WatchItemPanel.PANEL_HEIGHT); panel.repaint(); } } @Override public void setBounds(int x, int y, int width, int height) { super.setBounds(x, y, width, height); for (WatchItemPanel panel: this.watchPanels.values()) { panel.setSize(width, WatchItemPanel.PANEL_HEIGHT); panel.repaint(); } }
这里的另一条信息 - 正在绘制所有四个面板。我在WatchListPanel
中覆盖paintComponent
并添加了WatchItemPanel
并获得了此结果:
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=]
面板中那个额外的“无效”栏是什么?当我调整System.out.println
的大小时,“无效”就会消失。不过,它看起来像一个额外的列。其他行上没有相应的非无效值。 (这是删除包名称的默认WatchPanel
输出。
答案 0 :(得分:0)
添加组件后,请致电this.revalidate()
。这会导致容器被标记为重新布局其组件。一旦添加了这行代码,它就能完美运行。