Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly add new data to TableView and scroll to it

Problem

I want to add data dynamically to a TableView and scroll to the new data's position. But when the rows in the TableView reach the ViewPort size, I get this in the console:

Apr 18, 2015 9:14:34 AM com.sun.javafx.scene.control.skin.VirtualFlow addTrailingCells INFO: index exceeds maxCellCount. Check size calculations for class javafx.scene.control.TableRow

So I guess I did something wrong. All I did was using the Oracle TableView example and add this:

// button to add new data
Button bt = new Button( "Add");
bt.setOnAction(e -> {

    // insert new item
    int i = data.size() + 1;
    Person person = new Person( "Name " + i, "Name " + i, "Mail " + i);
    data.add( person);

    // scroll to new item
    table.scrollTo( person);

});

The same happens when you use

    table.getItems().add( person);

instead of modifying the list.

The culprit is the scrollTo method. The same info/error occurs when you use the row index with the scrollTo method.

Question

How do you add new items correctly to a TableView, so that the info/error doesn't show up?

Code

Here's a full example. The table is pre-filled. If you hit the Add button the viewport size is reached and the info (or error?) is displayed in the console.

public class TableViewSample extends Application {

    private TableView<Person> table = new TableView<Person>();
    private final ObservableList<Person> data = FXCollections.observableArrayList();

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

    @Override
    public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setTitle("Table View Sample");
        stage.setWidth(450);
        stage.setHeight(500);

        table.setEditable(true);

        TableColumn firstNameCol = new TableColumn("First Name");
        firstNameCol.setMinWidth(100);
        firstNameCol.setCellValueFactory(
                new PropertyValueFactory<Person, String>("firstName"));

        TableColumn lastNameCol = new TableColumn("Last Name");
        lastNameCol.setMinWidth(100);
        lastNameCol.setCellValueFactory(
                new PropertyValueFactory<Person, String>("lastName"));

        TableColumn emailCol = new TableColumn("Email");
        emailCol.setMinWidth(200);
        emailCol.setCellValueFactory(
                new PropertyValueFactory<Person, String>("email"));

        table.setItems(data);
        table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);

        // -------------------------------
        // dynamically add data
        // -------------------------------

        // fill table with data
        for( int i=0; i < 14; i++) {
            Person person = new Person( "Name " + i, "Name " + i, "Mail " + i);
            data.add( person);
        }

        // button to add new data
        Button bt = new Button( "Add");
        bt.setOnAction(e -> {

            // insert new item
            int i = data.size() + 1;
            Person person = new Person( "Name " + i, "Name " + i, "Mail " + i);
            data.add( person);

            // scroll to new item
            table.scrollTo( person);

        });

        // -------------------------------

        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.getChildren().addAll(table, bt);

        ((Group) scene.getRoot()).getChildren().addAll(vbox);

        stage.setScene(scene);
        stage.show();


    }

    public static class Person {

        private final SimpleStringProperty firstName;
        private final SimpleStringProperty lastName;
        private final SimpleStringProperty email;

        private Person(String fName, String lName, String email) {
            this.firstName = new SimpleStringProperty(fName);
            this.lastName = new SimpleStringProperty(lName);
            this.email = new SimpleStringProperty(email);
        }

        public String getFirstName() {
            return firstName.get();
        }

        public void setFirstName(String fName) {
            firstName.set(fName);
        }

        public String getLastName() {
            return lastName.get();
        }

        public void setLastName(String fName) {
            lastName.set(fName);
        }

        public String getEmail() {
            return email.get();
        }

        public void setEmail(String fName) {
            email.set(fName);
        }
    }
} 
like image 383
Roland Avatar asked Apr 18 '15 07:04

Roland


1 Answers

I solved this problem using fixed cells..

listCategory.setFixedCellSize(40); 

or

-fx-fixed-cell-size : 40;
like image 79
Gleidson Neves da Silveira Avatar answered Oct 24 '22 20:10

Gleidson Neves da Silveira