如何单独引用 RangeSlider 的每个拇指 (ControlsFX)
Posted
技术标签:
【中文标题】如何单独引用 RangeSlider 的每个拇指 (ControlsFX)【英文标题】:How to Individually Reference Each Thumb of a RangeSlider (ControlsFX) 【发布时间】:2017-05-20 17:54:01 【问题描述】:我正在尝试绑定要显示在RangeSlider 上下拇指上方的标签。
无论用户将其滑动到何处,标签的位置都应始终保持在其各自拇指上方。像这样:
我的方法是将侦听器附加到每个拇指,以便我可以将标签设置为每次用户滑动时都有适当的 X/Y 坐标。但是当我运行以下代码时,我似乎无法通过 css 选择器获得对个人拇指的引用。
我关注了this post,但这只用了一个拇指,因此很容易参考。您如何在我的上下文中正确使用 CSS 选择器,或者如果我的有缺陷,有什么更好的方法?
控制器
public class SliderDemoController implements Initializable
@FXML
private RangeSlider range;
@Override
public void initialize(URL location, ResourceBundle resources)
Pane thumb = (Pane) range.lookup(".range-slider .low-thumb");
System.out.println(thumb); // <-- Prints null
主要
public class SliderDemoMain extends Application
public static void main(String[] args)
launch(args);
@Override
public void start(Stage initStage) throws IOException
FXMLLoader loader = new FXMLLoader(Drag.class.getClassLoader().getResource("sliderdemo.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root);
Stage primaryStage = new Stage();
primaryStage.setTitle("Slider Demo");
primaryStage.setScene(scene);
primaryStage.show();
styleMain.css
.range-slider .range-bar
-fx-background-color: grey;
.range-slider .low-thumb
//....
.range-slider .high-thumb
//....
sliderdemo.fxml 的顶行
<HBox fx:id="menuBar" maxHeight="-Infinity" minHeight="-Infinity" prefHeight="79.0" stylesheets="@styleMain.css" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.propertydrop.SliderDemoController">
【问题讨论】:
【参考方案1】:要使 CSS 查找正常工作,您需要应用 CSS、制作布局通道以及成为场景一部分的节点。 (请注意您引用的帖子中的这一点,答案中的代码在执行查找之前会仔细执行这些步骤。)
这在控制器中很难实现,因为initialize()
方法通常在将 FXML 中的根节点添加到场景之前调用。您可以通过观察节点的sceneProperty()
来破解它,并在它设置为非空值时做出响应。 (是的,这有点骇人听闻……):
public class SliderDemoController implements Initializable
@FXML
private RangeSlider range;
@Override
public void initialize(URL location, ResourceBundle resources)
ChangeListener<Scene> initializer = new ChangeListener<Scene>()
@Override
public void changed(ObservableValue<? extends Scene> obs, Scene oldScene, Scene newScene)
if (newScene != null)
range.applyCss();
range.getParent().layout();
Pane thumb = (Pane) range.lookup(".range-slider .low-thumb");
System.out.println(thumb); // <-- No longer null
range.sceneProperty().removeListener(this);
;
range.sceneProperty().addListener(initializer);
根据您的具体要求,您也许可以避免一些不那么难看的事情,例如在事件处理程序或滑块的 highValue
或 lowValue
属性上的侦听器中执行查找。
【讨论】:
就个人而言,我不认为这是一种黑客行为。我只能说这是必要的,因为 API 没有提供开箱即用的“快捷方式”。很高兴甚至有解决方案:) @Jai 这是一个 hack :)。做你想做的事情的“API-正确”方法是为RangeSlider
创建一个新皮肤,其中包括你想要显示的标签。然而,由于(目前)皮肤类不公开,这将涉及重新发明***并且需要大量工作。
@James_D,只要这个 hack 在商业环境中是可靠的,我就可以接受美学。你已经回答了我的问题,谢谢。在range.lowValueProperty().addListener
中执行查找确实足够了。 +1以上是关于如何单独引用 RangeSlider 的每个拇指 (ControlsFX)的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 中制作这个自定义 RangeSlider?