问题描述
我目前使用 flatlaf UI 作为我的 Swing 应用程序的外观和感觉。
flatlaf 提供基于字体大小的用户缩放机制,例如:
12pt: 1.0 | 100%
16pt: 1.3 | 130%
这意味着所有边框和插图都是考虑到这个因素来计算的:
BorderFactory.createEmptyBorder(UIScale.scale(10),... // Which means 10 * 1.3,for example
当用户比例改变并且组件显示在屏幕上时出现问题。
鉴于我在类构造函数上添加和自定义组件...
public class ProtocolSearchBar extends Box {
public ProtocolSearchBar() {
...
add(protocolLabel);
add(Box.createHorizontalStrut(UIScale.scale(10)));
add(protocol);
add(Box.createHorizontalStrut(UIScale.scale(10)));
add(fetchButton);
}
...
...如何在用户每次更改 UI 比例时有效地更新其插图?
UIScale.addPropertychangelistener(event -> {
if ("userScaleFactor".equals(event.getPropertyName())) {
...
}
});
解决方法
一个巧妙的解决方案是扩展标准的 Swing 组件,例如
public class ScaledFiller extends Filler {
public enum Axis {
X_AXIS,Y_AXIS
}
public ScaledFiller(final int size,final Axis axis) {
super(
new Dimension(axis == X_AXIS ? size : 0,axis == Y_AXIS ? size : 0),new Dimension(axis == X_AXIS ? size : 0,new Dimension(axis == X_AXIS ? size : Short.MAX_VALUE,axis == Y_AXIS ? size : Short.MAX_VALUE)
);
}
public ScaledFiller(final Dimension min,final Dimension pref,final Dimension max) {
super(min,pref,max);
}
@Override
public Dimension getMinimumSize() {
return new ScaledDimension(super.getMinimumSize());
}
@Override
public Dimension getPreferredSize() {
return new ScaledDimension(super.getPreferredSize());
}
@Override
public Dimension getMaximumSize() {
return new ScaledDimension(super.getMaximumSize());
}
}
并用作
@NotNull
public static Filler horizontalStrut(final int size) {
return new ScaledFiller(size,ScaledFiller.Axis.X_AXIS);
}
@NotNull
public static Filler verticalStrut(final int size) {
return new ScaledFiller(size,ScaledFiller.Axis.Y_AXIS);
}