在我将表格 (TableView) 功能添加到代码中之前,我的按钮运行良好,但现在一旦单击相同的按钮,就会出现错误。如果我在 RoomsController
中注释掉这行代码,错误就会消失并且按钮可以工作:
intRoomIDColVR.setCellValueFactory(new PropertyValueFactory<>("roomID"));
vachRoomTypeIDColVR.setCellValueFactory(new PropertyValueFactory<>("roomTypeID"));
roomTableViewVR.setItems(olRoomData);
FXML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.codetech.hotelmis.controller.RoomsController">
<children>
<BorderPane prefHeight="338.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<center>
<Accordion BorderPane.alignment="CENTER">
<panes>
<TitledPane fx:id="accVacant" animated="false" text="Vacant Rooms">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<BorderPane prefHeight="324.0" prefWidth="598.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<center>
<TableView fx:id="roomTableViewVR" BorderPane.alignment="CENTER">
<columns>
<TableColumn fx:id="intRoomIDColVR" prefWidth="75.0" text="Room ID" />
<TableColumn fx:id="vachRoomTypeIDColVR" prefWidth="115.00000762939453" text="Room Type" />
<TableColumn fx:id="reservedColVR" prefWidth="94.0" text="Reserved?" />
<TableColumn fx:id="resCustomerColVR" prefWidth="95.0" text="Customer " />
</columns>
</TableView>
</center>
<top>
<HBox>
<children>
<Button fx:id="btnCheckInPopUp" mnemonicParsing="false" text="Check In" BorderPane.alignment="CENTER" />
</children>
</HBox>
</top>
</BorderPane>
</children>
</AnchorPane>
</content>
</TitledPane>
<TitledPane fx:id="accOccupied" animated="false" text="Occupied Rooms">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<BorderPane prefHeight="324.0" prefWidth="598.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<top>
<HBox>
<children>
<Button fx:id="btnTabCheckOut" mnemonicParsing="false" text="Check Out" BorderPane.alignment="CENTER" />
</children>
</HBox>
</top>
<center>
<TableView BorderPane.alignment="CENTER">
<columns>
<TableColumn fx:id="intRoomIDColOR" prefWidth="75.0" text="Room ID" />
<TableColumn fx:id="vachRoomTypeIDColOR" prefWidth="115.00000762939453" text="Room Type" />
<TableColumn fx:id="occupantColOR" prefWidth="83.0" text="Occupant" />
<TableColumn fx:id="checkInDateColOR" prefWidth="121.0" text="Check In Date" />
<TableColumn fx:id="checkOutDateColOR" prefWidth="181.99996948242188" text="Expected Check Out Date" />
</columns>
</TableView>
</center>
</BorderPane>
</children>
</AnchorPane>
</content>
</TitledPane>
</panes>
</Accordion>
</center>
<top>
<HBox prefHeight="24.0" prefWidth="600.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="btnNewRoom" mnemonicParsing="false" text="New Room" />
<Button fx:id="btnEditRoom" mnemonicParsing="false" text="Edit Room" />
<Button fx:id="btnNewRoomType" mnemonicParsing="false" text="New Room Type" />
<Button fx:id="btnEditRoomType" mnemonicParsing="false" text="Edit Room Type" />
<Button fx:id="btnGuestLog" mnemonicParsing="false" text="Guest Log" />
</children>
</HBox>
</top>
</BorderPane>
</children>
</AnchorPane>
Controller 类:
public class RoomsController implements Initializable {
@FXML
private TableView<RoomData> roomTableViewVR;
@FXML
private TableColumn<RoomData, Integer> intRoomIDColVR;
@FXML
private Button btnCheckInPopUp;
@FXML
private TableColumn<RoomData, String> vachRoomTypeIDColVR;
//Declare ObservableList
private ObservableList<RoomData> olRoomData;
private ActionEvent event;
private static Connection con;
private static ResultSet rs;
private static java.sql.Statement stmt;
private static String sql;
JavaToMySQL javaToMySQL = new JavaToMySQL();
public RoomsController() {
try {
con = DatabaseConnection.getConnected();
stmt = con.createStatement();
olRoomData = FXCollections.observableArrayList();
rs = con.createStatement().executeQuery("SELECT * FROM h_r_rooms");
while (rs.next()){
olRoomData.add(new RoomData(rs.getInt("intRoomID"),rs.getString("vachRoomTypeID")));
}
} catch (SQLException e) {
e.printStackTrace();
System.out.println("Error on Building Data");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
@Override
public void initialize(URL location, ResourceBundle resources) {
listeners();
intRoomIDColVR.setCellValueFactory(new PropertyValueFactory<>("roomID"));
vachRoomTypeIDColVR.setCellValueFactory(new PropertyValueFactory<>("roomTypeID"));
roomTableViewVR.setItems(olRoomData);
}
void listeners(){
btnCheckInPopUp.setOnAction((event -> {
System.out.println("I'm supposed to pop out a Check In window when you click me!");
Stage stage;
if (event.getSource()== btnCheckInPopUp){
stage = new Stage();
try {
Parent root = FXMLLoader.load(getClass().getResource("../view/popups/check_in.fxml"));
System.out.println("I work!");
stage.setScene(new Scene(root));
stage.setTitle("Check Customer In");
stage.initModality(Modality.APPLICATION_MODAL);
stage.initOwner(btnCheckInPopUp.getScene().getWindow());
stage.showAndWait();
} catch (IOException e) {
e.printStackTrace();
}
}
}));
}
}
当我单击“ checkin ”(btnCheckInPopUp
) 时,出现以下错误:
The Connection is open!
javafx.fxml.LoadException:
/home/mush/Programming/Dev/InteliJProjects/Hotel_MIS/out/production/Hotel_MIS/com/codetech/hotelmis/view/popups/check_in.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2605)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2583)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2445)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3218)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3179)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3152)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3128)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3108)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3101)
at com.codetech.hotelmis.controller.RoomsController.lambda$listeners$0(RoomsController.java:87)
at com.codetech.hotelmis.controller.RoomsController$$Lambda$104/1394020985.handle(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8390)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3758)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3486)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2495)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:350)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$350(GlassViewEventHandler.java:385)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$252/507580015.get(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:404)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:384)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:927)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$null$48(GtkApplication.java:139)
at com.sun.glass.ui.gtk.GtkApplication$$Lambda$43/1166661505.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at com.codetech.hotelmis.controller.RoomsController.initialize(RoomsController.java:74)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
... 70 more
我真的很想找出原因,但没有成功。我非常感谢您的帮助,我将提供有关解决问题所需的代码的更多详细信息。
问题here 看起来和我的很相似。
最佳答案
看来您正在为两个不同的 FXML 文件使用相同的 Controller 类。不要这样做:为每个 FXML 使用不同的 Controller 。
当调用 FXMLLoader
的 load()
方法时,它会执行以下操作(稍微简化的描述):
- 读取 FXML 文件
- 如果 FXML 文件指定 Controller 类,它将通过调用其无参数构造函数来创建 Controller 类的新实例
- 基于 FXML 元素创建对象层次结构
- 在元素上设置事件处理程序,映射到第 1 步中创建的 Controller 类实例
- 对于具有
fx:id
属性的元素,它将相应的对象注入(inject)到 Controller 实例中任何匹配的@FXML
注释引用中 - 在 Controller 实例上调用
initialize()
(如果存在此类方法)。 - 返回与 FXML 文件的根元素对应的对象。
在您的情况下,您有两个指定相同 Controller 类的 FXML 文件。当加载“主”FXML 文件时,就会发生上述过程。创建 RoomsController
的第一个实例,注入(inject)其与 fx:id
匹配的 @FXML
注释字段(包括 intRoomIDColVR
code> 等),注册事件处理程序,并调用 initialize()
方法。此时一切都很好。
当按下 btnCheckInPopup
按钮时,将调用其 onAction
处理程序。这会导致 check_in.fxml
被加载。由于这指定了相同的 Controller 类,因此将创建该类的第二个实例。注入(inject)与 check_in.fxml
元素相对应的 @FXML
注释字段以及匹配的 fx:id
。但请注意,由于 check_in.fxml
未使用 fx_id="intRoomIDColVR"
定义任何元素,因此此时 intRoomIDColVR
未初始化 Controller 实例。然后在第二个 Controller 实例上调用 initialize()
方法,并且由于 intRoomIDColVR
未初始化,这会导致 NullPointerException
行
intRoomIDColVR.setCellValueFactory(new PropertyValueFactory<>("roomID"));
这是一个很好的例子,说明了为什么每个 FXML 应该有自己的 Controller 类。如果您像这样“共享” Controller 类,那么在任何给定时间以及对于该类的任何特定实例,跟踪哪些字段已初始化、哪些字段未初始化将变得非常困难。
关于java - 当我在initialize()方法中添加TableView功能时按钮停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30198712/