Java 隐藏swing组件而不重新验证布局?
如果我用一些组件和布局管理器设置了一个JFrame,最初看起来非常好,但后来由于某种情况(比如,单击按钮),我会隐藏其中一个组件——布局管理器会再次洗牌所有组件 请参见示例代码-最初显示3个按钮。单击“隐藏”按钮时,“隐藏”按钮被隐藏,但两个外部按钮会挤压在一起。单击“显示”按钮时,它们会再次分开以腾出空间。我如何才能阻止这种情况的发生,以便在调用pack()之后,组件保持在原来的位置,而不管它们以后是否被隐藏 在我的实际代码中,我使用GridBagLayout来实现这一点,但在下面的示例中使用了FlowLayout,因为它更简单,代码更少,并且显示了完全相同的行为 我只能想到一些令人讨厌的方法,比如使用.setEnabled(false)而不是.setVisible(false),然后重写组件的paintComponent()方法,在禁用组件时不绘制组件 这里的问题似乎正好相反——哪里的人抱怨隐藏的按钮仍然占用空间:)但是那里没有示例代码显示它以这种方式工作 非常感谢您的建议:) 例如:Java 隐藏swing组件而不重新验证布局?,java,swing,layout,hide,invisible,Java,Swing,Layout,Hide,Invisible,如果我用一些组件和布局管理器设置了一个JFrame,最初看起来非常好,但后来由于某种情况(比如,单击按钮),我会隐藏其中一个组件——布局管理器会再次洗牌所有组件 请参见示例代码-最初显示3个按钮。单击“隐藏”按钮时,“隐藏”按钮被隐藏,但两个外部按钮会挤压在一起。单击“显示”按钮时,它们会再次分开以腾出空间。我如何才能阻止这种情况的发生,以便在调用pack()之后,组件保持在原来的位置,而不管它们以后是否被隐藏 在我的实际代码中,我使用GridBagLayout来实现这一点,但在下面的示例中使用
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 ();
}
});
}
}
您可以使用
卡片布局
,然后将按钮与空JPanel交换
有关更多信息和示例,请阅读上Swing教程的部分。您可以使用
卡片布局,然后将按钮与空JPanel交换
有关更多信息和示例,请阅读上Swing教程的部分。问题在于布局管理器,它在这里并不是一个真正的问题,因为它只是在完成它的工作。您可以将布局设置为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
关闭时退出;没有它,程序仍然在后台运行。问题在于布局管理器,它在这里不是真正的问题,因为它只是在完成它的工作。您可以将布局设置为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
关闭时退出;没有它,程序仍然在后台运行。是的,我经常使用CardLayouts,但不适用于此场景。这实际上是一个不错的主意,因为CardLayout会根据按钮(或任何东西)来调整大小,即使按钮不可见,所以它也不会滥用布局管理器。我构建了一个HideableComponent类,它就是这样做的——用CardLayout包装面板中的任何组件,因此可以调用.setHidden(true/false)在它上面,所以不必知道它是通过CardLayout实现的,并且它工作得非常完美:)所以可以这样做,例如新的HideableComponent(新的JButton(action))。如果有兴趣,这里的代码-是的,我用了很多卡片布局,但不是这个场景。这实际上是一个不错的主意,因为CardLayout会根据按钮(或任何东西)来调整大小,即使按钮不可见,所以它也不会滥用布局管理器。我构建了一个HideableComponent类,它就是这样做的——用CardLayout包装面板中的任何组件,因此可以调用.setHidden(true/false)在它上面,所以不必知道它是通过CardLayout实现的,并且它工作得非常完美:)所以可以这样做,例如新的HideableComponent(新的JButton(action))。如果有兴趣,这里的代码-