Свързване на два таблични изгледа заедно, така че да превъртат в синхрон

Искам да свържа два таблични изгледа заедно, така че да превъртат в синхрон. Как да направя това? Не мога да разбера как да осъществя достъп до лентата за превъртане на изглед на таблица.


person user1684679    schedule 20.09.2012    source източник


Отговори (3)


Направих CSS хак за свързване на Tableview с външна лента за превъртане. Една лента за превъртане контролира и двата изгледа на таблици.

Преглед на моята идея:

  • Създайте два таблични изгледа
  • Направете една вертикална лента за превъртане. Нека го наречем myScrollbar в този пример
  • Задайте min и max на myScrollbar на размер min=0, max=TableView.Items.size()
  • Когато стойността на myScrollbar се промени, извикайте функцията scrollTo(int) на двата tableview
  • Деактивирайте естествената вертикална лента за превъртане на табличния изглед, внедрен с CSS.

Това ще ви даде две таблици, и двете контролирани от една външна лента за превъртане (myScrollbar).

Ето кода за скриване на лентата за превъртане на изглед на таблица с помощта на css:

/* 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;

}

След това трябва да зададем как да превъртаме табличния изглед с помощта на лентата за превъртане.

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/

person privatejava    schedule 24.09.2012
comment
Решението изглежда страхотно. Напишете го като публикация, така че да се архивира при препълване на стека и аз ще ви дам наградата. - person The Unfun Cat; 25.09.2012

Не мисля, че в момента това е възможно. TableViewSkin наследява от VirtualContainerBase, който има поле VirtualFlow. Обектът VirtualFlow има две полета VirtualScrollBar, hbar и vbar, което е това, което търсите. Въпреки това не виждам начин да стигна до него.

Интересното е, че има и частно поле contentWidth в TableView, въпреки че това е частно. Сигурен съм, че екипът на JFX е изключително предпазлив относно отварянето на твърде много от API, което е разбираемо. Можете да поискате полето contentWidth да се отвори като свойство int като заявка за функция в пощенския списък на JFX JIRA или openjfx-dev.

Мярка за прекъсване на пропуска би била обвързването на избрания елемент или свойство на индекс на модела за избор на изгледи на таблица.

person Andy Till    schedule 22.09.2012
comment
Благодаря за приноса. Какъв е обичаят за приемане на отрицателни отговори? Нямам представа дали наистина е невъзможно или не - и доказването му със сигурност е невъзможно. Ще изчака поне още шест дни. - person The Unfun Cat; 22.09.2012

Най-лесният начин, който открих за разрешаване на проблема, е да обвържа valueProperty на видимите и скритите ленти за превъртане.

// Controller 
@FXML private TableView<MyBean> tableLeft;
@FXML private TableView<MyBean> 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();
        }
    }

Сега таблиците трябва да се превъртат синхронно чрез мишка, клавиш или лента за превъртане.

Забавлявай се, Олаф

person olaf    schedule 08.11.2014