根据用户规模变化更新组件 border/insets

Update components border/insets on user scale change

我目前正在使用 FlatLaf UI 作为我的 Swing 应用程序的外观。
FlatLaf 提供了一种基于字体大小的用户缩放机制,例如:

12pt: 1.0 | 100%
16pt: 1.3 | 130%

这意味着所有的边框和插图都是根据这个因素计算的:

BorderFactory.createEmptyBorder(UIScale.scale(10), ... // Which means 10 * 1.3, for example

当用户比例改变并且组件显示在屏幕上时出现问题。
鉴于我在 class 构造函数上添加和自定义组件...

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 比例时,我如何有效地更新它们的插图?

FlatLaf 提供回调通知。

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, axis == Y_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);
}