Reflection 根据数据类信息自动创建TableView列

Reflection 根据数据类信息自动创建TableView列,reflection,javafx-2,Reflection,Javafx 2,我有一个可编辑的JavaFX表用于编辑数据: public class DataTable { public void initTable(Stage primaryStage, Group root, Scene scene) { tableView.setEditable(true); Callback<TableColumn, TableCell> cellFactory = new Callback&

我有一个可编辑的JavaFX表用于编辑数据:

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();
        }
    }
}
公共类数据表{
公共void initTable(舞台主舞台、组根、场景){
tableView.setEditable(true);
回叫手机工厂=
新回调函数(){
@凌驾
公共TableCell调用(TableP列){
返回新的EditingCell();
}
};
TableColumn columnMonth=新的TableColumn(“月份”);
columnMonth.setCellValueFactory(
新物业价值工厂(“现场月”);
TableColumn columnValue=新的TableColumn(“值”);
columnValue.setCellValueFactory(
新的PropertyValueFactory(“fieldValue”);
//---添加值字段的可编辑单元格,双精度
columnValue.setCellFactory(cellFactory);
columnValue.setOnEditCommit(
新的EventHandler(){
@凌驾
公共无效句柄(TableColumn.CellEditEvent t){
((记录)t.getTableView().getItems().get(
t、 getTablePosition().getRow()).setFieldValue(t.getNewValue());
}
});
//---
tableView.setItems(数据列表);
tableView.getColumns().addAll(columnMonth,columnValue);
VBox VBox=新的VBox();
vBox.setspace(10);
vBox.getChildren().add(tableView);
vBox.setLayoutX(410);
vBox.setLayoutY(34);
root.getChildren().add(vBox);
}
公开课记录{
私人SimpleStringProperty fieldMonth;
私有SimpleDoubleProperty字段值;
记录(字符串fMonth,双fValue){
this.fieldMonth=新的SimpleStringProperty(fMonth);
this.fieldValue=新的SimpleDoubleProperty(fValue);
}
公共字符串getFieldMonth(){
return fieldMonth.get();
}
公共双getFieldValue(){
返回fieldValue.get();
}
公共无效setFieldMonth(字符串fMonth){
fieldMonth.set(每月一次);
}
公共无效setFieldValue(双fValue){
fieldValue.set(fValue);
}
}
private TableView TableView=new TableView();
私有可观察列表数据列表=
FXCollections.observableArrayList(
新纪录(100年1月),
新纪录(二零零零年二月),,
新纪录(“三月”,50),
新纪录(75年4月),,
新纪录(110年5月),
新纪录(“六月”,300),
新纪录(111年7月),
新纪录(八月三十日),,
新纪录(75年9月),
新纪录(55年10月),,
新纪录(225年11月),
新纪录(一九九九年十二月);;
类EditingCell扩展了TableCell{
私有文本字段文本字段;
公共编辑单元(){
}
@凌驾
公开作废已启动IT(){
super.startEdit();
if(textField==null){
createTextField();
}
设置图形(文本字段);
setContentDisplay(仅限ContentDisplay.GRAPHIC_);
textField.selectAll();
}
@凌驾
公共作废取消编辑(){
super.cancelEdit();
setText(String.valueOf(getItem());
setContentDisplay(仅限ContentDisplay.TEXT_);
}
@凌驾
public void updateItem(双项,布尔空){
super.updateItem(项,空);
if(空){
setText(空);
设置图形(空);
}否则{
if(isEditing()){
if(textField!=null){
setText(getString());
}
设置图形(文本字段);
setContentDisplay(仅限ContentDisplay.GRAPHIC_);
}否则{
setText(getString());
setContentDisplay(仅限ContentDisplay.TEXT_);
}
}
}
私有void createTextField(){
textField=newtextfield(getString());
textField.setMinWidth(this.getWidth()-this.getGraphicTextGap()*2);
setOnKeyPressed(新的EventHandler(){
@凌驾
公共无效句柄(KeyEvent t){
if(t.getCode()==KeyCode.ENTER){
committedit(Double.parseDouble(textField.getText());
}else if(t.getCode()==KeyCode.ESCAPE){
取消编辑();
}
}
});
}
私有字符串getString(){
返回getItem()==null?”:getItem().toString();
}
}
}

我必须创建一个小程序,它可以显示数据库表中的数据并编辑这些表。当我点击一个表时,我遇到了这个问题,我必须从JPA对象生成动态表视图,所以每次我都有一个表,但有不同的列。我是否可以用JPA的数据生成每个时间表,并根据情况自动更新列?

您可以使用反射来实现这一点。例如,解析数据类的方法,并为每个方法创建以
属性
结尾的列:

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", "jacob.smith@example.com"),
                new Person("Isabella", "Dow", "isabella.dow@example.com"),
                new Person("Ethan", "Williams", "ethan.williams@example.com"),
                new Person("Emma", "Jones", "emma.jones@example.com"),
                new Person("Michael", "Brown", "michael.brown@example.com"));

        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;
        }
    }
}
公共类SmartTableView扩展应用程序{
私有void populateColumns(类clazz,表视图表){
for(方法:clazz.getMethods()){
String name=method.getName();
如果(名称.endsWith(“属性”)){
字符串propName=name.replace(“属性”,“属性”);
TableColumn=新的TableColumn(propName);
column.setCellValueFactory(新属性ValueFactory(propName));
table.getColumns().add(列);
}
}
}
@凌驾
公众假期开始(阶段)