Java 在JDialog上强制执行隐式最小大小? 问题:
我有一个应用程序模式Java 在JDialog上强制执行隐式最小大小? 问题:,java,swing,awt,jdialog,Java,Swing,Awt,Jdialog,我有一个应用程序模式JDialog,我希望有一个强制的最小大小(即操作系统阻止用户使窗口小于最小大小)。但窗口仍应可调整大小(即setresizeable(false)不是选项)。优选地,应隐式定义强制最小尺寸(即,由子组件的最小尺寸动态确定,而不是使用setMinimumSize显式设置固定尺寸) 我遇到的问题是,如果我没有通过setMinimumSize在JDialog上显式设置最小大小,操作系统将不会强制执行它。因此,即使JDialog隐式地知道在任何给定时间使用的正确最小大小,也不会强制
JDialog
,我希望有一个强制的最小大小(即操作系统阻止用户使窗口小于最小大小)。但窗口仍应可调整大小(即setresizeable(false)
不是选项)。优选地,应隐式定义强制最小尺寸(即,由子组件的最小尺寸动态确定,而不是使用setMinimumSize
显式设置固定尺寸)
我遇到的问题是,如果我没有通过setMinimumSize
在JDialog
上显式设置最小大小,操作系统将不会强制执行它。因此,即使JDialog
隐式地知道在任何给定时间使用的正确最小大小,也不会强制执行该大小,除非我调用类似dlg.setMinimumSize(dlg.getMinimumSize())
。请参见下面的SSCCE
在许多情况下,在打开对话框之前显式设置最小大小就足够了。但是,有时我会遇到这样一种情况,即当对话框打开时,隐式最小大小可能会改变,例如,可以动态地在对话框中添加或删除子组件。如果我在对话框上设置了一个明确的最小大小,那么这个大小对于新布局来说可能不够大
是否有任何方法可以配置JDialog
以强制执行对话框的隐式最小大小?如果没有,是否有其他优雅的方法在打开的对话框上强制执行动态更改的最小大小
SSCCE
在这个SSCCE中,目标是创建一个不能小于300x300像素的对话框。只有明确设置了最小大小,才能实现此目标
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);
}
}
使用显式setMinimumSize
调用:
无显式setMinimumSize
调用:
两种情况下的输出:
对话框最小大小:java.awt.Dimension[宽度=300,高度=300]对话框最小大小:java.awt.Dimension[宽度=300,高度=300] 值得一提的是,我在Windows8.1和jdk1.8.091上观察到了这一点 但是,这并不理想,因为它会导致固定最小对话框大小 是的,您不应该硬编码值 您可以将面板的
getMinimumSize()
方法重写为:
AncestorListener
。将面板添加到可见窗口时会生成ancestorAdded
事件(因此基本上,该事件是在对话框上的setVisible()之后生成的)。然后可以使用SwingUtilities.windowForComponent(…)
方法获取面板的窗口。然后可以在对话框上调用setMinimumSize()
但是,这并不理想,因为它会导致固定最小对话框大小
是的,您不应该硬编码值
您可以将面板的getMinimumSize()
方法重写为:
您可以在面板中添加一个
AncestorListener
。将面板添加到可见窗口时会生成ancestorAdded
事件(因此基本上,该事件是在对话框上的setVisible()之后生成的)。然后可以使用SwingUtilities.windowForComponent(…)
方法获取面板的窗口。然后可以在对话框中调用setMinimumSize()。检查代码中的注释。这里没有魔法数字
import java.awt.*;
import java.awt.Dialog.ModalityType;
import javax.swing.*;
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("As big as needed"), BorderLayout.CENTER);
//pnl.setMinimumSize(new Dimension(300,300));
dlg.add(pnl);
System.out.println("Dialog minimum size: " + dlg.getMinimumSize());
dlg.pack(); // make the dialog as large as needed to display content
// Minimum size is not enforced by the OS without this call
dlg.setMinimumSize(dlg.getPreferredSize());
System.out.println("Dialog minimum size: " + dlg.getMinimumSize());
dlg.setVisible(true);
}
}
输出
检查代码中的注释。这里没有魔法数字
import java.awt.*;
import java.awt.Dialog.ModalityType;
import javax.swing.*;
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("As big as needed"), BorderLayout.CENTER);
//pnl.setMinimumSize(new Dimension(300,300));
dlg.add(pnl);
System.out.println("Dialog minimum size: " + dlg.getMinimumSize());
dlg.pack(); // make the dialog as large as needed to display content
// Minimum size is not enforced by the OS without this call
dlg.setMinimumSize(dlg.getPreferredSize());
System.out.println("Dialog minimum size: " + dlg.getMinimumSize());
dlg.setVisible(true);
}
}
输出
我也有同样的问题,这就是我使用的代码:
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
Dimension size = getSize();
if( size.getWidth() <= getMinimumSize().getWidth() || size.getHeight() <= getMinimumSize().getHeight() ) {
int width = (int) (getMinimumSize().getWidth() + 2);
int height = (int) (getMinimumSize().getHeight() + 2);
setSize( new Dimension( width, height ) );
}
}
});
addComponentListener(新的ComponentAdapter(){
@凌驾
公共无效组件已恢复(组件事件e){
维度大小=getSize();
如果(size.getWidth()我也有同样的问题,我使用的代码是:
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
Dimension size = getSize();
if( size.getWidth() <= getMinimumSize().getWidth() || size.getHeight() <= getMinimumSize().getHeight() ) {
int width = (int) (getMinimumSize().getWidth() + 2);
int height = (int) (getMinimumSize().getHeight() + 2);
setSize( new Dimension( width, height ) );
}
}
});
addComponentListener(新的ComponentAdapter(){
@凌驾
公共无效组件已恢复(组件事件e){
维度大小=getSize();
如果(size.getWidth()我尝试在JPanel
上重写getMinimumSize()
,这没有什么区别。硬编码的值只是为了在SSCCE中简洁起见。JDialog
知道正确的最小大小,问题是除非通过dlg.setMinimumSize(…)显式设置,否则它不会强制执行
这很有帮助,谢谢。如果添加/删除组件,我想我也可以使用容器列表器来响应。我已经尝试覆盖getMinimumSize()
在JPanel
上,它没有区别。硬编码值只是为了在SSCCE中简洁起见。JDialog
知道正确的最小大小,问题是除非通过dlg.setMinimumSize(…)显式设置,否则它不会强制执行
这很有帮助,谢谢。如果添加/删除组件,我想我也可以使用ContainerListener
来响应。嗨,Andrew,正如我向camickr提到的那样,JPanel
上的硬编码最小大小只是为了在SSCE中简洁。我实际的问题是如何让操作系统强制执行隐式最小大小我更新了我的问题,使之更清楚。嗨,安德鲁,正如我也向camickr提到的,JPanel
上硬编码的最小大小只是为了在SSCE中简洁。我实际的问题是如何让操作系统强制执行JDialog
的隐式最小大小。我更新了我的问题,使其更简洁一个c的对话