在将表(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>
控制器类:
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();
}
}
}));
}
}
当我单击“签入(
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文件使用相同的控制器类。不要这样做:为每个FXML使用不同的控制器。
调用FXMLLoader
的load()
方法时,它将执行以下操作(略有简化的描述):
读取FXML文件
如果FXML文件指定了控制器类,它将通过调用其无参数构造函数来创建控制器类的新实例。
基于FXML元素创建对象层次结构
在元素上设置事件处理程序,映射到在步骤1中创建的控制器类实例
对于具有fx:id
属性的元素,它将相应的对象注入控制器实例中任何匹配的带有@FXML
注释的引用中
如果存在这样的方法,请在控制器实例上调用initialize()
。
返回与FXML文件的根元素相对应的对象。
在您的情况下,您有两个FXML文件指定了相同的控制器类。加载“主” FXML文件时,将发生上述过程。创建RoomsController
的第一个实例,将其与@FXML
匹配的fx:id
注释字段注入(包括intRoomIDColVR
和其他),注册事件处理程序,并调用initialize()
方法。此时一切都很好。
按下btnCheckInPopup
按钮时,将调用其onAction
处理程序。这将导致check_in.fxml
被加载。由于这指定了相同的控制器类,因此将创建该类的第二个实例。注入与匹配的@FXML
的check_in.fxml
元素相对应的fx:id
注释字段。但是,请注意,由于check_in.fxml
没有使用fx_id="intRoomIDColVR"
定义任何元素,因此不会为第二个控制器实例初始化intRoomIDColVR
。然后,在第二个控制器实例上调用initialize()
方法,并且由于未初始化intRoomIDColVR
,因此在该行上导致NullPointerException
intRoomIDColVR.setCellValueFactory(new PropertyValueFactory<>("roomID"));
这是一个很好的例子,确切地说明了为什么每个FXML应该具有自己的控制器类。如果您像这样“共享”控制器类,就很难跟踪哪些字段已初始化以及哪些字段在给定时间没有初始化,对于该类的任何特定实例,这非常困难。