【问题标题】:How to Individually Reference Each Thumb of a RangeSlider (ControlsFX)如何单独引用 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">

【问题讨论】:

    标签: javafx rangeslider controlsfx


    【解决方案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);
        }
    }
    

    根据您的具体要求,您也许可以避免一些不那么难看的事情,例如在事件处理程序或滑块的 highValuelowValue 属性上的侦听器中执行查找。

    【讨论】:

    • 就个人而言,我不认为这是一种黑客行为。我只能说这是必要的,因为 API 没有提供开箱即用的“快捷方式”。很高兴甚至有解决方案:)
    • @Jai 这是一个 hack :)。做你想做的事情的“API-正确”方法是为 RangeSlider 创建一个新皮肤,其中包括你想要显示的标签。然而,由于(目前)皮肤类不公开,这将涉及重新发明轮子并且需要大量工作。
    • @James_D,只要这个 hack 在商业环境中是可靠的,我就可以接受美学。你已经回答了我的问题,谢谢。在range.lowValueProperty().addListener 中执行查找确实足够了。 +1
    猜你喜欢
    • 1970-01-01
    • 2015-04-27
    • 2016-09-14
    • 2020-11-02
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多