Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX: How to refresh table?

Tags:

java

javafx

I have problem with refresh rows styles in JavaFX TableView.

java version "1.8.0_51"

Java(TM) SE Runtime Environment (build 1.8.0_51-b16)

Java HotSpot(TM) Server VM (build 25.51-b03, mixed mode)

Logic:

  1. Load data to tableView.
  2. Set new styles to rows by setRowFactory.
  3. Load new data to table.
  4. Refresh styles for new table rows. (Not working for me.)

How to reload styles for rows?

My code snippet:

import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Callback;

public class RowFactoryAndOptimisationDemo extends Application {

        VBox root;

        public ObservableList<RFDDomain> data = FXCollections.observableArrayList();
        public TableView<RFDDomain> tableView = new TableView<RFDDomain>();

    @Override
    public void start(Stage stage) throws Exception {
                root = new VBox();
        root.autosize();
        Scene scene = new Scene(root, Color.LINEN);

        stage.setTitle("Row Factory Demo");
        stage.setWidth(500);
        stage.setHeight(300);
        stage.setScene(scene);
        stage.show();

        configureTable();
    }

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

        private void recheck_table() {
            tableView.setRowFactory(new Callback<TableView<RFDDomain>, TableRow<RFDDomain>>() {
            @Override
            public TableRow<RFDDomain> call(TableView<RFDDomain> paramP) {
                    return new TableRow<RFDDomain>() {

                            @Override
                            protected void updateItem(RFDDomain paramT, boolean paramBoolean) {

                                super.updateItem(paramT, paramBoolean);
                                if (!isEmpty()) {
                                    String style = "-fx-control-inner-background: #007F0E;"
                            + "-fx-control-inner-background-alt: #007F0E;";
                                    setStyle(style);
                                }
                            }
                    };
            }
    });
        }



    @SuppressWarnings("unchecked")
    private void configureTable() {
        int id =1;
        for (int i = 1; i <= 1; i++) {
            data.add(new RFDDomain(id++,"First Row", "This is for check.", 1));
            data.add(new RFDDomain(id++,"Second Row", null, 2));
            data.add(new RFDDomain(id++,"Third Row", "This is for check.", 3));
            data.add(new RFDDomain(id++,"Fourth Row", "dil", 4));
        }

        tableView.setItems(data);
                recheck_table();


        TableColumn<RFDDomain, Integer> column0 = new TableColumn<RFDDomain, Integer>("Id");
        column0.setCellValueFactory(new PropertyValueFactory<RFDDomain, Integer>("id"));

        TableColumn<RFDDomain, String> column1 = new TableColumn<RFDDomain, String>("Title");
        column1.setCellValueFactory(new PropertyValueFactory<RFDDomain, String>("name"));

        TableColumn<RFDDomain, String> column2 = new TableColumn<RFDDomain, String>("Description");
        column2.setCellValueFactory(new PropertyValueFactory<RFDDomain, String>("description"));

        TableColumn<RFDDomain, Number> column3 = new TableColumn<RFDDomain, Number>("Status");
        column3.setPrefWidth(55);
        column3.setCellValueFactory(new PropertyValueFactory<RFDDomain, Number>("status"));

        TableColumn<RFDDomain, String> column4 = new TableColumn<RFDDomain, String>("Action");
        column4.setCellValueFactory(new PropertyValueFactory<RFDDomain, String>("name"));

        tableView.getColumns().addAll(column0, column1, column2, column3, column4);

        this.root.getChildren().add(tableView);

                Button button1 = new Button("Load new Data");

                button1.setOnAction(new EventHandler<ActionEvent>() {
                    @Override public void handle(ActionEvent e) {
                        data.clear();
                        data.removeAll(data);
                        data.add(new RFDDomain(1,"First Row", "This is for check.", 1));
                        data.add(new RFDDomain(2,"Second Row", null, 2));
                        tableView.setItems(data);
                        recheck_table();
                    }
                });

                this.root.getChildren().add(button1);


    }

    /**
     * Domain Model for this demo.
     */
    public class RFDDomain {
        private SimpleIntegerProperty id = new SimpleIntegerProperty();
        private SimpleStringProperty name = new SimpleStringProperty();
        private SimpleStringProperty description = new SimpleStringProperty();
        private SimpleIntegerProperty status = new SimpleIntegerProperty();

        public RFDDomain(int id,String name, String desc, int status) {
            this.id.set(id);
            this.name.set(name);
            this.description.set(desc);
            this.status.set(status);
        }

        public int getId() {
            return id.get();
        }

        public SimpleIntegerProperty idProperty() {
            return id;
        }

        public String getDescription() {
            return description.get();
        }

        public SimpleStringProperty descriptionProperty() {
            return description;
        }

        public String getName() {
            return name.get();
        }

        public SimpleStringProperty nameProperty() {
            return name;
        }

        public int getStatus() {
            return status.get();
        }

        public SimpleIntegerProperty statusProperty() {
            return status;
        }
    }
}
like image 298
stdex Avatar asked Aug 15 '15 17:08

stdex


2 Answers

Try tableView.refresh(). It's available in JavaFX since Java 8u60.

like image 131
Ruslan Gabbazov Avatar answered Oct 13 '22 03:10

Ruslan Gabbazov


Probably no longer relevant, but simply add

else { setStyle(null) }

to the updateItem method in your custom factory - what's happening is that only as many cells are created as are absolutely required to show on the screen (prevents creating unnecessarily many UI elements). These cells are re-used when you scroll through the table by their updateItem method. Sometimes (in your case), an existing cell will be updated with null to indicate the cell should be empty. You haven't implemented this case, but you should, and you should clear the cell's style.

like image 44
RDM Avatar answered Oct 13 '22 03:10

RDM