JavaFX中如何避免重复添加VBox并实现数量递增?
实现已有订单项递增数量的解决方案
你的核心问题是找到对应节点后,没有获取到它的OrderItemController实例来调用addProduct()方法。这里提供两种可行的解决方式:
方式一:通过VBox的userData关联控制器
步骤1:修改addProductToOrder方法
在加载订单项时把控制器实例绑定到VBox的userData,找到匹配节点后直接取出调用方法:
private void addProductToOrder(String id, String name, String price){ for (Node node : order.getChildren()){ if (Objects.equals(node.getId(), id)) { // 取出关联的控制器并调用递增方法 if (node.getUserData() instanceof OrderItemController) { ((OrderItemController) node.getUserData()).addProduct(); } return; } } FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/com/luxrest/gui/components/orderItem.fxml")); try { VBox item = fxmlLoader.load(); OrderItemController controller = fxmlLoader.getController(); controller.setData(id, name, price); item.setId(id); // 将控制器绑定到VBox的userData item.setUserData(controller); order.getChildren().add(item); }catch (IOException e){ e.printStackTrace(); } }
方式二:用Map维护ID与控制器的映射(性能更优)
如果订单项数量较多,遍历节点效率偏低,可以维护一个Map来存储ID和对应控制器的关系,避免循环遍历:
步骤1:在DashboardController中定义Map成员变量
private Map<String, OrderItemController> orderItemControllerMap = new HashMap<>();
步骤2:修改addProductToOrder方法
private void addProductToOrder(String id, String name, String price){ // 直接从Map查找对应控制器 OrderItemController existingController = orderItemControllerMap.get(id); if (existingController != null) { existingController.addProduct(); return; } // 不存在则加载新订单项并存入Map FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/com/luxrest/gui/components/orderItem.fxml")); try { VBox item = fxmlLoader.load(); OrderItemController controller = fxmlLoader.getController(); controller.setData(id, name, price); item.setId(id); order.getChildren().add(item); orderItemControllerMap.put(id, controller); }catch (IOException e){ e.printStackTrace(); } }
两种方式都能实现需求:当屏幕上已存在对应ID的订单项时,直接调用addProduct()递增数量,而不会新增VBox。第二种方式无需遍历节点,在数据量大时性能表现更好。
内容的提问来源于stack exchange,提问作者Sérgio Serra
相关产品推荐
相关产品推荐

