您只需向列表视图的选择模型注册侦听器,并在选择更改时加载相应的视图。
例如,假设你在FXML有
public class View {
private final String name ;
private final Class<?> controllerType ;
// You could assume that the resource is name+".fxml" if you want to rely on conventions like that
// That would eliminate the need for another field here, but would prevent
// e.g. names with whitespace etc.
private final String resource ;
public View(String name, Class<?> controllerType, String resource) {
this.name = name ;
this.controllerType = controllerType ;
this.resource = resource ;
}
public String getName() {
return name ;
}
public Class<?> getControllerType() {
return controllerType ;
}
public String getResource() {
return resource ;
}
@Override
public String toString() {
return name ;
}
}
然后:
<!-- imports, namespaces omitted -->
<BorderPane fx:id="root" fx:controller="app.MainController" ... >
<left>
<ListView fx:id="selector"/>
</left>
</BorderPane>
,并在控制器:
package app ;
public class MainController {
@FXML
private BorderPane root ;
@FXML
private ListView<View> selector ;
public void initialize() {
selector.getSelectionModel().selectedItemProperty().addListener((obs, oldView, newView) -> {
if (newView == null) {
root.setCenter(null);
} else {
// assumes each FXML is in the same package as its controller
// (which I think is a nice way to organize things)
FXMLLoader loader = new FXMLLoader(newView.getControllerType().getResource(newView.getResource()));
try {
root.setCenter(loader.load());
} catch (IOException exc) {
// unrecoverable...
throw new UncheckedIOException(exc);
}
}
});
selector.getItems().addAll(
new View("Fruits", FruitsController.class, "Fruits.fxml"),
new View("Vegetables", VegetablesController.class, "Vegetables.fxml")
);
}
}
如果所有的控制器都具有共同的功能,可以使它们实现一个通用接口(例如ProductsController
),并检索当前控制器f加载新的FXML后,从ProductsController currentController = loader.getController();
开始从加载程序。 (在这种情况下,您也可以将View
中的controllerType
更改为Class<? extends ProductsController>
)。
这可能最好不要用''来完成。只需向列表视图的选择模型注册监听器,并在控制器中选择更改时加载新的FXML。 –
是的,这是我的解决方案,但我有9-10项,并且列表随着时间增长,所以我认为有一种更简单的方法,在每次添加新的时候都不写入加载程序项目列表。你为什么说“最好不要这样做”?这是一种糟糕的方式,或者仅仅是不可能的? – Sunflame
不知道我明白。您只需要一个监听器来选择,然后根据所选内容选择FXML文件。然后*为该FXML文件创建一个加载器并加载它。 (我想我不明白“写入”加载程序的含义。)如果使用'',您基本上必须加载所有可能的FXML文件,并以某种方式隐藏不想显示的文件,这会更加复杂,并且会一直将所有这些UI保存在内存中。也许如果你不能以简单的方式使用监听器发布一些代码来展示你如何去做。 –