【问题标题】:Synchronizing two scroll bars JavaFX同步两个滚动条JavaFX
【发布时间】:2017-10-04 11:14:14
【问题描述】:

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

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

问题是我注意到bar1 的最大值是1.0bar2 的最大值是102.5。因此,问题是,当我滚动bar2 时,bar1 移动很多,因为它们的值存在很大差异。在绑定 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;
        }
    }
}

【问题讨论】:

  • 请提供一个可运行的示例来演示该问题(请参阅stackoverflow.com/help/how-to-ask
  • 另见“如何创建minimal reproducible example”。
  • 看起来缩放比例不同:在 scrollPane 中它被标准化为 max = 1.0 而在 tableView 中它是原始像素。奇怪的是,允许将该值设置为任何值......但在实际滚动时重置:因此,如果您滚动表格,则窗格立即处于其上限(1.0),如果您滚动窗格,表格立即处于其上限下限(非常接近 0.0)
  • 忘了提及解决方案;)您不能使用双向绑定,但需要两个属性的侦听器,缩放值并将其设置为另一个
  • @kleopatra 你能想出可行的解决方案吗?太棒了,可以发在这里吗?我尝试使用 scrollbar1.valueproperty().addlistener 然后使用 lambda 表达式,然后分别通过乘法和除法对其进行缩放,但它不起作用并导致了一些溢出问题。

标签: javafx scrollbar


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2018-09-05
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 2012-05-06
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多