简体   繁体   中英

Hide a button from Layout in Java Swing

I am trying something very basic: I have a list of 5 buttons. They are in a FlowLayout and the general idea should be that once I click one it should disappear and the others should reorder themselves accordingly.

Now, if I call setVisible(false) the button becomes invisible, but it still occupies it's space in the Layoutmanager.

Is there any way to keep the Button in the JPanel while hiding it so it doesn't get picked up by Layout?

Update: : Thanks for all the answers, the problem with removing the buttons is that the order is important. The problem I was trying to solve was a find as you type szenario where a very long list of buttons gets filtered down to only the ones matching the characters entered so users can easily click them. Since users can delete characters from the search field ordering is important and buttons have to pop back in once they match again.

Works fine for me.

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

public class FlowLayoutInvisible extends JFrame
    implements ActionListener
{
    JPanel north;
    int i;

    public FlowLayoutInvisible()
    {

        north = new JPanel();

        for (int i = 0; i < 5; i++)
        {
            JButton button = new JButton("North - " + i);
            button.addActionListener(this);
            north.add(button);
        }

        getContentPane().add(north, BorderLayout.NORTH);
        }

    public void actionPerformed(ActionEvent e)
    {
        Component c = (Component)e.getSource();
        c.setVisible(false);
    ((JPanel)c.getParent()).revalidate();
    }

    public static void main(String[] args)
    {
        FlowLayoutInvisible frame = new FlowLayoutInvisible();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }
}

If you need more help post your SSCCE .

Update: I don't know if the revalidate() is required. I seemed to have a problem once but now I can't duplicate the problem.

Just remove it:

 panel.remove( button );

What's wrong with this option?

Layout managers are thought precisely to avoid having the "user" to make tricks in order to have each component it the right place ( although it seems to provoke the opposite effect )

Removing the button from the panel will have the effect of laying out again all the remaining components. That's why it's name is "Layout manager" it manages to layout the components for you.

I see two possibilities:

  • Write your own layout manager that listens for changes to its children's visible property - shouldn't be too hard, you can probably subclass FlowLayout to do it.
  • actually remove the clicked-button from the panel and, if necessary, re-add it later.

您可以重写每个按钮的getPreferredSize()方法(也可以重写getMinimumSize() ,以在组件不可见时返回0,0;并且我需要调用invalidate() (或revalidatevalidate ,我永远无法保持将它们放在容器上)。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM