隐藏挥杆组件而不重新验证布局?

时间:2014-09-17 16:02:49

标签: java swing layout hide invisible

如果我用一些组件和布局管理器设置一个JFrame,它最初看起来非常好,然后由于某些条件(比如,点击一个按钮),我隐藏了其中一个组件 - 布局管理器将所有组件洗牌组件再次出现。

参见示例代码 - 最初出现3个按钮。单击“隐藏”按钮时,“隐藏”按钮将被隐藏 - 但两个外部按钮则会挤压在一起。单击“显示”按钮时,它们会再次分开以腾出空间。如何阻止这种情况发生,以便在我调用pack()之后,组件会保留在它们的位置,无论它们以后是否被隐藏?

在我的实际代码中,我使用GridBagLayout执行此操作,但在下面的示例中使用了FlowLayout,因为它更简单,代码更少,并且显示完全相同的行为。

我只能想到这样做的讨厌方法,比如使用.setEnabled(false)而不是.setVisible(false),然后覆盖组件的paintComponent()方法,以便在组件不被绘制时禁用。

这似乎是完全相反的问题 - Hide a button from Layout in Java Swing - 在哪里抱怨隐藏按钮仍然占用空间:)但是那里没有示例代码可供展示它以这种方式工作。

非常感谢任何建议:)

示例:

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class RevalidateWhenSetChildInvisibleExample
{
    private JButton button1;
    private JButton button2;
    private JButton button3;

    public void run ()
    {
        // Set up action
        Action hideButtonAction = new AbstractAction ()
        {
            @Override
            public void actionPerformed (ActionEvent e)
            {
                button2.setVisible (false);
            }
        };
        hideButtonAction.putValue (Action.NAME, "Hide");

        Action showButtonAction = new AbstractAction ()
        {
            @Override
            public void actionPerformed (ActionEvent e)
            {
                button2.setVisible (true);
            }
        };
        showButtonAction.putValue (Action.NAME, "Show");

        // Set up buttons
        button1 = new JButton ("Dummy");
        button2 = new JButton (hideButtonAction);
        button3 = new JButton (showButtonAction);

        // Set up content pane
        JPanel contentPane = new JPanel ();
        contentPane.setLayout (new FlowLayout ());
        contentPane.add (button1);
        contentPane.add (button2);
        contentPane.add (button3);

        // Set up frame
        JFrame frame = new JFrame ();
        frame.setContentPane (contentPane);
        frame.pack ();
        frame.setVisible (true);
    }

    public static void main (String args [])
    {
        SwingUtilities.invokeLater (new Runnable ()
        {
            public void run ()
            {
                new RevalidateWhenSetChildInvisibleExample ().run ();
            }
        });
    }
}

2 个答案:

答案 0 :(得分:4)

您可以使用CardLayout,然后将该按钮与空的JPanel交换。

阅读How to Use CardLayout上Swing教程中的部分,了解更多信息和示例。

答案 1 :(得分:1)

问题是布局管理器,这不是一个真正的问题,因为它只是在做它的工作。您可以将布局设置为null,然后为每个按钮设置边界;这样他们就永远不会移动,除非你改变他们的位置。

panel.setLayout(null);
button1.setBounds(10,10,50,20);
button2.setBounds(70,10,50,20);
button3.setBounds(xPos,yPos,width,height);

另一种方法是使用GridLayout

contentPane.setLayout(new GridLayout());

我测试了它,它工作正常,因为组件没有被删除它保持不变。

此外,您应该在代码中添加以下内容:

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

这使得程序在JFrame关闭时退出;没有它,程序仍然在后台运行。