javafx - 同步两个滚动条JavaFX

标签 javafx scrollbar

我的问题是我有两个水平滚动条,我希望它们同时滚动,我试过使用:

bar1.valueProperty().bindBidirectional(bar2.valueProperty());

问题是我注意到 bar1 的最大值是 1.0bar2 的最大值是 102.5。因此,问题是,当我滚动 bar2 时,bar1 由于它们的值存在很大差异而移动了很多。在绑定(bind) value 属性之前,我尝试使用 setMinsetMaxsetUnitIncrementsetBlockIncrement。但这是行不通的。

public class DynamicTableView extends Application {
    private Scene scene;
    private VBox root;
    private ScrollPane scPane;
    private static final int N_COLS = 10;
    private static final int N_ROWS = 10;
    private Button button;

    public void start(Stage stage) throws Exception {

        root = new VBox();
        scPane = new ScrollPane();
        Label lbl = new Label("Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table");
        scPane.setContent(lbl);

        root.getChildren().add(scPane);

        TestDataGenerator dataGenerator = new TestDataGenerator();

        TableView<ObservableList<String>> tableView = new TableView<>();

        // add columns
        List<String> columnNames = dataGenerator.getNext(N_COLS);
        for (int i = 0; i < columnNames.size(); i++) {
            final int finalIdx = i;
            TableColumn<ObservableList<String>, String> column = new TableColumn<>(
                    columnNames.get(i)
            );
            column.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue().get(finalIdx)));
            tableView.getColumns().add(column);
        }

        // add data
        for (int i = 0; i < N_ROWS; i++) {
            tableView.getItems().add(
                    FXCollections.observableArrayList(
                            dataGenerator.getNext(N_COLS)
                    )
            );
        }

        root.getChildren().add(tableView);

        tableView.setPrefHeight(200);

        button = new Button("Delete");
        button.setOnAction(event -> { tableView.getItems().clear();});

        root.getChildren().add(button);

        Scene scene = new Scene(root, 600, 600);
        stage.setScene(scene);
        stage.show();

        for(Node node1: scPane.lookupAll(".scroll-bar"))
        {
            if(node1 instanceof ScrollBar)
            {
                ScrollBar scrollBar1 = (ScrollBar)node1;
                if(scrollBar1.getOrientation() == Orientation.HORIZONTAL)
                {
                    for(Node node2: tableView.lookupAll(".scroll-bar"))
                    {
                        if(node2 instanceof ScrollBar)
                        {
                            ScrollBar scrollBar2 = (ScrollBar)node2;
                            if(scrollBar2.getOrientation() == Orientation.HORIZONTAL)
                            {
                                scrollBar2.valueProperty().bindBidirectional(scrollBar1.valueProperty());
                                break;
                            }
                        }
                    }
                }
            }
        }

    }

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

    private static class TestDataGenerator {
        private static final String[] LOREM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tempus cursus diam ac blandit. Ut ultrices lacus et mattis laoreet. Morbi vehicula tincidunt eros lobortis varius. Nam quis tortor commodo, vehicula ante vitae, sagittis enim. Vivamus mollis placerat leo non pellentesque. Nam blandit, odio quis facilisis posuere, mauris elit tincidunt ante, ut eleifend augue neque dictum diam. Curabitur sed lacus eget dolor laoreet cursus ut cursus elit. Phasellus quis interdum lorem, eget efficitur enim. Curabitur commodo, est ut scelerisque aliquet, urna velit tincidunt massa, tristique varius mi neque et velit. In condimentum quis nisi et ultricies. Nunc posuere felis a velit dictum suscipit ac non nisl. Pellentesque eleifend, purus vel consequat facilisis, sapien lacus rutrum eros, quis finibus lacus magna eget est. Nullam eros nisl, sodales et luctus at, lobortis at sem.".split(" ");

        private int curWord = 0;

        List<String> getNext(int nWords) {
            List<String> words = new ArrayList<>();

            for (int i = 0; i < nWords; i++) {
                if (curWord == Integer.MAX_VALUE) {
                    curWord = 0;
                }

                words.add(LOREM[curWord % LOREM.length]);
                curWord++;
            }

            return words;
        }
    }
}

最佳答案

scrollPane 中的 scrollBar 的 valueProperty 与 tableView 中的 scrollBar 的 valueProperty 的双向绑定(bind)是不可能的,因为前者是规范化的而后者不是。相反,请手动收听更改和缩放,例如:

protected void bindScrollBarValues(ScrollBar scrollBarInTable, ScrollBar scrollBarInPane) {
    // can't use bidi-binding because bar in scrollPane is normalized, bar in table is not
    // scrollBarInTable.valueProperty().bindBidirectional(scrollBarInPane.valueProperty());
    // scale manually
    scrollBarInTable.valueProperty().addListener((src, ov, nv) -> {
        double tableMax = scrollBarInTable.getMax();
        scrollBarInPane.setValue(nv.doubleValue() / tableMax);
    });

    scrollBarInPane.valueProperty().addListener((src, ov, nv) -> {
        double tableMax = scrollBarInTable.getMax();
        scrollBarInTable.setValue(nv.doubleValue() * tableMax);
    });
}

关于javafx - 同步两个滚动条JavaFX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46563432/

相关文章:

JavaFX - 居中覆盖 BorderPane 的 BackgroundImage

delphi - 如果控件在表单滚动时定位,为什么它们会位于错误的位置?

html - 如何防止 IE10 中的滚动条覆盖内容?

html - 将父元素居中,直到到达左上角,然后停止居中并显示滚动条?

css - 鼠标悬停在文本区域滚动条上会提供文本光标而不是默认光标

java - JavaFX 中的默认表模型

带有监听器的 JavaFX TextArea 给出 : “java.lang.IllegalArgumentException: The start must be <= the end”

java - TableView - 编辑焦点单元格

Swing 的 JavaFX 模态窗口所有权

javascript - 滚动条需要一段时间才会出现