I have an application-modal JDialog
which I want to have an enforced minimum size (i.e. the OS prevents the user from making the window any smaller than the minimum size). But the window should still be resizable (i.e. setResizable(false)
is not an option). Preferably, the enforced minimum size should be implicitly defined (i.e. dynamically determined by the minimum sizes of the child components, and not a fixed size set explicitly using setMinimumSize
)
The problem I've run into is that it seems if I don't explicitly set a minimum size on the JDialog
via setMinimumSize
, the OS will not enforce it. So even though the JDialog
implicitly knows the correct minimum size to use at any given time, that size won't be enforced unless I call something like dlg.setMinimumSize(dlg.getMinimumSize())
. See the SSCCE below.
In many cases, explicitly setting the minimum size just before opening the dialog is sufficient. However, sometimes I have a situation where the implicit minimum size can change while the dialog is open, e.g. a child component may be dynamically added or removed from the dialog. And if I set an explicit minimum size on the dialog, that size may not be sufficiently large for the new layout.
Is there any way to configure a JDialog
to enforce the implicit minimum size of the dialog? If not, is there some other elegant way to enforce a dynamically changing minimum size on an open dialog?
In this SSCCE, the goal is to create a dialog that cannot be made any smaller than 300x300 pixels. This goal is only met if the minimum size is explicitly set.
public class SSCCE {
public static void main(String[] args) {
JDialog dlg = new JDialog(null, ModalityType.APPLICATION_MODAL);
dlg.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
JPanel pnl = new JPanel(new BorderLayout());
pnl.add(new JLabel("300x300"), BorderLayout.CENTER);
// The panel is given a hard-coded minimum size just to make the
// problem easier to see
pnl.setMinimumSize(new Dimension(300,300));
dlg.add(pnl);
System.out.println("Dialog minimum size: " + dlg.getMinimumSize());
// Minimum size is not enforced by the OS without this call
dlg.setMinimumSize(dlg.getMinimumSize());
System.out.println("Dialog minimum size: " + dlg.getMinimumSize());
dlg.pack();
dlg.setVisible(true);
}
}
With explicit setMinimumSize
call:
Without explicit setMinimumSize
call:
Output in both cases:
Dialog minimum size: java.awt.Dimension[width=300,height=300]
Dialog minimum size: java.awt.Dimension[width=300,height=300]
For what it's worth - I observed this on Windows 8.1 with jdk1.8.0_91.
However, this is less than ideal because it causes the minimum dialog size to be fixed
Yes you should not be hardcoding values.
You could override the getMinimumSize()
method of your panel to:
Edit;
is there some other elegant way to allow for a dynamically changing minimum size on an open dialog?
You could add an AncestorListener
to your panel. The ancestorAdded
event is generated when the panel is added to a visible window (so basically the event is generated after the setVisible() on the dialog). Then you can use the SwingUtilities.windowForComponent(...)
method to get the window for the panel. Then you can invoked the setMinimumSize() on the dialog.