Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 编号/轴:如何在布局期间强制立即更新内部状态?_Java_Slider_Javafx 8_Axis - Fatal编程技术网

Java 编号/轴:如何在布局期间强制立即更新内部状态?

Java 编号/轴:如何在布局期间强制立即更新内部状态?,java,slider,javafx-8,axis,Java,Slider,Javafx 8,Axis,受到一个小错误和一个小错误的触发,我尝试实现一个利用axis服务的SliderSkin,特别是它在像素和值之间的转换方法。工作正常,只是NumberAxis将其转换偏移量和比例因子保持为仅在布局过程中更新的内部字段 如果我想在布局脉冲期间使用转换来更新另一个协作者,这就带来了一个问题:在滑块的情况下,它将是拇指 下面是一个小例子来演示这个问题:只需一个NumberAxis和某个值的复选框。启动时,长方体将放置在中间的值处。为了获得最大效果,请最大化窗口,并注意长方体的位置没有改变-现在位于轴的起

受到一个小错误和一个小错误的触发,我尝试实现一个利用axis服务的SliderSkin,特别是它在像素和值之间的转换方法。工作正常,只是NumberAxis将其转换偏移量和比例因子保持为仅在布局过程中更新的内部字段

如果我想在布局脉冲期间使用转换来更新另一个协作者,这就带来了一个问题:在滑块的情况下,它将是拇指

下面是一个小例子来演示这个问题:只需一个NumberAxis和某个值的复选框。启动时,长方体将放置在中间的值处。为了获得最大效果,请最大化窗口,并注意长方体的位置没有改变-现在位于轴的起点附近。实际上,调整窗口大小时也是如此,但不太明显-请参见差异的打印输出

让它工作的选项

  • 延迟拇指定位,直到下一个布局脉冲(感觉笨拙)
  • 强制轴立即更新
正在寻找后一种方法(除了反射调用axis的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());
}

实际上,值/像素转换是Axis的一项公共服务,应该一直有效

不确定这是否有助于您的首次发行,只需手动计算即可。另一个plus-request布局变得不必要,可以删除

  double range = axis.getUpperBound()-axis.getLowerBound();
  double pixelOnAxis = axis.getWidth()*(value.get()-axis.getLowerBound())/range;

刚刚从中得到了一个有用的技巧:我们需要在更改大小/位置之后,在查询转换方法之前调用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);

当然,另一个可行的选择,谢谢:-)更愿意避免手动操作。事实上,我认为“加号”(在这种情况下没有任何区别,只是因为核心代码经常添加它而添加)是一个bug:公共服务必须始终正确提供;-)@GunnarBernstein hach,忘记接受我自己的——多年来:)