为什么我的新组件不在空布局管理器中显示?
-
02-10-2019 - |
题
一个面板 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
包含 WatchPanel
. 。我可以通过Drag-n-Drop与它进行互动。我什至可以拖动特定的面板 - 但它是空白的。我调整大小的那一刻 WatchPanel
, ,它出现并正确绘制。
现在,我已经覆盖了 setBounds
方法开 WatchListPanel
打电话 setSize
和 repaint
在每个 WatchItemPanel
列表中的实例,但我在打电话 setBounds
和 repaint
在新 WatchItemPanel
我已经添加了。我尝试添加 repaint
和 invalidate
在每个可能的地方打电话,也许我错过了一些东西,但没有运气。我绝对添加了 WatchItemPanel
到 WatchListPanel
并打电话 setBounds
, setVisible(true)
, , 和 repaint
在新面板上。
这里有 addWatch
和 updatePositions
在 WatchListPanel
:
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(); }
这是 setBounds
方法开启 WatchListPanel
:
@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(); } }
这里的另一个信息 - 所有四个面板都在绘制。我覆盖了 paintComponent
在里面 WatchItemPanel
并添加 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()
输出包装名称已删除。
解决方案
添加组件后,请致电 this.revalidate()
. 。这会导致标记容器以重新分配其组件。一旦添加了这条代码,它就可以完美地工作。