当 windows 缩放未设置为 100% 时,与 Jframes 的 setMinimumSize 和手动拖动的行为不一致

Inconsistent beahaviour with Jframes's setMinimumSize and manully dragging when windows scaling is not set to 100%

我正在使用 Java 8,我有一个 JFrame,我希望它具有所需的最小尺寸。如果框架被放大是可以的,但它不应该低于最小值以便 GUI 可用。 为此,我使用了 中描述的解决方案。我首先使用 pack 然后将最小尺寸设置为帧尺寸。但出于某种原因,它仅在 Windows 缩放比例设置为 1/100% 时才有效。对于其他缩放值,我实际上可以通过拖动使框架变小(这与缩放值成正比)。

这是一个示例代码

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

public class ScalingProblem extends JFrame {

  public ScalingProblem() {

    setTitle("My Gui");
    setSize(400, 400);

    JButton button = new JButton("Button 1");
    JButton button2 = new JButton("Button 2");
    JButton button3 = new JButton("Button 3");
    JButton button4 = new JButton("Button 4");
    JPanel panel = new JPanel(new BorderLayout());

    panel.add(button, BorderLayout.NORTH);
    panel.add(button2, BorderLayout.EAST);
    panel.add(button3, BorderLayout.WEST);
    panel.add(button4, BorderLayout.SOUTH);

    this.getContentPane().add(panel);

    setVisible(true);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    pack();
    setMinimumSize(getSize());
  }

  public static void main(String[] args) {

    ScalingProblem a = new ScalingProblem();
  }
}

即使在设置了最小框架尺寸后,我也可以将其缩小 1.25 倍,这也是我的显示比例因子。

所以基本上当拖动框架时,尺寸可以小于使用 setMinimumSize 设置的最小尺寸。我尝试将最小尺寸设置为 getSize 返回值的 1.25 倍,但这会使框架变大,我无法使用 packsetSize.

等方法使其变小

所以我的问题是

  1. 我可以使用 setMinimumSize 使拖动符合框架集的最小尺寸吗?
  2. 我可以使帧大小小于使用 setMinimumSize 设置的大小吗? 手动拖动?

我发现了一个(肮脏的)技巧:获取比例因子并相应地计算最小尺寸;然后在设置缩放最小尺寸时暂时禁用 setSize 方法。

这是在单屏环境下工作的,对于多屏我必须在它上面工作(基本上检查window移动时的图形配置并更新最小尺寸)。

package test;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.geom.AffineTransform;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class TestScaling extends JFrame {

    public TestScaling() {
        super("Test scaling");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel=new JPanel(new GridBagLayout());
        GridBagConstraints c=new GridBagConstraints();
        for (int i=0;i<10;i++) {
            for (int j=0;j<8;j++) {
                c.gridx=j;
                c.gridy=i;
                panel.add(new JButton(i+"x"+j),c);
            }
        }
        setContentPane(panel);
        pack();
        Dimension dorig=getSize();
        AffineTransform at=getGraphicsConfiguration().getDefaultTransform();
        Dimension dmin=new Dimension((int) (dorig.width*at.getScaleX()), (int) (dorig.height*at.getScaleY()));
        
        //A dirty trick, when workaround is true setSize(int,int) will not work
        //so setMinimumSize will not resize the window
        workaround=true;
        setMinimumSize(dmin);
        workaround=false;
    }
    
    protected boolean workaround;
    
    @Override
    public void setSize(int width, int height) {
        if (workaround) {
            return;
        }
        super.setSize(width, height);
    }
    
    
    public static void main(String[] args) {
        new TestScaling().setVisible(true);
    }
}