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

时间:2015-05-20 22:01:02

标签: java swing jframe layout-manager border-layout

以下是向框架添加两个面板的示例。只显示一个面板(第二个红色面板)。

Disappearing Panel In Frame

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

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));
    }
}

2 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:3)

  

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

不完全正确。

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

在示例代码中,红色面板是&#34;活动&#34;通过使用pack()方法验证框架时的面板,因此只设置了它的边界,因此只绘制了它。

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

  1. 点击&#34;在中心添加面板&#34;按钮,即使蓝色面板被添加到中心,也似乎没有任何事情发生。
  2. 将鼠标移到红色面板上会出现按钮,因为鼠标翻转逻辑会导致按钮被重新绘制。
  3. 现在增加框架宽度,蓝色面板将显示在红色面板下。
  4. 代码:

    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),因为它从来不是&#34;活跃的&#34;最初使用pack()方法验证框架时BorderLayout.CENTER中的面板。

    当框架调整大小时,蓝色面板是&#34;活动&#34; BorderLayout.CENTER中的面板调整了边界,因此它现在将填充框架中的额外空间。

    现在进行另一项测试:

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

      底线仍然相同:

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