首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在JDialog上强制执行隐式最小大小?

在JDialog上强制执行隐式最小大小?
EN

Stack Overflow用户
提问于 2016-10-19 20:42:25
回答 3查看 1.3K关注 0票数 0

问题

我有一个应用程序模式的JDialog,我希望有一个强制的最小大小(即操作系统阻止用户使窗口比最小大小更小)。但是窗口仍然应该是可调整大小的(即setResizable(false)不是一个选项)。最好是隐式定义强制执行的最小大小(即由子组件的最小大小动态确定,而不是使用setMinimumSize显式地确定固定大小集)。

我遇到的问题是,如果我不通过JDialog通过setMinimumSize显式设置最小大小,操作系统就不会强制执行它。因此,即使JDialog隐式地知道在任何给定时间使用正确的最小大小,除非我调用类似于dlg.setMinimumSize(dlg.getMinimumSize())的东西,否则不会强制使用该大小。请参阅下面的SSCCE。

在许多情况下,在打开对话框之前显式设置最小大小就足够了。但是,有时我遇到的情况是,在打开对话框时,隐式最小大小可能会发生变化,例如,可以动态添加或从对话框中删除子组件。如果我在对话框上设置了一个显式的最小大小,那么对于新的布局来说,这个大小可能不够大。

是否有任何方法配置JDialog以强制执行对话框的隐式最小大小?如果没有,是否有其他优雅的方法在打开的对话框上强制执行动态更改的最小大小?

SSCCE

在这个SSCCE中,目标是创建一个不能小于300x300像素的对话框。只有在显式设置最小大小时才能实现此目标。

代码语言:javascript
复制
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.Dimensionwidth=300,height=300 对话框最小大小: java.awt.Dimensionwidth=300,height=300

值得注意的是,我在Windows8.1上用jdk1.8.0_91观察到了这一点。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-19 20:51:45

但是,这并不理想,因为它会使最小对话框大小固定下来。

是的,您不应该硬编码值。

可以重写面板的getMinimumSize()方法,以便:

  1. 只需返回预先推断的大小,或
  2. 返回一些优先大小的比率。

编辑;

在打开的对话框中,是否有其他优雅的方法允许动态更改最小大小?

您可以向面板中添加一个AncestorListenerancestorAdded事件是在面板添加到可见窗口时生成的(因此,该事件基本上是在对话框上的setVisible()之后生成的)。然后可以使用SwingUtilities.windowForComponent(...)方法获取面板的窗口。然后,您可以在对话框上调用setMinimumSize()。

票数 2
EN

Stack Overflow用户

发布于 2016-10-20 12:30:11

检查代码中的注释。这里没有魔法号码!

代码语言:javascript
复制
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);
    }
}

输出

代码语言:javascript
复制
Dialog minimum size: java.awt.Dimension[width=97,height=16]
Dialog minimum size: java.awt.Dimension[width=113,height=55]
票数 3
EN

Stack Overflow用户

发布于 2021-05-01 21:38:54

我也有同样的问题,这就是我使用的代码:

代码语言:javascript
复制
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 ) );
        }
    }
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40141159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档