Если я настроил JFrame с некоторыми компонентами и менеджером компоновки, который изначально выглядит отлично, а затем позже из-за некоторого состояния (например, нажав кнопку), я скрою один из этих компонентов - менеджер компоновки перетасовывает все компоненты снова вокруг.Скрыть компонент качания без повторной калибровки макета?
См. Пример кода - изначально отображаются 3 кнопки. Когда вы нажимаете кнопку «Скрыть», кнопка «Скрыть» скрыта, но две внешние кнопки скручиваются вместе. Когда вы нажимаете кнопку «Показать», они снова разворачиваются, чтобы освободить место. Как я могу остановить это, чтобы после того, как я вызвал пакет(), компоненты останутся там, где они не имеют значения, если они позже станут скрытыми?
В моем реальном коде я делаю это с 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();
}
});
}
}
Да, я много использовал CardLayouts, но не для этого сценария. Его действительно неплохая идея, потому что CardLayout будет определять размер в соответствии с кнопкой (или что-то еще), даже если кнопка не видна, поэтому она не хочет злоупотреблять менеджером компоновки. – nigelg
Я построил класс HideableComponent, который делает именно это - обертывает любой компонент в панели с помощью cardlayout, поэтому может просто вызвать .setHidden (true/false) на нем, поэтому его не нужно знать, что под обложками он реализуется через CardLayout , и он отлично работает :), так можно сделать, например новый HideableComponent (новый JButton (действие)).Если вас интересует код - https://sourceforge.net/p/momime/code/HEAD/tree/Java/MoMIMEClient/trunk/src/main/java/momime/client/ui/components/HideableComponent.java –
nigelg