javafxtableviewsimple-framework

JavaFX TableView with simple xml model


For configuration I use simple xml. I also use this model for TableView. My problem is using of boolean. TableView needs BooleanProperty but simple xml cannot access to this object, obviously. How can I combine this without write big code?

Model

@Root(name="scriptdata")
@Order(elements={"title", "active"})
public class ScriptData {
    @Element (required=true)
    private String title;
    @Element (required=false)
    private BooleanProperty active;

    /**
     *
     * @param title
     * @param active
     */
     public ScriptData() {
        this.active = new SimpleBooleanProperty(active);
     }


    public boolean isActive() {
        return active.getValue();
    }

    public void setActive(boolean active) {
        this.active.set(active);
    }

CellFactory

modulActiveColumn.setCellValueFactory(new PropertyValueFactory<>("active"));
modulActiveColumn.setCellFactory(CheckBoxTableCell.forTableColumn(modulActiveColumn));
modulActiveColumn.setOnEditCommit((EventHandler<CellEditEvent>) t -> {
    ((ScriptData) t.getTableView().getItems().get(
      t.getTablePosition().getRow())
      ).setActive((boolean) t.getNewValue());
}


Solution

  • My problem is using of boolean. TableView needs BooleanProperty

    You're wrong. In fact the TableView never gains access to the BooleanProperty object stored in the active field of it's items.

    PropertyValueFactory uses reflection to

    1. Access a property object by invoking a method with the constructor parameter concatenated with "Property". (This method would be called activeProperty() in your case).
    2. If the above doesn't work it wraps the value returned by a the getter for the property in a ObservableValue. (The name of the getter in this case is getActive() or isActive).

    In your case the cellValueFactory does something similar to the following factory

    modulActiveColumn.setCellValueFactory(cellData -> new SimpleBooleanProperty(cellData.getValue().isActive()));
    

    Using a boolean field to store the data achieves exactly the same result in your case. The drawback of this approach is that programatic updates of the property do not trigger an update of the TableView and the edits need to be handled manually.

    @Root(name="scriptdata")
    @Order(elements={"title", "active"})
    public class ScriptData {
        @Element (required=true)
        private String title;
        @Element (required=false)
        private boolean active;
    
        /**
         *
         * @param title
         * @param active
         */
        public ScriptData() {
        }
    
        public boolean isActive() {
            return active;
        }
    
        public void setActive(boolean active) {
            this.active = active;
        }
    }