0

我正在尝试Slider在我的 JavaFX 应用程序中添加一个路径到一个组,该组也包含一个,以便让用户标记与该Slider值关联的对象的某些特征。但是,路径(在这种情况下是一条垂直线)没有被标记在完全正确的位置。对于较小的值,它在拇指之前,对于较大的值,它在拇指之后。

double pixelsPerValue = slider.getWidth() / (slider.getMax() - slider.getMin());
double leftAdjust = slider.getLayoutX();
double pathX = leftAdjust + (slider.getValue() * pixelsPerValue);
Path path = PathBuilder.create()
    .elements(
        new MoveTo(pathX, 0)
        , new LineTo(pathX, 25)
        )
    .stroke(Color.CYAN)
    .strokeWidth(3)
    .translateX(0)
    .translateY(27.0)
    .build();

注意两点:

  1. 该组位于 BorderPane 底部的 HBox 中;
  2. Slider 的最大值由用户想要滚动的对象数量决定,例如 8,617、10,492、6,345 - 你懂的。

知道为什么会这样吗?我该如何解决?

4

2 回答 2

2

很少的笔记;

  1. 您绘制的线的轻微滑动是由于滑块的边框和滑块线之间的左右边距。您可以通过更改double margin下面代码中的值来测试它。
  2. 在显示阶段之前,您无法使用slider.getWidth()。请参阅下面代码中的“之前”和“之后”打印。相反,我使用了slider.getPrefWidth(). 当然,如果您在某些事件处理程序中使用 getWidth() 则没问题。
  3. 使用绑定更容易控制和编码。在下面的代码中滑动拇指。

公共类 SliderDemo 扩展应用程序 {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        Slider slider = new Slider();
        slider.setStyle("-fx-border-color: green");
        slider.setLayoutX(60);
        slider.setLayoutY(50);
        slider.setMax(200);
        slider.setValue(180);
        slider.setMin(100);
        slider.setPrefWidth(390);

        double margin = 10; // left and right margins between the border and the slider line of the slider

        SimpleDoubleProperty pixelsPerValueProperty = //
                new SimpleDoubleProperty((slider.getPrefWidth() //
                - (2 * margin)) / (slider.getMax() - slider.getMin()));

        SimpleDoubleProperty pathXProperty = new SimpleDoubleProperty();
        pathXProperty.bind(slider.layoutXProperty()//
                .add(margin)//
                .add(pixelsPerValueProperty.multiply(slider.valueProperty().subtract(slider.getMin()))));

        MoveTo moveTo = new MoveTo(0, 0);
        moveTo.xProperty().bind(pathXProperty);
        LineTo lineTo = new LineTo(0, 25);
        lineTo.xProperty().bind(pathXProperty);

        Path path = PathBuilder.create().elements(
                moveTo, lineTo)//
                .stroke(Color.CYAN)//
                .strokeWidth(3)//
                .translateX(0)//
                .translateY(77.0)//
                .build();

        Group group = new Group(slider, path);
        primaryStage.setScene(new Scene(group, 700, 250));
        System.out.println("before slider.getWidth() = " + slider.getWidth());
        primaryStage.show();
        System.out.println("after slider.getWidth() = " + slider.getWidth());
    }
}
于 2012-07-24T10:09:36.403 回答
0
private void addMarker() {

       double margin = 7; // left and right margins between the border and the slider line of the slider

        SimpleDoubleProperty pixelsPerValueProperty = new SimpleDoubleProperty( //
                (slider.getPrefWidth() - (2 * margin)) / (slider.getMax() - slider.getMin())); // need preferred width even though called from keystroke handler

        SimpleDoubleProperty pathXProperty = new SimpleDoubleProperty();
        pathXProperty.bind(slider.layoutXProperty()//
                .add(margin)//
                .add(pixelsPerValueProperty.multiply(slider.valueProperty().subtract(slider.getMin())))//
        );

        double currentValue = pathXProperty.doubleValue(); 
        MoveTo moveTo = new MoveTo(0, 0);
        moveTo.setX(currentValue);
        LineTo lineTo = new LineTo(0, 25);
        lineTo.setX(currentValue);

        Path myTick = PathBuilder.create()
            .elements(
                moveTo
                , lineTo
                )
            .stroke(Color.CYAN)
            .strokeWidth(3)
            .translateX(0)     // for path instantiated in FXML = 7.0
            .translateY(27.0)
            .managed(true)
            .build();

        pathGroup.getChildren().add(myTick);

}
于 2012-07-25T19:57:15.603 回答