JavaFX中TableView选中预约行后打开对应详情表单的问题
问题:JavaFX右键菜单点击无反应,无法根据预约类型打开对应表单
我用JavaFX开发GUI,表格里有两种预约类型,对应不同的visitTypeId。数据初始化和表格列配置代码如下:
现有代码
数据初始化
ObservableList<IAppointmentModel> initialData() { IAppointmentModel apt1 = new IAppointmentModel("10/31/2023", "Test Apt 1", 1, "Dr. Smith"); IAppointmentModel apt2 = new IAppointmentModel("2/8/2023", "Test Apt 2", 2, "Dr. Smith"); return FXCollections.<IAppointmentModel>observableArrayList(apt1, apt2); }
表格列配置
aptData.setCellValueFactory(new PropertyValueFactory<IAppointmentModel, String>("aptDate")); referringMd.setCellValueFactory(new PropertyValueFactory<IAppointmentModel, String>("referringMd")); visitType.setCellValueFactory(new PropertyValueFactory<IAppointmentModel, String>("visitType")); tableView.setItems(initialData());
用户右键点击预约行时,会弹出带“View Details”选项的上下文菜单,需求是点击该选项后根据预约类型打开对应表单(比如Test Apt 1打开FormA,Test Apt 2打开FormB)。但我尝试了两种实现,点击后均无反应:
尝试的两种无效实现
第一种(基于visitTypeId判断)
viewButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { IAppointmentModel item = tableView.getSelectionModel().getSelectedItem(); try { if(item.equals(visitTypeId.equals(1))){ Parent popUp; popUp = FXMLLoader.load(Objects.requireNonNull(GaitApplication.class.getResource("Visits/VisitDetailsGait.fxml"))); Stage stage1 = new Stage(); stage1.setTitle("GAIT Visit Details: "); stage1.setScene(new Scene(popUp, 800, 680)); stage1.show(); }else if(item.equals(visitTypeId.equals(2))){ Parent popUp; popUp = FXMLLoader.load(Objects.requireNonNull(GaitApplication.class.getResource("Visits/VisitDetailsUE.fxml"))); Stage stage1 = new Stage(); stage1.setTitle("UE Visit Details: "); stage1.setScene(new Scene(popUp, 800, 680)); stage1.show(); } } catch (IOException e) { throw new RuntimeException(e); } } });
第二种(基于visitType文本判断)
viewButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { IAppointmentModel item = tableView.getSelectionModel().getSelectedItem(); try { if(item.equals(visitType.getText().equals("Test Apt 1"))){ Parent popUp; popUp = FXMLLoader.load(Objects.requireNonNull(GaitApplication.class.getResource("Visits/FormA.fxml"))); Stage stage1 = new Stage(); stage1.setTitle("GAIT Visit Details: "); stage1.setScene(new Scene(popUp, 800, 680)); stage1.show(); }else if(item.equals(visitType.getText().equals("Test Apt 2"))){ Parent popUp; popUp = FXMLLoader.load(Objects.requireNonNull(GaitApplication.class.getResource("Visits/FormB.fxml"))); Stage stage1 = new Stage(); stage1.setTitle("UE Visit Details: "); stage1.setScene(new Scene(popUp, 800, 680)); stage1.show(); } } catch (IOException e) { throw new RuntimeException(e); } } });
问题分析与修正方案
两种实现的核心错误都是条件判断逻辑错误:
- 第一种中
item.equals(visitTypeId.equals(1))是将IAppointmentModel对象和布尔值(visitTypeId.equals(1)的返回结果)比较,永远不会相等,条件永远不触发。 - 第二种中
item.equals(visitType.getText().equals("Test Apt 1"))同样是对象和布尔值比较,且visitType.getText()获取的是表格列本身的文本,而非选中行的预约类型文本。
修正后的代码(基于visitTypeId判断)
假设IAppointmentModel类有getVisitTypeId()方法获取预约类型ID:
viewButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { IAppointmentModel item = tableView.getSelectionModel().getSelectedItem(); // 先判断选中项是否为空 if (item == null) { return; } try { Parent popUp; Stage stage1 = new Stage(); if(item.getVisitTypeId() == 1){ popUp = FXMLLoader.load(Objects.requireNonNull(GaitApplication.class.getResource("Visits/VisitDetailsGait.fxml"))); stage1.setTitle("GAIT Visit Details: "); } else if(item.getVisitTypeId() == 2){ popUp = FXMLLoader.load(Objects.requireNonNull(GaitApplication.class.getResource("Visits/VisitDetailsUE.fxml"))); stage1.setTitle("UE Visit Details: "); } else { // 处理未知类型,可提示或直接返回 return; } stage1.setScene(new Scene(popUp, 800, 680)); stage1.show(); } catch (IOException e) { throw new RuntimeException(e); } } });
修正后的代码(基于visitType文本判断)
假设IAppointmentModel类有getVisitType()方法获取预约类型名称:
viewButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { IAppointmentModel item = tableView.getSelectionModel().getSelectedItem(); if (item == null) { return; } try { Parent popUp; Stage stage1 = new Stage(); String visitTypeName = item.getVisitType(); if("Test Apt 1".equals(visitTypeName)){ popUp = FXMLLoader.load(Objects.requireNonNull(GaitApplication.class.getResource("Visits/FormA.fxml"))); stage1.setTitle("GAIT Visit Details: "); } else if("Test Apt 2".equals(visitTypeName)){ popUp = FXMLLoader.load(Objects.requireNonNull(GaitApplication.class.getResource("Visits/FormB.fxml"))); stage1.setTitle("UE Visit Details: "); } else { return; } stage1.setScene(new Scene(popUp, 800, 680)); stage1.show(); } catch (IOException e) { throw new RuntimeException(e); } } });
额外注意事项:
- 必须确保
IAppointmentModel类提供了对应的getter方法(如getVisitTypeId()、getVisitType()),否则PropertyValueFactory无法正常工作,同时修正后的代码也无法获取对应属性。 - 添加了选中项为空的判断,避免空指针异常。
- 可根据实际需求补充未知预约类型的处理逻辑。
内容的提问来源于stack exchange,提问作者Kameron
相关产品推荐
相关产品推荐

