【问题标题】:Why does my new component not display in a null layout manager?为什么我的新组件不显示在空布局管理器中?
【发布时间】:2011-04-11 17:43:32
【问题描述】:

JFrame 中有一个名为WatchPanel extends JPanel 的面板,它使用GroupLayout 并包含WatchListPanel extends JPanelWatchListPanel 使用 null LayoutManager 并包含多个 WatchItemPanel extends JPanel 实例。 WatchItemPanelGridBagLayout 来布置其内容。

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

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

现在,我已经覆盖了WatchListPanel 上的setBounds 方法,以在列表中的每个WatchItemPanel 实例上调用setSizerepaint,但我正在调用setBoundsrepaint新的WatchItemPanel 已经在我添加时。我尝试在每个可以想象的地方添加repaintinvalidate 电话,我想我可能错过了一些东西,但没有运气。我绝对已将WatchItemPanel 添加到WatchListPanel 并在新面板上调用setBoundssetVisible(true)repaint

这是WatchListPanel 上的addWatchupdatePositions 方法:

公共无效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() 输出。

【问题讨论】:

    标签: java swing null-layout-manager


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2011-07-12
      • 2020-12-31
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多