在不重新验证布局的情况下隐藏摆动组件?

nig*_*elg 1 java layout swing invisible hide

如果我设置了一个带有一些组件和布局管理器的 JFrame,它最初看起来非常好,然后由于某些条件(例如,单击一个按钮)我隐藏了其中一个组件 - 布局管理器再次将所有组件打乱.

查看示例代码 - 最初出现 3 个按钮。当您单击“隐藏”按钮时,“隐藏”按钮将被隐藏 - 但两个外部按钮随后会挤压在一起。当您单击显示按钮时,它们会再次分开以腾出空间。我怎样才能阻止这种情况发生,以便在我调用 pack() 之后,无论组件以后是否隐藏,它们都将保持原样?

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

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

这似乎完全相反的问题在这里-隐藏布局的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 ();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

cam*_*ckr 5

您可以使用 aCardLayout然后用空的 JPanel 交换按钮。

阅读 Swing 教程中关于如何使用 CardLayout 的部分以获取更多信息和示例。