问题描述
我正在使用 Java 8 并且我有一个 JFrame,我希望它具有所需的最小大小。如果框架被放大是可以的,但它不应低于最小值,以便 GUI 可用。
为此,我使用此 answer 中描述的解决方案。我首先使用 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 倍,但这会使框架更大,而且我无法使用 pack
或 setSize
之类的方法将其缩小。
所以我的问题是
- 我可以使用
setMinimumSize
使拖动尊重框架集的最小尺寸吗? - 我可以使帧尺寸小于使用
setMinimumSize
设置的尺寸而不是 手动拖动?
解决方法
我发现了一个(肮脏的)技巧:获取缩放因子并相应地计算最小尺寸;然后在设置缩放的最小尺寸时暂时禁用 setSize 方法。
这是在单屏环境中工作的,对于多个屏幕我必须在它上面工作(基本上在移动窗口时检查图形配置并更新最小尺寸)。
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);
}
}