JFrame 中有一个名为WatchPanel extends JPanel 的面板,它使用GroupLayout 并包含WatchListPanel extends JPanel。 WatchListPanel 使用 null LayoutManager 并包含多个 WatchItemPanel extends JPanel 实例。 WatchItemPanel 用GridBagLayout 来布置其内容。
当我加载框架并实例化 WatchPanel 时,我用三个带有数据的 WatchItemPanel 实例预加载了 WatchListPanel。这些工作正常。我的实现允许通过拖放对它们进行重新排序(因此是null 布局),并且效果也很好。在WatchPanel 上有一个添加新手表的按钮,它会在自己的JFrame 中弹出一个新面板,可以在其中添加手表。当在这个新面板上按下“保存”按钮时,它会将新手表添加到 WatchPanel,它会向下渗透到 WatchListPanel 并关闭 JFrame 以添加新手表。
问题是,当添加这个新的WatchItemPanel 时,除非我调整包含WatchPanel 的JFrame 的大小,否则它不会被绘制。我可以通过拖放与它进行交互。我什至可以拖动那个特定的面板——但它是空白的。当我调整WatchPanel 的大小时,它就会出现并且绘制正确。
现在,我已经覆盖了WatchListPanel 上的setBounds 方法,以在列表中的每个WatchItemPanel 实例上调用setSize 和repaint,但我正在调用setBounds 和repaint新的WatchItemPanel 已经在我添加时。我尝试在每个可以想象的地方添加repaint 和invalidate 电话,我想我可能错过了一些东西,但没有运气。我绝对已将WatchItemPanel 添加到WatchListPanel 并在新面板上调用setBounds、setVisible(true) 和repaint。
这是WatchListPanel 上的addWatch 和updatePositions 方法:
公共无效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();
}
这里是WatchListPanel 上的setBounds 方法:
@覆盖
公共无效 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();
}
}
这里还有一条信息 - 所有四个面板都在涂漆。我在WatchItemPanel 中覆盖了paintComponent 并添加了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() 输出。