繁体   English   中英

从Oracle DB检索数据的javaFX TableView中的格式化日期列

[英]Formatting Date Column in javaFX TableView for Data retrieved from Oracle DB

我按照这篇文章对日期格式进行了组合,但是遇到了java.lang.NullPointerException

控制器类别:

这是我的代码:FXML文件:

    <AnchorPane id="AnchorPane" prefHeight="864.0" prefWidth="1090.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.60" fx:controller="idehmis.controller.PersonController">
    <children>
        <BorderPane layoutX="418.0" layoutY="159.0" prefHeight="705.0" prefWidth="1090.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="159.0">
            <center>
                <TableView fx:id="personTable" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
                    <columns>
                        <TableColumn prefWidth="75.0" text="C1" />
                        <TableColumn prefWidth="75.0" text="C2" />
                    </columns>
                </TableView>
            </center>
        </BorderPane>
        <JFXTextField fx:id="Pmrn" layoutX="49.0" layoutY="43.0" maxWidth="117.0" minWidth="106.0" nodeOrientation="LEFT_TO_RIGHT" prefColumnCount="8" prefHeight="31.0" prefWidth="117.0" promptText="MRN" unFocusColor="#0f098a">
        </JFXTextField>
        <JFXTextField fx:id="Plastname" layoutX="47.0" layoutY="88.0" maxWidth="121.0" minWidth="106.0" nodeOrientation="LEFT_TO_RIGHT" prefColumnCount="8" prefHeight="31.0" prefWidth="117.0" promptText="Last Name" unFocusColor="#190879">
        </JFXTextField>
        <JFXDatePicker fx:id="Pdateofbirth" layoutX="210.0" layoutY="43.0" prefHeight="31.0" prefWidth="201.0" promptText="Date Of Birth" />
        <Button fx:id="getAllData" layoutX="573.0" layoutY="30.0" mnemonicParsing="false" onAction="#SubmitButton" text="Retrieve data" />
    </children>
</AnchorPane>

这是个人类:

public class Person {

    public final StringProperty mrn;
    public final StringProperty lastname;
    //public final StringProperty dateofbirth;
    public ObjectProperty<LocalDate> dateofbirth = new SimpleObjectProperty<>();

    public Person() {
        this.mrn = new SimpleStringProperty();
        this.lastname = new SimpleStringProperty();
        //this.dateofbirth = new SimpleStringProperty();
        this.dateofbirth = new SimpleObjectProperty<>();
    }

    public String getMRN() {
        return mrn.get();
    }

    public void setMRN(String mrn) {
        this.mrn.set(mrn);
    }

    public StringProperty mrnProperty() {
        return mrn;
    }

    public String getLarstName() {
        return lastname.get();
    }

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

    public StringProperty lastNameProperty() {
        return lastname;
    }

    public Object getDateOfBirth() {
        return dateofbirth.get();
    }

    public void setDateOfBirth(LocalDate dateofbirth) {
        this.dateofbirth.set(dateofbirth);
    }

    public ObjectProperty<LocalDate> dateOfBirthProperty() {
        return dateofbirth;
    }
}

这是控制器:

    public class PersonController implements Initializable {

    @FXML
    private TableView<Person> personTable;
    @FXML
    private JFXTextField Pmrn;
    @FXML
    private JFXTextField Plastname;
    @FXML
    private JFXDatePicker Pdateofbirth;
    @FXML
    private ObservableList<Person> data;
    @FXML
    private Button getAllData;
    @FXML
    TableColumn<Person, String> MRN;
    @FXML
    TableColumn<Person, String> LASTNAME;
    @FXML
    TableColumn<Person, LocalDate> DATEOFBIRTH;
    SimpleDateFormat sdf = new SimpleDateFormat("dd,MMM,yyyy", Locale.getDefault());

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        DATEOFBIRTH.setCellValueFactory(new PropertyValueFactory<>("dateOfBirth"));
        DATEOFBIRTH.setCellFactory(new PersonController.ColumnFormatter<>(DateTimeFormatter.ofPattern("MM/dd/yyyy")));
    }
    @FXML
    void SubmitButton(ActionEvent event) {
        if (event.getSource() == getAllData) {
            try {
                populatetData();
            } catch (Exception ex) {
                out.println(ex);
            }
        }
    }
    private class ColumnFormatter<S, T> implements Callback<TableColumn<S, T>, TableCell<S, T>> {

        private final DateTimeFormatter format;

        public ColumnFormatter(DateTimeFormatter format) {
            super();
            this.format = format;
        }

        @Override
        public TableCell<S, T> call(TableColumn<S, T> arg0) {
            return new TableCell<S, T>() {
                @Override
                protected void updateItem(T item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item == null || empty) {
                        setGraphic(null);
                    } else {
                        LocalDate ld = (LocalDate) item;
                        String val = ld.format(format);
                        setGraphic(new Label(val));
                    }
                }
            };
        }
    }

    @SuppressWarnings("Convert2Lambda")
    public void populatetData() throws Exception {
        Connection conn = null;
        Person pt = new Person();
        conn = DBConnection.getConnection();
        String SQL;
        Person p = new Person();
        try {
            conn = DBConnection.getConnection();
            data = FXCollections.observableArrayList();
            SQL = "SELECT MRN, LASTNAME, DATEOFBIRTH FROM " + "HIVP.PATIENT";
            out.println(SQL);
            ResultSet rs = conn.createStatement().executeQuery(SQL);
            if (rs != null) {
                while (rs.next()) {
                    p.setMRN(rs.getString(1));
                    p.setLastName(rs.getString(2));
                    Date x = rs.getDate(3);
                    if (x != null) {
                        p.setDateOfBirth(rs.getDate(3).toLocalDate());
                    } else {
                        p.setDateOfBirth(LocalDate.MIN);
                    }
                    data.addAll(p);
                }
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        personTable.setItems(data);
                    }
                });
            }
        } catch (Exception e) {
            out.println("ERROR GETTING DATA: " + e);
        } finally {
            if (conn != null) {
                DBConnection.closeConnection((OracleConnection) conn);
            }
        }
    }
}


Exception in Application start method
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javafx.fxml.LoadException: 
file:/C:/Users/abayazids15/Documents/NetBeansProjects/IDEHMIS/dist/run1719879236/IDEHMIS.jar!/idehmis/view/Person.fxml
file:/C:/Users/abayazids15/Documents/NetBeansProjects/IDEHMIS/dist/run1719879236/IDEHMIS.jar!/idehmis/view/mainApplication.fxml:66

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.access$2700(FXMLLoader.java:103)
    at javafx.fxml.FXMLLoader$IncludeElement.constructValue(FXMLLoader.java:1143)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:746)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
    at idehmis.IDEHMIS.start(IDEHMIS.java:21)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    ... 1 more
Caused by: java.lang.NullPointerException
    at idehmis.controller.PersonController.initialize(PersonController.java:58)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
    ... 23 more
Exception running application idehmis.IDEHMIS
Java Result: 1

我做错了什么来获取NullPointException。 请帮助。谢谢

您只是忘记了将ID放入您的列中...它必须像这样:

<TableColumn fx:id="MRN" prefWidth="75.0" text="C1" />
<TableColumn fx:id="LASTNAME" prefWidth="75.0" text="C2" />

没有它们,由于FXMLLoader在fxml文件中找不到匹配的(按ID)字段,因此“ initialize”方法中的MRN字段将保持“ null”。 在我看来,尽管两个字段的名称仅因大小写而不同(例如,在您的代码中,例如TextField“ mrn”和TableColumn“ MRN”),但确实令人困惑。

此外,您的数据模型和方法populateData也存在问题:

  • 首先,您的TableView应该是Person类型,而不是List类型:Person是Table将保存的数据类型。 因此,TableColumns应该声明为TableColumn
  • 其次,您必须确定是要使用FXML还是要使用Java代码。 您已经在表中有了列(通过FXML),但是在populateData方法中您将其清除,然后尝试再次添加。 如果您事先知道这些列,则只需使用FXML并将populateData方法的这一部分切掉
  • 第三,当您读取从数据库获得的结果时,应该为每一行创建一个Person对象,然后将该对象添加到数据列表中。 像这样:

      while (rs.next()) { Person p = new Person(); p.setMRN(rs.getString(1)); p.setLastName(rs.getString(2)); Date x = rs.getDate(3); if (x != null) { p.setDateOfBirth(rs.getDate(3).toLocalDate()); } else { p.setDateOfBirth(LocalDate.MIN); } data.add(p); } 

尝试使用调试器跟踪代码,这将有助于您理解。

至于日期格式,我建议使用DateTimeFormatter:

DATEOFBIRTH.setCellValueFactory(new PropertyValueFactory<>("dateOfBirth"));
DATEOFBIRTH.setCellFactory(new PersonController.ColumnFormatter<>(DateTimeFormatter.ofPattern("MM/dd/yyyy")));

并以这种方式修改ColumnFormatter:

private class ColumnFormatter<S, T> implements Callback<TableColumn<S, T>, TableCell<S, T>> {

    private final DateTimeFormatter format;

    public ColumnFormatter(DateTimeFormatter format) {
        super();
        this.format = format;
    }

    @Override
    public TableCell<S, T> call(TableColumn<S, T> arg0) {
        return new TableCell<S, T>() {
            @Override
            protected void updateItem(T item, boolean empty) {
                super.updateItem(item, empty);
                if (item == null || empty) {
                    setGraphic(null);
                } else {
                    LocalDate ld = (LocalDate) item;
                    String val = ld.format(format);
                    setGraphic(new Label(val));
                }
            }
        };
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM