5

这是我的代码:

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 x 200px JPanel。但是当我删除时:

JFrame.setDefaultLookAndFeelDecorated(true);

用户可以调整JFrame到任何大小。

为什么默认外观装饰会影响调整大小?我怎样才能使它工作没有setDefaultLookAndFeelDecorated(true)?我知道我可以手动设置帧最小尺寸 ( JFrame#setMinimumSize(new Dimension dim)),如果没有更智能的解决方案,我会这样做。

我在 Windows 7 上使用 jdk 1.7。

4

2 回答 2

4

曾经是一个错误,该页面谈到了解决方法,例如:

  • 覆盖setSize()并检查新大小是否小于所需大小
  • paint(Graphics g)检查高度和宽度的内部JFrame并“重新创建”框架到新的最小尺寸

但是有人声称它已修复,因为为错误提案发布的原始示例省略了对 的调用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(..)的,但我将它包含在内,因为这就是我找到代码片段的方式(我确实删除了 代码片段包含的被覆盖getPreferredSize()的方法)。JFrame

于 2012-09-30T20:02:03.380 回答
2

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

因为在拖动时窗口大小完全由 LAF 控制: (fi) MetalRootPaneUI 安装的 mouseHandler 不会将窗口大小调整到 LayoutManager 返回的最小值以下。在不设置框架的 minimumSize 的情况下,您仍然可以通过编程方式减小其大小。

强制窗口最小尺寸的唯一方法(不幸的是)始终是手动设置它。不幸的是,这意味着跟踪该最小值的动态变化并酌情更新它。

可使用的片段(取消/评论 defaultDecoration 和 frame min 设置)

JFrame.setDefaultLookAndFeelDecorated(true);
JPanel panel = new JPanel() {

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.BLACK);
        Dimension m = getMinimumSize();
        // visualize the min
        g.drawRect(0, 0, m.width - 1, m.height -1);
    }

};
// BEWARE: for demonstration only, NEVER do in production code 
panel.setMinimumSize(new Dimension(400, 400));
panel.setPreferredSize(panel.getMinimumSize());
final JXFrame frame = new JXFrame("", true);
Action action = new AbstractAction("resize") {

    @Override
    public void actionPerformed(ActionEvent e) {
        frame.setSize(300, 300);
        LOG.info("succeeded? " + frame.getSize());
    }
};
panel.add(new JButton(action));
frame.add(panel);
frame.pack();
// set minimum is required to enforce the minimum
frame.setMinimumSize(frame.getMinimumSize());

更新

查看 Window 源代码,事实证明,您可以通过覆盖 isMinimumSizeSet 并无条件返回 true 来对最小尺寸进行自动魔术动态尊重:

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

虽然没有测试副作用

于 2012-10-01T09:14:37.463 回答