JavaFX问题:无法通过Pagination的createPage()方法更新Label内容
JavaFX场景数据传递问题:点击编辑按钮更新目标Label内容
问题描述
我正在学习JavaFX,近期发布过相关帖子。目前遇到的问题:
- 在
editScene场景中有一个Label,希望根据点击的编辑按钮更新它的内容 displayScene场景里有带ListView的Pagination,每个列表项包含Label和两个按钮(其中一个是编辑按钮)- 点击编辑按钮时,想把当前列表项Label的内容显示到
editScene的Label上,但无法实现 - 只能在
initialize()方法中更新Label,但该方法无法访问选中的item - 尝试用成员变量存储选中的item,在
initialize()中判断是否为null并赋值给Label,但该变量在initialize()里始终为null(尽管点击按钮后通过输出能看到变量包含所需数据)
另外说明:很快会替换ListView,目前被这个问题缠住。
提供的代码片段
displayScene控制器的initialize方法
@FXML public void initialize(){ //input for schedule inputOutput = new InputOutput(); schedule = inputOutput.inputSchedule(); Collections.sort(schedule); //set mainView = mainImage mainView.setImage(mainImage); //set up display pages displayPagination.setPageCount((int)Math.ceil((double) schedule.size()/maxPerPage)); displayPagination.setPageFactory(this::createPage); }
场景切换方法
@FXML public void switchToEditScene(ActionEvent event) throws IOException{ root = FXMLLoader.load(getClass().getResource("editScene.fxml")); stage = (Stage)((Node)event.getSource()).getScene().getWindow(); scene = new Scene(root); scene.getStylesheets().add(css); stage.setScene(scene); stage.show(); }
Pagination页面创建方法
@FXML public Node createPage(int pageIndex){ ListView<Event> eventView = new ListView<>(); int fromIndex = pageIndex * maxPerPage; int toIndex = Math.min(fromIndex + maxPerPage, schedule.size()); List<Event> eventString = schedule.subList(fromIndex, toIndex); //testing buttons eventView.setCellFactory(param -> new ListCell<Event>(){ @Override protected void updateItem(Event item, boolean empty){ super.updateItem(item,empty); if(empty || item == null){ setText(null); setGraphic(null); } else{ Label label = new Label(item.display()); Button editButton = new Button ("Edit"); Button completedButton = new Button ("Completed"); Label test = new Label(item.display()); editLabel = test; editButton.setOnAction(event ->{ edittedTask = item; try{ switchToEditScene(event); } catch(IOException e){ e.printStackTrace(); } }); completedButton.setOnAction(event ->{ System.out.println("done"); System.out.println(item); }); HBox eventHbox = new HBox(label); HBox buttonHbox = new HBox(editButton,completedButton); buttonHbox.setSpacing(50); buttonHbox.setAlignment(Pos.CENTER_RIGHT); HBox.setMargin(buttonHbox,new Insets(0,0,0,400)); HBox hbox = new HBox(eventHbox,buttonHbox); setGraphic(hbox); } } }); ObservableList<Event> observableEventList = FXCollections.observableArrayList((eventString)); eventView.setItems(observableEventList); return eventView; } @FXML public void handlePreviousPage(){ if(currentPage > 0){ currentPage--; displayPagination.setCurrentPageIndex(currentPage); } } @FXML public void handleNextPage(){ if(currentPage < displayPagination.getPageCount()-1){ currentPage++; displayPagination.setCurrentPageIndex(currentPage); } }
解决方案
核心问题
之前的方法失败是因为场景加载顺序:调用FXMLLoader.load()时,editScene的控制器会立即执行initialize()方法,此时选中的edittedTask还未传递到控制器,导致initialize()中变量为null。正确做法是先加载FXML获取控制器实例,再手动传递数据并更新UI。
步骤1:修改editScene控制器
在editScene的控制器中添加接收数据的方法,不要在initialize()中处理数据:
public class EditSceneController { @FXML private Label targetLabel; // 对应editScene中需要更新的Label // 外部调用此方法传递数据并更新Label public void setEventData(Event event) { if (event != null) { targetLabel.setText(event.display()); } } }
步骤2:修改场景切换方法
创建FXMLLoader实例,加载FXML后获取控制器,再传递选中的Event对象:
@FXML public void switchToEditScene(ActionEvent event) throws IOException{ FXMLLoader loader = new FXMLLoader(getClass().getResource("editScene.fxml")); root = loader.load(); // 加载FXML文件 // 获取editScene的控制器实例 EditSceneController editController = loader.getController(); // 传递选中的任务数据 if (edittedTask != null) { editController.setEventData(edittedTask); } stage = (Stage)((Node)event.getSource()).getScene().getWindow(); scene = new Scene(root); scene.getStylesheets().add(css); stage.setScene(scene); stage.show(); }
步骤3:确认成员变量作用域
确保edittedTask是displayScene控制器的成员变量(不是局部变量):
// 在displayScene控制器类中定义 private Event edittedTask;
内容的提问来源于stack exchange,提问作者Wyatt Cake
相关产品推荐
相关产品推荐

