为什么添加到框架的第一个面板消失了?

下面是将两个面板添加到框架的示例。 仅出现一个面板(第2个红色面板)。

框架中消失的面板

为什么第一个面板消失了?

import java.awt.*; import javax.swing.*; import javax.swing.border.EmptyBorder; public class DisappearingPanelInFrame { DisappearingPanelInFrame() { JFrame f = new JFrame(this.getClass().getSimpleName()); f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); f.add(new ColoredPanel(Color.GREEN)); f.add(new ColoredPanel(Color.RED)); f.pack(); f.setVisible(true); } public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { new DisappearingPanelInFrame(); } }; SwingUtilities.invokeLater(r); } } class ColoredPanel extends JPanel { ColoredPanel(Color color) { setBackground(color); setBorder(new EmptyBorder(20, 150, 20, 150)); } } 

  • JFrame的默认布局(或者更具体地说,在这种情况下,框架的内容窗格 )是BorderLayout
  • 在没有约束的情况下将组件添加到BordeLayout时,Swing API会将组件放入CENTER
  • BorderLayout可以在5个布局约束中的每一个中仅包含一个组件。
  • 当第二个组件添加到BorderLayout的相同(在本例中为CENTER )约束时,此Java实现将显示添加最后一个组件。

至于什么是更好的方法取决于用户界面的特定需求。

当第二个组件添加到BorderLayout的相同(在本例中为CENTER)约束时,此Java实现将显示添加的最后一个组件。

不完全正确。

BorderLayoutreset the bounds添加到特定约束位置的最后一个组件reset the bounds (即大小和位置)。 这与其他布局管理器的不同之处在于它们将重置容器中所有组件的边界。

在示例代码中,红色面板是使用pack()方法validation框架时的“活动”面板,因此仅设置了它的边界,因此只绘制了它。

有关此过程的演示,请使用以下步骤运行以下示例:

  1. 单击“在中心添加面板”按钮,即使蓝色面板已添加到中心,也不会发生任何事情。
  2. 将鼠标移到红色面板上,将出现按钮,因为鼠标翻转逻辑将导致按钮被重新绘制。
  3. 现在增加框架宽度,蓝色面板将出现在红色面板下方。

代码:

 import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.EmptyBorder; public class DisappearingPanelInFrame { DisappearingPanelInFrame() { JButton button = new JButton ("Add Panel In Center"); button.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JPanel blue = new JPanel(); blue.setBackground( Color.BLUE ); blue.add( new JButton("Button 1") ); blue.add( new JButton("Button 2") ); Component c = (Component)e.getSource(); Window window = SwingUtilities.windowForComponent(c); window.add(blue ); window.revalidate(); window.repaint(); } }); JFrame f = new JFrame(this.getClass().getSimpleName()); f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); f.add(new ColoredPanel(Color.GREEN)); //f.pack(); f.add(new ColoredPanel(Color.RED)); f.add(button, BorderLayout.SOUTH); f.pack(); f.setVisible(true); } public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { new DisappearingPanelInFrame(); } }; SwingUtilities.invokeLater(r); } } class ColoredPanel extends JPanel { ColoredPanel(Color color) { setBackground(color); setBorder(new EmptyBorder(20, 150, 20, 150)); } } 

将蓝色面板添加到BorderLayout并调用revalidate()时,将设置蓝色面板的边界。

但是,由于Swing做ZOrder绘画的方式,首先绘制蓝色面板,然后在蓝色面板的顶部绘制红色面板。 绿色面板的大小仍为(0,0),因为在最初使用pack()方法validation框架时,它从不是BorderLayout.CENTER的“活动”面板。

调整框架大小时,蓝色面板是BorderLayout.CENTER的“活动”面板,其边界已调整,因此它现在将填充框架中的额外空间。

现在进行另一项测试:

  1. 将绿色面板添加到框架后pack()框架。
  2. 运行代码并增加框架的宽度,将出现红色和绿色框架
  3. 然后单击按钮并增加宽度,现在将显示所有3个面板

底线仍然是相同的:

不要尝试将多个面板添加到BorderLayout的相同约束中。 如果这样做,请确保删除上一个面板,否则可能会出现意外结果。