【问题标题】:JavaFX static ObservableList not refreshing ComboBoxJavaFX静态ObservableList不刷新组合框
【发布时间】:2019-01-24 16:03:34
【问题描述】:

我想要做的是有一个单独的类来维护一个静态的 ObservableList 国家。我想在 ComboBox 中显示这些国家。我的这部分工作正常。现在,我还想让用户将新国家添加到列表中。因此,组合框旁边有一个按钮,它将显示另一个对话框,允许输入另一个国家/地区名称。用户输入国家名称并单击保存后,我希望单个静态 ObservableList 更新为新国家,然后显示在 ComboBox 中。这部分没有发生。

我将展示哪些有效,哪些无效。

保存对静态列表的引用并对其进行更新。像这样:

public class CustomerController implements Initializable {

    private ObservableList<Country> countryList;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        countryList = Country.getCountryList();
        comboCountry.setItems(countryList);
    }

    ...

    // Fired when clicking the "new country" button
    @FXML
    void handleNewCountry(ActionEvent event) {
        Country country = new Country();
        country.setCountry("Austria");
        countryList.add(country);
    }
}

这是我想做的,但它不起作用:

public class CustomerController implements Initializable {

    @FXML
    private ComboBox<Country> comboCountry;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        comboCountry.setItems(Country.getCountryList());
    }

    @FXML
    void handleNewCountry(ActionEvent event) {
        showScene("Country.fxml", "dialog.newCountry");
    }

    private void showScene(String sceneResource, String titleResource) {
        try {
            FXMLLoader loader = new FXMLLoader(
                    getClass().getResource(sceneResource),
                    resourceBundle
            );
            Scene scene = new Scene(loader.load());
            getNewStage(resourceBundle.getString(titleResource), scene).showAndWait();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private Stage getNewStage(String title, Scene scene) {
        Stage stage = new Stage();
        stage.setTitle(title);
        stage.setResizable(false);
        stage.setScene(scene);
        stage.initOwner(rootPane.getScene().getWindow());
        stage.initModality(Modality.APPLICATION_MODAL);
        return stage;
    }
}

国家类:

public class Country extends BaseModel {
    private int countryID;
    private StringProperty country;
    private static ObservableList<Country> countryList; // The static observable list

    public Country() {
        countryList = FXCollections.observableArrayList();
        country = new SimpleStringProperty();
    }

    public int getCountryID() {
        return countryID;
    }

    public void setCountryID(int countryID) {
        this.countryID = countryID;
    }

    public StringProperty countryProperty() {
        return this.country;
    }

    public String getCountry() {
        return this.country.get();
    }

    public void setCountry(String country) {
        this.country.set(country);
    }

    public boolean equals(Country country) {
        if (this.getCountry().compareToIgnoreCase(country.getCountry()) != 0) {
            return false;
        }
        return true;
    }

    public static ObservableList<Country> getCountryList() {
        if (countryList.size() < 1) {
            updateCountryList();
        }
        return countryList;
    }

    public static void updateCountryList() {
        countryList.clear();
        ArrayList<Country> daoList = CountryDao.listCountries();
        for (Country country : daoList) {
            countryList.add(country);
        }
    }

    @Override
    public String toString()  {
        return this.getCountry();
    }
}

还有进入新国家的对话框:

public class CountryController implements Initializable {
    @FXML
    private TextField textCountry;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
    }    

    @FXML
    void handleSave(ActionEvent event) {
        Country country = new Country();
        country.setCountry(textCountry.getText().trim());
        CountryDao.insert(country); // Insert the country into the database
        Country.updateCountryList(); // Update the static ObservableList
        close();
    }

    @FXML
    void handleCancel() {
        close();
    }

    void close() {
        final Stage stage = (Stage) textCountry.getScene().getWindow();
        stage.close();        
    }
}

所以,我的理论是,当调用 setItems 时,ComboBox 会以某种方式创建 ObservableList 的新实例。不过我真的不确定。一个静态对象应该只有一个实例,所以从任何地方更新它都应该更新那个 ComboBox。有谁知道这是怎么回事?

【问题讨论】:

    标签: javafx combobox observablelist


    【解决方案1】:

    每次调用 Country 构造函数时,您都会创建一个新的 ObservableList 实例。这样,与ComboBox 使用的列表不同的列表就会被修改。

    如果您确实需要将国家/地区列表保存在静态字段中(这被认为是不好的做法),您应该确保只创建一个 ObservableList

    private static final ObservableList<Country> countryList = FXCollections.observableArrayList();
    

    (也从构造函数中移除该字段的赋值。)

    【讨论】:

    • 我知道这是小东西咬我的。感谢您指出!尽管我确实想知道为什么将这样的列表保留在单个静态列表中会被认为是不好的做法。我的总体想法是在国家列表方面拥有单一的事实来源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-19
    • 1970-01-01
    • 2016-03-02
    相关资源
    最近更新 更多