如何加载内容JavaFX的标签动态?(How to load content to JavaFX t

2019-06-27 10:18发布

我有一个图形用户界面,使用JavaFX与FXML制成。

该GUI有很多组件,而不是所有的人都在一个时刻需要。

例如,假设从服务器接收部分城市的列表的GUI。 每个城市自己的标签上描述的(并且有很多节点的描述)。 该组城市中含有30个元素。

当GUI启动时,它要求城市列表服务器。 服务器返回城市的一个随机的“子集”(所以,也可以是莫斯科里加+ +纽约或圣彼得堡+东京,或者只阿姆斯特丹,或在一组的所有30个城市)。

所以。 我有没有必要让所有30个选项卡在我的节点树(我想他们会只是“吃”内存,仅此而已)。

我要管理我在我的GUI每一刻标签的数量。

第一个简单的解决办法我有如下:

  1. 创建一个包含所有城市部件的FXML文件
  2. 在控制器类的初始化,删除选项卡,这是没有必要的。

有对我有这个解决方案的问题。 首先,我不知道是否tabPane.getTabs().remove(index)确实删除选项卡,并从节点树中的所有内容。 其次,所有不需要的标签将被initializated他们将被删除之前,所以他们会使用内存和资源,无论如何,我的GUI可以是一个比它慢不得。

第二种解决方案我已经是:

  1. 让很多FXMLs的。 一为所有城市,每个城市和一个城市的每个组合。

但会有办法很多FXMLs,因此该方案也没有用处。

我梦想的解决方案:

  1. 创建每个城市和一个与标签的主要应用程序的FXML文件。
  2. 在需要的时候加载FXML城市文件内容到一个标签动态。

因此,如果有人对这个任务的任何想法,或者知道该解决方案,请大家帮我吧?

Answer 1:

好吧,如果我理解正确的你,这里是我的建议维多利亚;
假设主要的应用程序FXML包含TabPane某处吧:

// other controls
<TabPane fx:id="tabPane" id="tabPane">
   <tabs>
   </tabs>
</TabPane>
// other controls

在主控制器:

// TabPane in fxml
@FXML
private TabPane tabPane;

// The FXMLLoader
private FXMLLoader fXMLLoader = new FXMLLoader();

// City list fetched from server
private String[] cityList = {"Moscow", "Stambul", "New York", "Bishkek"};

// OPTIONAL : Map for "city name - city fxml controller" pairs
private Map<String, Object> cityControllerMap = new HashMap<String, Object>();

// Belows are in init method

// Add only tabs dynamically but not their content
for (String city : cityList) {
    tabPane.getTabs().add(new Tab(city));
}

// It is important to call it before adding ChangeListener to the tabPane to avoid NPE and
// to be able fire the manual selection event below. Otherwise the 1st tab will be selected
// with empty content.
tabPane.getSelectionModel().clearSelection();

// Add Tab ChangeListener
tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() {
    @Override
    public void changed(ObservableValue<? extends Tab> observable, Tab oldValue, Tab newValue) {
        System.out.println("Tab selected: " + newValue.getText());
        if (newValue.getContent() == null) {
            try {
                // Loading content on demand
                Parent root = (Parent) fXMLLoader.load(this.getClass().getResource(newValue.getText() + ".fxml").openStream());
                newValue.setContent(root);

                // OPTIONAL : Store the controller if needed
                cityControllerMap.put(newValue.getText(), fXMLLoader.getController());

            } catch (IOException ex) {
                ex.printStackTrace();
            }
        } else {
            // Content is already loaded. Update it if necessary.
            Parent root = (Parent) newValue.getContent();
            // Optionally get the controller from Map and manipulate the content
            // via its controller.
        }
    }
});
// By default, select 1st tab and load its content.
tabPane.getSelectionModel().selectFirst();

如果您决定存储控制器,你可以定义一个控制器,每个城市FXML或只定义一个控制器类为所有这些并设定它像fXMLLoader.setController(new CommonCityController()); 之前加载城市FXML文件。

HTH。



文章来源: How to load content to JavaFX tabs dynamically?
标签: javafx-2 fxml