2012-07-23 71 views
0

我想在我的JavaFX应用程序中添加一个包含Slider的组的路径,以便让用户标记与该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. 滑块的最大值由用户想滚动的对象的数量 确定,可以是例如, 8,617,10,492,6,345 - 你明白了。

任何想法为什么会发生这种情况?我该如何解决它?

回答

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()); 
    } 
} 
+0

感谢 - 这工作。为了达到我的目的,我稍微更改了绑定代码,即在滑块上的用户确定位置设置永久性标记: – 2012-07-25 19:39:06

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); 

}