3

I have this editable JavaFX table for editing data:

public class DataTable {

    public void initTable(Stage primaryStage, Group root, Scene scene) {

        tableView.setEditable(true);
        Callback<TableColumn, TableCell> cellFactory =
                new Callback<TableColumn, TableCell>() {
            @Override
            public TableCell call(TableColumn p) {
                return new EditingCell();
            }
        };

        TableColumn columnMonth = new TableColumn("Month");
        columnMonth.setCellValueFactory(
                new PropertyValueFactory<Record, String>("fieldMonth"));

        TableColumn columnValue = new TableColumn("Value");
        columnValue.setCellValueFactory(
                new PropertyValueFactory<Record, Double>("fieldValue"));

        //--- Add for Editable Cell of Value field, in Double
        columnValue.setCellFactory(cellFactory);
        columnValue.setOnEditCommit(
                new EventHandler<TableColumn.CellEditEvent<Record, Double>>() {
            @Override
            public void handle(TableColumn.CellEditEvent<Record, Double> t) {
                ((Record) t.getTableView().getItems().get(
                        t.getTablePosition().getRow())).setFieldValue(t.getNewValue());
            }
        });
        //---

        tableView.setItems(dataList);
        tableView.getColumns().addAll(columnMonth, columnValue);

        VBox vBox = new VBox();
        vBox.setSpacing(10);
        vBox.getChildren().add(tableView);
        vBox.setLayoutX(410);
        vBox.setLayoutY(34);

        root.getChildren().add(vBox);


    }

    public class Record {

        private SimpleStringProperty fieldMonth;
        private SimpleDoubleProperty fieldValue;

        Record(String fMonth, double fValue) {
            this.fieldMonth = new SimpleStringProperty(fMonth);
            this.fieldValue = new SimpleDoubleProperty(fValue);
        }

        public String getFieldMonth() {
            return fieldMonth.get();
        }

        public double getFieldValue() {
            return fieldValue.get();
        }

        public void setFieldMonth(String fMonth) {
            fieldMonth.set(fMonth);
        }

        public void setFieldValue(Double fValue) {
            fieldValue.set(fValue);
        }
    }
    private TableView<Record> tableView = new TableView<>();
    private ObservableList<Record> dataList =
            FXCollections.observableArrayList(
            new Record("January", 100),
            new Record("February", 200),
            new Record("March", 50),
            new Record("April", 75),
            new Record("May", 110),
            new Record("June", 300),
            new Record("July", 111),
            new Record("August", 30),
            new Record("September", 75),
            new Record("October", 55),
            new Record("November", 225),
            new Record("December", 99));

    class EditingCell extends TableCell<Record, Double> {

        private TextField textField;

        public EditingCell() {
        }

        @Override
        public void startEdit() {
            super.startEdit();

            if (textField == null) {
                createTextField();
            }

            setGraphic(textField);
            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            textField.selectAll();
        }

        @Override
        public void cancelEdit() {
            super.cancelEdit();

            setText(String.valueOf(getItem()));
            setContentDisplay(ContentDisplay.TEXT_ONLY);
        }

        @Override
        public void updateItem(Double item, boolean empty) {
            super.updateItem(item, empty);

            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                if (isEditing()) {
                    if (textField != null) {
                        textField.setText(getString());
                    }
                    setGraphic(textField);
                    setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                } else {
                    setText(getString());
                    setContentDisplay(ContentDisplay.TEXT_ONLY);
                }
            }
        }

        private void createTextField() {
            textField = new TextField(getString());
            textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
            textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
                @Override
                public void handle(KeyEvent t) {
                    if (t.getCode() == KeyCode.ENTER) {
                        commitEdit(Double.parseDouble(textField.getText()));
                    } else if (t.getCode() == KeyCode.ESCAPE) {
                        cancelEdit();
                    }
                }
            });
        }

        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }
    }
}

I have to create small program which can display data from database tables and edit the tables. I came to this problem when I click on a table I have to generate dynamic table view from JPA object, so I have every time one table but with different columns. Can I somehow generate every time table with the data from JPA and update columns automatically based on the case?

3
  • you want to resize the table columns ? Commented Apr 23, 2013 at 19:30
  • I want to change the number of the columns based of the number of Java object attributes. Commented Apr 23, 2013 at 19:38
  • you need to study the java reflection API. Commented Apr 23, 2013 at 19:44

1 Answer 1

7

You can use Reflection to achieve that. For example, parse methods of your data class and create column for each one which ends with Property:

public class SmartTableView extends Application {

    private void populateColumns(Class clazz, TableView table) {
        for (Method method : clazz.getMethods()) {
            String name = method.getName();
            if (name.endsWith("Property")) {
              String propName = name.replace("Property", "");

              TableColumn column = new TableColumn(propName);
              column.setCellValueFactory(new PropertyValueFactory<>(propName));
              table.getColumns().add(column);
            }
        }
    }

    @Override
    public void start(Stage primaryStage) {
        final ObservableList<Person> data = FXCollections.observableArrayList(
                new Person("Jacob", "Smith", "[email protected]"),
                new Person("Isabella", "Dow", "[email protected]"),
                new Person("Ethan", "Williams", "[email protected]"),
                new Person("Emma", "Jones", "[email protected]"),
                new Person("Michael", "Brown", "[email protected]"));

        TableView table = new TableView(data);
        populateColumns(Person.class, table);

        Scene scene = new Scene(table, 300, 250);
        primaryStage.setTitle("Hello");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

    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 StringProperty firstNameProperty() {
            return firstName;
        }

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

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

        public StringProperty lastNameProperty() {
            return lastName;
        }

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

        public void setEmail(String fName) {
            email.set(fName);
        }

        public StringProperty emailProperty() {
            return lastName;
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.