Why does the first panel added to the frame disappear?

Below is an example of adding two panels to a frame. Only one panel is displayed (the second, red panel).

Disappearing Panel In Frame

Why does the first panel disappear?

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

      

+3


source to share


2 answers


  • The default layout JFrame

    (or more specifically, in this case, the content area ) is BorderLayout

    .
  • When adding a component to BordeLayout

    no limit, the Swing API will place the component to CENTER

    .
  • A BorderLayout

    can contain exactly one component in each of the 5 layout constraints.
  • When a second component is added to the same (in this case CENTER

    ) constraint BorderLayout

    , this Java implementation will render the last added component added.


As far as the best approach goes, depends on the specific needs of the user interface.

+5


source


When the second component is added to the same (in this case CENTER) BorderLayout constraint, this Java implementation will show the last added component.

Not entirely true.

BorderLayout

will only reset the bounds

(i.e. size and location) the last component added to the specific location of the constraint. This differs from other layout managers in that they will reset the bounds of all components in the container.

In the example code, the red pane was the "active" pane when the frame was checked using the pack () method, and therefore only its border was set, and therefore only it was drawn.

To demonstrate this process, follow the example below by following these steps:

  • Click the "Add Center Bar" button, nothing happens even if a blue bar was added to the center.
  • Move your mouse over the red bar and the buttons will appear, because the mouse rollover logic will cause the buttons to repaint.
  • Now increase the width of the frame and a blue panel will appear below the red panel.

Code:

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

      



When the blue bar is added to the BorderLayout and when called revalidate()

, the borders of the blue bar are set.

However, due to the way Swing draws the ZOrder, the blue bar is drawn first, and then the red bar is painted over the blue bar. The green bar still has a size of (0, 0) because it was never the "active" bar BorderLayout.CENTER

when the frame was initially checked with the pack () method.

When the frame is resized, the blue bar, which is the "active" bar in BorderLayout.CENTER

, has its borders, so it fills the extra space in the frame.

Now for another test:

  • pack()

    frame after adding a green bar to the frame.
  • run the code and increase the border width and a red and green border appears.
  • then click the button and increase the width and all 3 panels will now appear.

The bottom line remains the same:

Don't try to add multiple panels to the same BorderLayout constraint. If you do, make sure to delete the previous panel or you have the potential for unexpected results.

+3


source







All Articles