在JavaSwing中隐藏布局中的按钮

在JavaSwing中隐藏布局中的按钮,java,swing,Java,Swing,我正在尝试一些非常基本的东西: 我有5个按钮的列表。它们在一个FlowLayout中,一般的想法应该是,一旦我点击其中一个,它就会消失,其他人应该相应地重新排序 现在,如果调用setVisible(false),按钮将不可见,但它仍会占用Layoutmanager中的空间 有没有办法在隐藏按钮的同时将其保留在JPanel中,这样它就不会被布局拾取 更新::感谢您提供的所有答案,删除按钮的问题在于顺序很重要。我试图解决的问题是,键入szenario时查找,其中一个很长的按钮列表被过滤到只与输入的字

我正在尝试一些非常基本的东西: 我有5个按钮的列表。它们在一个FlowLayout中,一般的想法应该是,一旦我点击其中一个,它就会消失,其他人应该相应地重新排序

现在,如果调用setVisible(false),按钮将不可见,但它仍会占用Layoutmanager中的空间

有没有办法在隐藏按钮的同时将其保留在JPanel中,这样它就不会被布局拾取


更新::感谢您提供的所有答案,删除按钮的问题在于顺序很重要。我试图解决的问题是,键入szenario时查找,其中一个很长的按钮列表被过滤到只与输入的字符匹配的按钮,因此用户可以轻松单击它们。因为用户可以从搜索字段中删除字符,所以排序很重要,按钮必须在再次匹配后重新弹出。

您可以覆盖每个按钮的
getPreferredSize()
方法(可能还有
getMinimumSize())
以及在组件不可见时返回0,0;我认为,您需要在容器上调用
invalidate()
(或者
revalidate
或者
validate
,我永远无法保持它们的正确性)。

我看到了两种可能性:

  • 编写您自己的布局管理器,以侦听其子级的
    可见属性的更改-应该不太难,您可能可以使用子类
    FlowLayout
    来执行此操作
  • 实际上,从面板中删除单击的按钮,如有必要,稍后重新添加
只需将其卸下:

 panel.remove( button );
这个选项有什么问题

布局管理器被认为恰恰是为了避免“用户”为了让每个组件都在正确的位置而耍花招(尽管这似乎会引起相反的效果)

从面板中删除按钮将产生重新布局所有剩余组件的效果。这就是为什么它的名称为“布局管理器”,它可以为您布局组件。

对我来说很好

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);
    }
}
import java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
公共类FlowLayoutVisible扩展JFrame
实现ActionListener
{
杰帕内尔北;
int i;
公共FlowLayoutVisible()
{
北=新JPanel();
对于(int i=0;i<5;i++)
{
JButton按钮=新JButton(“北-”+i);
addActionListener(这个);
添加(按钮);
}
getContentPane().add(north,BorderLayout.north);
}
已执行的公共无效操作(操作事件e)
{
组件c=(组件)e.getSource();
c、 setVisible(假);
((JPanel)c.getParent()).revalidate();
}
公共静态void main(字符串[]args)
{
FlowLayoutInvisible frame=新的FlowLayoutInvisible();
frame.setDefaultCloseOperation(关闭时退出);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
}
如果您需要更多帮助,请发布您的


更新:我不知道是否重新验证()是必需的。我似乎有一次遇到问题,但现在我无法复制该问题。

问题是FlowLayout在组件之间放置的空间将出现两次,因此仍然会有明显的间隙。按钮是否重新排序有关系?因为这将排除所有答案,并删除和重新添加FlowLay出来