JavaFX Slider仅响应拖拽忽略轨道点击的实现方案问询
让JavaFX Slider仅响应拖拽操作,忽略轨道点击
需求说明
我需要让JavaFX的Slider组件仅响应用户拖拽滑块的操作,始终忽略用户点击轨道的行为。另外也考虑过备选方案:点击轨道时仅让滑块值改变1。
我的尝试代码
第一次尝试
我试过通过addEventHandler获取事件目标(轨道或滑块),但不确定具体如何处理:
public class App extends Application { @Override public void start(Stage stage) { Slider slider = new Slider(); slider.addEventHandler(MouseEvent.ANY, new EventHandler<MouseEvent>() { public void handle(MouseEvent event) { event.getTarget(); //Do something here based on target...? event.consume(); } }); FlowPane flowPane = new FlowPane(); flowPane.getChildren().add(slider); var scene = new Scene(flowPane); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(); } }
第二次尝试(存在响应缓慢问题)
我做了新的尝试,控制台输出符合预期,但滑块响应非常缓慢,无法实际使用:
public class App extends Application { private boolean valueChanged; int blockIncrementStep = 1; @Override public void start(Stage stage) { Slider slider = new Slider(); slider.setMin(0); slider.setMax(255); slider.setBlockIncrement(blockIncrementStep); slider.setOnMouseDragged(e -> { valueChanged = false; System.out.println((int) slider.getValue()); }); slider.setOnMouseClicked(event -> valueChanged = false); slider.valueProperty().addListener((ov, oldValue, newValue) -> { if (!valueChanged) { valueChanged = true; if (newValue.intValue() > oldValue.intValue()) { slider.setValue(oldValue.intValue() + blockIncrementStep); System.out.println(oldValue.intValue() + blockIncrementStep); } else { slider.setValue(oldValue.intValue() - blockIncrementStep); System.out.println(oldValue.intValue() - blockIncrementStep); } } else { } }); FlowPane flowPane = new FlowPane(); flowPane.getChildren().add(slider); var scene = new Scene(flowPane); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(); } }
注:必须在setOnMouseDragged中添加valueChanged = false,否则滑块拖拽到最小值或最大值时无法正常工作。
第三次尝试(可行但不够简洁)
目前我得到了一个可行的实现,但代码不够简洁,因为我的项目中有大量Slider组件,希望能有更优雅的方案:
public class App extends Application { private boolean valueChanged; int blockIncrementStep = 1; Slider slider; @Override public void start(Stage stage) { slider = new Slider(); slider.setMin(0); slider.setMax(255); slider.setBlockIncrement(blockIncrementStep); slider.setOnMouseDragged(e -> { getSliderValue(); }); slider.setOnMouseClicked(event -> valueChanged = false); slider.valueProperty().addListener((ov, oldValue, newValue) -> { if (newValue.intValue() == 255 || oldValue.intValue() == 255 || newValue.intValue() == 0 || oldValue.intValue() == 0) { valueChanged = false; } }); slider.valueProperty().addListener((ov, oldValue, newValue) -> { if (!valueChanged) { valueChanged = true; if (newValue.intValue() > oldValue.intValue()) { slider.setValue(oldValue.intValue() + blockIncrementStep); getSliderValue(); } else { slider.setValue(oldValue.intValue() - blockIncrementStep); getSliderValue(); } } }); FlowPane flowPane = new FlowPane(); flowPane.getChildren().add(slider); var scene = new Scene(flowPane); stage.setScene(scene); stage.show(); } private void getSliderValue() { System.out.println((int) slider.getValue()); } public static void main(String[] args) { launch(); } }
希望能得到更简洁的实现方案,感谢!
内容的提问来源于stack exchange,提问作者droid
相关产品推荐
相关产品推荐

