由question about Slider和一个小错误触发,我试图实现一个利用轴服务的SliderSkin,特别是它在像素和值之间的转换方法。工作正常,但NumberAxis将其转换偏移和比例因子保持为仅在布局过程中更新的内部字段。
如果我想在布局脉冲期间使用转换来更新另一个协作者,那么会出现问题:如果是滑块,那就是拇指。
下面是一个演示问题的小例子:只是一个NumberAxis和一个值的CheckBox。启动时,框放在中间的值。为获得最大效果,请最大化窗口并注意框位置未更改 - 现在位于轴的起点附近。实际上,在调整窗口大小但是不那么明显时也是如此 - 请参阅差异的打印输出。
使其有效的选项
寻找后者的方法(除了反射调用轴'layoutChildren之外找不到任何东西)。
示例:
public class AxisInvalidate extends Application {
public static class AxisInRegion extends Region {
NumberAxis axis;
Control thumb;
IntegerProperty value = new SimpleIntegerProperty(50);
private double thumbWidth;
private double thumbHeight;
public AxisInRegion() {
axis = new NumberAxis(0, 100, 25);
thumb = new CheckBox();
getChildren().addAll(axis, thumb);
}
@Override
protected void layoutChildren() {
thumbWidth = snapSize(thumb.prefWidth(-1));
thumbHeight = snapSize(thumb.prefHeight(-1));
thumb.resize(thumbWidth, thumbHeight);
double axisHeight = axis.prefHeight(-1);
axis.resizeRelocate(0, getHeight() /4, getWidth(), axisHeight);
// this marks the layout as dirty but doesn't immediately update internals
// doesn't make a difference, shouldn't be needed anyway
//axis.requestAxisLayout();
double pixelOnAxis = axis.getDisplayPosition(value.getValue());
Platform.runLater(() -> {
LOG.info("diff " + (pixelOnAxis - axis.getDisplayPosition(value.getValue())));
});
// moving this line into the runlater "solves" the problem
thumb.relocate(pixelOnAxis, getHeight() /4);
}
}
private Parent getContent() {
AxisInRegion region = new AxisInRegion();
BorderPane content = new BorderPane(region);
return content;
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(getContent(), 500, 200));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
@SuppressWarnings("unused")
private static final Logger LOG = Logger.getLogger(AxisInvalidate.class
.getName());
}
实际上,I think it's a bug:值/像素转换是Axis的公共服务 - 应始终有效。
答案 0 :(得分:1)
不确定它是否对您的初始问题有帮助,但只是手动执行计算。另一个加号 - 请求布局变得不必要,可以删除。
double range = axis.getUpperBound()-axis.getLowerBound();
double pixelOnAxis = axis.getWidth()*(value.get()-axis.getLowerBound())/range;
答案 1 :(得分:0)
刚从bug report开始工作:我们需要在更改大小/位置之后调用axis.layout()
,然后再查询转换方法,例如:
axis.resizeRelocate(0, getHeight() /4, getWidth(), axisHeight);
// doesn't make a difference, shouldn't be needed anyway
//axis.requestAxisLayout();
// working hack from bug report:
axis.layout();
double pixelOnAxis = axis.getDisplayPosition(value.getValue());
thumb.relocate(pixelOnAxis, getHeight() /4);