在JDialog上实施隐式最小大小?

时间:2016-10-19 20:42:25

标签: java swing awt jdialog

问题

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

我遇到的问题是,如果我没有通过JDialogsetMinimumSize上明确设置最小大小,操作系统将不会强制执行它。因此,即使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来电:

Properly sized 300x300 JDialog

没有明确的setMinimumSize电话:

Improperly sized JDialog

两种情况下的输出:

  

对话框最小尺寸:java.awt.Dimension [width = 300,height = 300]
  对话框最小尺寸:java.awt.Dimension [width = 300,height = 300]

对于它的价值 - 我在Windows 8.1上使用jdk1.8.0_91观察到了这一点。

3 个答案:

答案 0 :(得分:2)

  

但是,这不太理想,因为它会导致最小对话框大小固定

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

您可以将面板的getMinimumSize()方法覆盖为:

  1. 只返回优先大小,或
  2. 返回首选大小的比例。
  3. 编辑;

      

    还有其他一些优雅的方法可以在打开的对话框中动态更改最小尺寸吗?

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

答案 1 :(得分:2)

检查代码中的注释。这里没有神奇的数字!

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);
    }
}

输出

Dialog minimum size: java.awt.Dimension[width=97,height=16]
Dialog minimum size: java.awt.Dimension[width=113,height=55]

答案 2 :(得分:0)

我遇到了同样的问题,这就是我使用的代码:

p[i][j]