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

萝らか妹 提交于 2019-12-04 06:55:08

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

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

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!