You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

天气项目中从其他控制器接收数据后无刷新更新场景的方法

Hey there! Let's figure out how to get your selected cities from the modal EnterCityDocument window into the main ListView without reloading the scene—JavaFX has some great built-in tools for this, so let's break down two straightforward approaches:

Approach 1: Use a Callback Interface (Most Explicit)

This method lets you define a clear contract for passing data between controllers. We'll create a callback interface that the MainController implements, then pass that implementation to the modal controller. When the user clicks "Select", the modal triggers the callback to send the selected cities back.

First, define the callback interface (you can put this in its own file or inside one of the controllers):

public interface CitySelectionCallback {
    void onCitiesSelected(List<String> selectedCities);
}

Next, update your MainController to implement this interface, and pass itself to the modal when opening it:

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.List;

public class MainController implements CitySelectionCallback {
    @FXML
    private ListView<String> cityListView;
    // ObservableList automatically updates the UI when modified
    private ObservableList<String> cityList = FXCollections.observableArrayList();

    @FXML
    public void initialize() {
        // Bind the ListView to our ObservableList
        cityListView.setItems(cityList);
    }

    @FXML
    private void onAddButtonClicked(ActionEvent event) {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("EnterCityDocument.fxml"));
            Parent modalRoot = loader.load();

            EnterCityDocumentController modalController = loader.getController();
            // Pass the callback implementation to the modal controller
            modalController.setSelectionCallback(this);

            // Set up and show the modal window
            Stage modalStage = new Stage();
            modalStage.initModality(Modality.APPLICATION_MODAL);
            modalStage.initOwner(((javafx.scene.Node) event.getSource()).getScene().getWindow());
            modalStage.setScene(new Scene(modalRoot));
            modalStage.showAndWait();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onCitiesSelected(List<String> selectedCities) {
        // Add the selected cities to our ObservableList—UI updates automatically!
        cityList.addAll(selectedCities);
    }
}

Now update the EnterCityDocumentController to use the callback:

import javafx.fxml.FXML;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
import java.util.List;

public class EnterCityDocumentController {
    @FXML
    private ListView<String> modalCityListView;
    private CitySelectionCallback selectionCallback;

    // Method to set the callback from the main controller
    public void setSelectionCallback(CitySelectionCallback callback) {
        this.selectionCallback = callback;
    }

    @FXML
    private void onSelectButtonClicked() {
        List<String> selectedCities = modalCityListView.getSelectionModel().getSelectedItems();
        if (selectionCallback != null && !selectedCities.isEmpty()) {
            // Trigger the callback to send data back to MainController
            selectionCallback.onCitiesSelected(selectedCities);
            // Close the modal window
            ((Stage) modalCityListView.getScene().getWindow()).close();
        }
    }
}

Approach 2: Share an ObservableList (More Concise)

If you don't need the extra structure of a callback, you can directly pass the MainController's ObservableList to the modal controller. Since the ListView is bound to this list, any changes will immediately reflect in the UI.

Modify the onAddButtonClicked method in MainController:

@FXML
private void onAddButtonClicked(ActionEvent event) {
    try {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("EnterCityDocument.fxml"));
        Parent modalRoot = loader.load();

        EnterCityDocumentController modalController = loader.getController();
        // Pass the main's ObservableList directly to the modal
        modalController.setMainCityList(cityList);

        Stage modalStage = new Stage();
        modalStage.initModality(Modality.APPLICATION_MODAL);
        modalStage.initOwner(((javafx.scene.Node) event.getSource()).getScene().getWindow());
        modalStage.setScene(new Scene(modalRoot));
        modalStage.showAndWait();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Then update EnterCityDocumentController to use the shared list:

import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
import java.util.List;

public class EnterCityDocumentController {
    @FXML
    private ListView<String> modalCityListView;
    private ObservableList<String> mainCityList;

    public void setMainCityList(ObservableList<String> mainCityList) {
        this.mainCityList = mainCityList;
    }

    @FXML
    private void onSelectButtonClicked() {
        List<String> selectedCities = modalCityListView.getSelectionModel().getSelectedItems();
        if (mainCityList != null && !selectedCities.isEmpty()) {
            // Add directly to the shared ObservableList—UI updates instantly
            mainCityList.addAll(selectedCities);
            ((Stage) modalCityListView.getScene().getWindow()).close();
        }
    }
}

Key Note

The magic here is JavaFX's ObservableList—it's designed to notify bound UI components (like your ListView) whenever its contents change. That means you never have to manually refresh the scene or reload the FXML; updating the list is all you need to do.

内容的提问来源于stack exchange,提问作者Kian Park

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:10:41