SetVisible(false) changes the layout of my components within my Panel
Asked Answered
T

3

7

How do I make the subpanels within my main panel stay where they are when I set one of the subpanels to be invisible?

What I have looks like:

[ (Panel1) (Panel2) (Panel3) (Panel4) ]

When I do panel3.setVisible(false) it then looks like:

[      (Panel1) (Panel2) (Panel4)     ]

I would like it to look like:

[ (Panel1) (Panel2)          (Panel4) ]

I am using the GridBagLayout and my mainPanel declaration looks like:

final JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();

and I add an new panel like:

final JTextField valueTextField = new JTextField();
valueTextField.setPreferredSize(new Dimension(80, 25));
valueTextField.setName("Value");
c.gridx =0;
panel.add(valueTextField, c);

I'll provide more code if needed and I don't care which layout I use as long as it gets me what I want.

Triplane answered 26/5, 2011 at 15:45 Comment(0)
R
7

I suggest using a CardLayout within the individual cells, and instead of setting it to invisible, switch to an empty panel instead.

The code below demonstrates this. Within hidePanel() there are two options to hide the cell with the CardLayout route currently enabled.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class InvisiblePanels {
    public static void main(String... args) throws Exception {
        JFrame frame = new JFrame();
        frame.setLayout(new GridBagLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        frame.add(new MyPanel(), c);
        c.gridx = 1;
        frame.add(new MyPanel(), c);
        c.gridx = 2;
        frame.add(new MyPanel(), c);

        frame.pack();
        frame.setVisible(true);

    }

    private static class MyPanel extends JPanel {

        CardLayout layout;

        public MyPanel() {
            layout = new CardLayout();
            setLayout(layout);
            JButton button = new JButton("Click me");
            button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    hidePanel();
                }
            });
            add(button, "visible");
            add(new JPanel(), "invisible");
            layout.show(this, "visible");
        }

        public void hidePanel() {
//            setVisible(false);
            layout.show(this, "invisible");
        }
    }
}
Rattly answered 26/5, 2011 at 16:16 Comment(0)
S
4

I believe all the layout manager respect the visibility of a component and don't include invisible components in the preferred size and layout calculations.

One solution might be to wrap all your panels in a panel using the OverlayLayout:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class OverlayLayoutInvisible
{
    public static void main(String[] args)
    {
        JPanel panel = new JPanel();
        panel.add( createPanel("Button 1") );
        panel.add( createPanel("Button 2") );
        panel.add( createPanel("Button 3") );
        panel.add( createPanel("Button 4") );
        panel.add( createPanel("Button 5") );

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.add( panel );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }

    public static JPanel createPanel(String text)
    {
        JButton button = new JButton( text );
        button.addActionListener( new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                Component c = (Component)e.getSource();
                c.setVisible(false);
            }
        });

        InvisibleComponent ic = new InvisibleComponent( button );

        JPanel panel = new JPanel();
        panel.setLayout( new OverlayLayout(panel) );
        panel.add( ic );
        panel.add( button );


        return panel;
    }

    public static class InvisibleComponent extends JComponent
    {
        private Component master;

        public InvisibleComponent(Component master)
        {
            this.master = master;
            setAlignmentX( master.getAlignmentX() );
            setAlignmentY( master.getAlignmentY() );
        }

        public Dimension getPreferredSize()
        {
            return master.getPreferredSize();
        }
    }
}
Slipslop answered 26/5, 2011 at 16:25 Comment(4)
Note that the comment about "all layout respect visibility" is only partially true. Some Layouts have options regarding behavior in this case (MigLayout has, and I think GroupLayout has also). DesignGridLayout doesn't care about components visibility: added components are laid out the same way, visible or not.Forgo
+1 Color me dumb-struck. I thought you were referring to a custom layout until I checked the JavaDocs! The docs. are a bit thin with @since tags, when was it introduced?Villatoro
@Andrew Thompson, its been there as long as I can remember, but I've never found it that useful. I seem to remember having problems understanding how it positions components in the panel when they are different sizes. Also, you have to be careful how you layer components. For example if you put a label on top of a button. The button will paint overtop of the label on a mouse over since the button gets mouseover event and paints the rollover effect for the button.Slipslop
Thanks. I had since noted the Java Tutorial does not seem to cover it. Perhaps the Swing developers are a little embarrassed about OverlayLayout (which keeps reminding me of Beck - rhyming with Odelay). ;)Villatoro
S
2

You might be able to tweak GridLayout (do you have an SSCCE?)

Otherwise:

Put Panel3 and Panel4 together in a single panel that you add to the GridBagLayout. Then setup the new Panel in a Layout like FlowLayout (aligned Left with a preferred size), BorderLayout, GridLayout, etc.

Satellite answered 26/5, 2011 at 15:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.