将两个tableviews绑定在一起,以便它们同步滚动

我想将两个tableviews绑定在一起,以便它们同步滚动。 我怎么做? 我无法找到如何访问tableview的滚动条。

我已经制作了一个CSS hack来将Tableview绑定到外部滚动条。 一个滚动条控制两个tableviews。

我的想法概述:

  • 创建两个tableviews
  • 制作一个垂直滚动条。 在这个例子中,我们称之为myScrollbar
  • 将myScrollbar的min和max设置为min = 0,max = TableView.Items.size()
  • 当myScrollbar的值更改时,然后调用tableview的scrollTo(int)函数
  • 禁用使用CSS实现的tableview的本机垂直滚动条。

这将为您提供两个表,两个表都由一个外部滚动条(myScrollbar)控制。

这是使用css隐藏tableview滚动条的代码:

/* The main scrollbar **track** CSS class */ .mytableview .scroll-bar:vertical .track{ -fx-padding:0px; -fx-background-color:transparent; -fx-border-color:transparent; -fx-background-radius: 0em; -fx-border-radius:2em; } /* The increment and decrement button CSS class of scrollbar */ .mytableview .scroll-bar:vertical .increment-button , .mytableview .scroll-bar:vertical .decrement-button { -fx-background-color:transparent; -fx-background-radius: 0em; -fx-padding:0 0 0 0; } .mytableview .scroll-bar:vertical .increment-arrow, .mytableview .scroll-bar:vertical .decrement-arrow { -fx-shape: " "; -fx-padding:0; } /* The main scrollbar **thumb** CSS class which we drag every time (movable) */ .mytableview .scroll-bar:vertical .thumb { -fx-background-color:transparent; -fx-background-insets: 0, 0, 0; -fx-background-radius: 2em; -fx-padding:0px; } 

然后我们需要设置如何使用滚动条滚动tableview。

 scroll.setMax(100); //make sure the max is equal to the size of the table row data. scroll.setMin(0); scroll.valueProperty().addListener(new ChangeListener(){ @Override public void changed(ObservableValue ov, Number t, Number t1) { //Scroll your tableview according to the table row index table1.scrollTo(t1.intValue()); table2.scrollTo(t1.intValue()); } }); 

http://blog.ngopal.com.np/2012/09/25/how-to-bind-vertical-scroll-in-multi-tableview/

我认为目前不可能。 TableViewSkininheritance自VirtualContainerBase,后者具有VirtualFlow字段。 VirtualFlow对象有两个VirtualScrollBar字段,hbar和vbar,这就是你所追求的。 虽然我看不到任何方法。

有趣的是,TableView中还有一个私有的contentWidth字段,尽管这是私有的。 我确信JFX团队对开放太多的API非常谨慎,这是可以理解的。 您可以要求将contentWidth字段作为int属性打开,作为JFX JIRA或openjfx-dev邮件列表上的function请求。

停止间隔度量将绑定表视图选择模型的所选项或索引属性。

我发现解决问题的最简单方法是绑定隐藏滚动条的可见值valueProperty。

 // Controller @FXML private TableView tableLeft; @FXML private TableView tableRight; @FXML private ScrollBar scrollBar; @SuppressWarnings("rawtypes") private void bindScrollBars(TableView tableView1, TableView tableView2, ScrollBar scrollBar, Orientation orientation) { // Get the scrollbar of first table VirtualFlow vf = (VirtualFlow)tableView1.getChildrenUnmodifiable().get(1); ScrollBar scrollBar1 = null; for (final Node subNode: vf.getChildrenUnmodifiable()) { if (subNode instanceof ScrollBar && ((ScrollBar)subNode).getOrientation() == orientation) { scrollBar1 = (ScrollBar)subNode; } } // Get the scrollbar of second table vf = (VirtualFlow)tableView2.getChildrenUnmodifiable().get(1); ScrollBar scrollBar2 = null; for (final Node subNode: vf.getChildrenUnmodifiable()) { if (subNode instanceof ScrollBar && ((ScrollBar)subNode).getOrientation() == orientation) { scrollBar2 = (ScrollBar)subNode; } } // Set min/max of visible scrollbar to min/max of a table scrollbar scrollBar.setMin(scrollBar1.getMin()); scrollBar.setMax(scrollBar1.getMax()); // bind the hidden scrollbar valueProterty the visible scrollbar scrollBar.valueProperty().bindBidirectional(scrollBar1.valueProperty()); scrollBar.valueProperty().bindBidirectional(scrollBar2.valueProperty()); } /* * This method must be called in Application.start() after the stage is shown, * because the hidden scrollbars exist only when the tables are rendered */ public void setScrollBarBinding() { bindScrollBars(this.tableLeft, this.tableRight, this.scrollBar, Orientation.VERTICAL); } 

现在,您必须在显示阶段并呈现表之后从Application调用绑定:

 // Application private MyController controller; @Override public void start(Stage primaryStage) { try { FXMLLoader fxmlLoader = new FXMLLoader(SalesApp.class.getResource("scene.fxml")); BorderPane root = (BorderPane) fxmlLoader.load();; Scene scene = new Scene(root); scene.getStylesheets().add(getClass().getResource("app.css").toExternalForm()); primaryStage.setScene(scene); primaryStage.show(); controller = (MyController) fxmlLoader.getController(); controller.setScrollBarBinding(); } catch(Exception e) { e.printStackTrace(); } } 

现在表格应该通过鼠标,键或滚动条同步滚动。

玩得开心,奥拉夫