切换垂直 JScrollBar min/max 位置
Switch vertical JScrollBar min/max location
我有一个 vertical JScrollBar
,当滚动条值为在模型 最小值.
我想要相反的行为:当值处于最小值时,拇指将位于 底部。
我试过 setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT)
它适用于 水平滚动条 但不适用于垂直滚动条...
如何让它按预期工作(如果可能,不创建完整的 ScrollBarUI
)?
这是预期的行为吗(水平和垂直滚动条之间的一种 "UI inconsistency"*,或者缺少 ComponentOrientation.BOTTOM_TO_TOP
常量)?
这里有一些 SSCE 可以说明问题:
public static void main(String[] args) throws Exception {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int orient = JScrollBar.VERTICAL; // <<--- Change to HORIZONTAL
JScrollBar sb = new JScrollBar(orient, 0, 100, 0, 1000);
sb.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); // <<--- Works only for HORIZONTAL
sb.addAdjustmentListener(new AdjustmentListener() {
@Override public void adjustmentValueChanged(AdjustmentEvent e) {
System.out.println(e.getValue());
}
});
f.add(sb);
if (orient == JScrollBar.HORIZONTAL)
f.setBounds(100, 100, 500, 100);
else
f.setBounds(100, 100, 100, 500);
f.setVisible(true);
}
*: "inconsistency" 因为如果它在水平方向上反转拇指,我希望在垂直方向上也能反转拇指...
编辑:滚动条用于控制地图中的滚动,可以将其配置为原点在屏幕的顶部或底部,向下或向上,或向左或-向右,向右或向左(它必须匹配物理设置,因此是可配置的)。处理左或右设置只是将滚动条设置为水平,从右到左的方向,但同样不适用于垂直。
我还检查了 BasicScrollBarUI
的来源,当滚动条为 HORIZONTAL
时,它确实只处理 getComponentOrientation().isLeftToRight()
。所以这确实是预期的行为(只是不是 I 预期的...)。
我最终将 JScrollBar
子类化为 getAdjustedValue()
进行翻译。这个想法是 "reverse" 最小和最大,所以 [min;max]
变成 [-max;-min]
。然后我们在调整模型值时必须考虑范围,因为拇指底部(value + extent
)是我们想要的值:
public static class MySB extends JScrollBar {
private boolean inv;
public MySB(int orient, int value, int extent, int min, int max, boolean inv) {
super(orient, inv ? -value-extent : value, extent, inv ? -max : min, inv ? -min : max);
this.inv = inv;
}
public int getAdjustedValue() {
int v = super.getValue();
if (inv)
v = -(v + model.getExtent());
return v;
}
}
然后修改上面的SSCE,在AdjustmentListener中加入sb.getAdjustedValue()
:
...
MySB sb = new MySB(orient, 0, 100, 0, 1000, true);
sb.addAdjustmentListener(new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
System.out.println(e.getValue()+", "+((MySB)e.getAdjustable()).getMyValue());
}
});
...
-100, 0
-200, 100
-200, 100
-200, 100
-300, 200
-300, 200
我们看到了原始值和更正后的值。我最初开始对模型进行子类化并覆盖 getValue()
但它弄乱了页面 up/down 和箭头行为。
我有一个 vertical JScrollBar
,当滚动条值为在模型 最小值.
我想要相反的行为:当值处于最小值时,拇指将位于 底部。
我试过 setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT)
它适用于 水平滚动条 但不适用于垂直滚动条...
如何让它按预期工作(如果可能,不创建完整的 ScrollBarUI
)?
这是预期的行为吗(水平和垂直滚动条之间的一种 "UI inconsistency"*,或者缺少 ComponentOrientation.BOTTOM_TO_TOP
常量)?
这里有一些 SSCE 可以说明问题:
public static void main(String[] args) throws Exception {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int orient = JScrollBar.VERTICAL; // <<--- Change to HORIZONTAL
JScrollBar sb = new JScrollBar(orient, 0, 100, 0, 1000);
sb.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); // <<--- Works only for HORIZONTAL
sb.addAdjustmentListener(new AdjustmentListener() {
@Override public void adjustmentValueChanged(AdjustmentEvent e) {
System.out.println(e.getValue());
}
});
f.add(sb);
if (orient == JScrollBar.HORIZONTAL)
f.setBounds(100, 100, 500, 100);
else
f.setBounds(100, 100, 100, 500);
f.setVisible(true);
}
*: "inconsistency" 因为如果它在水平方向上反转拇指,我希望在垂直方向上也能反转拇指...
编辑:滚动条用于控制地图中的滚动,可以将其配置为原点在屏幕的顶部或底部,向下或向上,或向左或-向右,向右或向左(它必须匹配物理设置,因此是可配置的)。处理左或右设置只是将滚动条设置为水平,从右到左的方向,但同样不适用于垂直。
我还检查了 BasicScrollBarUI
的来源,当滚动条为 HORIZONTAL
时,它确实只处理 getComponentOrientation().isLeftToRight()
。所以这确实是预期的行为(只是不是 I 预期的...)。
我最终将 JScrollBar
子类化为 getAdjustedValue()
进行翻译。这个想法是 "reverse" 最小和最大,所以 [min;max]
变成 [-max;-min]
。然后我们在调整模型值时必须考虑范围,因为拇指底部(value + extent
)是我们想要的值:
public static class MySB extends JScrollBar {
private boolean inv;
public MySB(int orient, int value, int extent, int min, int max, boolean inv) {
super(orient, inv ? -value-extent : value, extent, inv ? -max : min, inv ? -min : max);
this.inv = inv;
}
public int getAdjustedValue() {
int v = super.getValue();
if (inv)
v = -(v + model.getExtent());
return v;
}
}
然后修改上面的SSCE,在AdjustmentListener中加入sb.getAdjustedValue()
:
...
MySB sb = new MySB(orient, 0, 100, 0, 1000, true);
sb.addAdjustmentListener(new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
System.out.println(e.getValue()+", "+((MySB)e.getAdjustable()).getMyValue());
}
});
...
-100, 0
-200, 100
-200, 100
-200, 100
-300, 200
-300, 200
我们看到了原始值和更正后的值。我最初开始对模型进行子类化并覆盖 getValue()
但它弄乱了页面 up/down 和箭头行为。