Java setDefaultLookAndFeelDecorated影响JFrame调整大小行为

Java setDefaultLookAndFeelDecorated影响JFrame调整大小行为,java,swing,jframe,resize,look-and-feel,Java,Swing,Jframe,Resize,Look And Feel,这是我的代码: import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class Test{ public static void main(String[] args){ SwingUtilities.invokeLater(new Runnable(){ @Overr

这是我的代码:

import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class Test{


public static void main(String[] args){

    SwingUtilities.invokeLater(new Runnable(){

        @Override
        public void run() {

            JFrame.setDefaultLookAndFeelDecorated(true);

            JFrame frame = new JFrame();
            JPanel jp = new JPanel();

            jp.setMinimumSize(new Dimension(200, 200));
            jp.setPreferredSize(new Dimension(200, 200));

            //frame.getContentPane().setMinimumSize(new Dimension(200, 200));
            //frame.getContentPane().setPreferredSize(new Dimension(200, 200));

            frame.getContentPane().add(jp);

            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);
        }
    });
}
}
它的行为正是我想要的。用户可以调整JFrame的大小,但它总是足够大,可以容纳200px 200px
JPanel
。但当我删除:

JFrame.setDefaultLookAndFeelDecorated(true)

用户可以将
JFrame
调整为任意大小

为什么默认外观装饰会影响大小调整?如果没有
设置DefaultLookandFeelDecorated(true)
,我如何使其工作?我知道我可以手动设置框架最小尺寸(
JFrame#setMinimumSize(新尺寸标注)
),如果没有更智能的解决方案,我会这样做

我在Windows 7上使用jdk 1.7。

曾经是一个bug,页面谈到了一些解决方法,如:

  • 覆盖
    setSize()
    并检查新尺寸是否小于所需尺寸
  • 内部
    绘制(图形g)
    JFrame
    检查高度和宽度,并将框架“重新创建”为新的最小尺寸
然而,有人声称它是固定的,因为为bug建议发布的原始示例忽略了对
setMinimumSize(…)
的调用,这是必需的,因为JFrame没有强制执行最小大小

以下是显示人员代码的代码片段:

import java.awt.Dimension;
import javax.swing.*;

public class JavaApplication118 {

    private final Dimension m_dim = new Dimension(200, 150);

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new JavaApplication118().createAndShowUI();
            }
        });
    }

    private void createAndShowUI() {

        // JFrame.setDefaultLookAndFeelDecorated(true);

        final JFrame frame = new JFrame("Test") {

            @Override
            public Dimension getMinimumSize() {
                return m_dim;
            }

        };

        frame.setMinimumSize(m_dim);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        initComponents(frame);

        // frame.setResizable(false);
        frame.pack();
        frame.setVisible(true);
    }

    private void initComponents(JFrame frame) {
        JPanel jp = new JPanel();

        jp.setMinimumSize(new Dimension(200, 200));
        jp.setPreferredSize(new Dimension(400, 400));//for testing

        frame.getContentPane().add(jp);
    }
}
编辑

代码段覆盖了
getMinimumSize()
虽然调用
setMinimumSize(…)
后这似乎是多余的,但我保留了它,因为这就是我找到代码段的原因(我确实删除了代码段包含的
JFrame
的被覆盖的
getPreferredSize()
方法)

为什么默认外观装饰会影响大小调整

因为在拖动时,窗口大小完全由LAF控制:由(f.i.)MetalRootPaneUI安装的鼠标手柄不会将窗口大小调整到LayoutManager返回的最小值以下。在不设置帧的最小大小的情况下,仍然可以通过编程方式减小其大小

执行窗口最小大小的唯一方法(不幸的是)始终是手动设置它。不幸的是,这意味着要跟踪该最小值的动态变化,并在适当时进行更新

要使用的片段(取消/注释DefaultEdition和frame min设置)

更新

查看窗口源代码,您可以通过重写isMinimumSizeSet并非常规地返回true来获得最小大小的auto magic动态特性:

final JXFrame frame = new JXFrame("", true) {
    @Override
    public boolean isMinimumSizeSet() {
        return true;
    }
};
...
// no longer needed
// frame.setMinimumSize(frame.getMinimumSize());

没有进行副作用测试,不过这是一个很好的问题。我也想知道。这已经过时了:从1.6开始,Window保证遵守最小大小,不幸的是,只有在Window显式设置的情况下。setMinimumSize@kleopatra是的,这就是为什么我认为调用这些方法并不“坏”+1到您的iszminimumsizeset重写它是一个奇点,可能是因为它是一个顶级容器。它的行为只有在底层操作系统保证的情况下才能得到保证。所有其他setXXSize仍然是邪恶的;-)
final JXFrame frame = new JXFrame("", true) {
    @Override
    public boolean isMinimumSizeSet() {
        return true;
    }
};
...
// no longer needed
// frame.setMinimumSize(frame.getMinimumSize());