我有视图,有ListView
和Pane
。我想将控制器添加为ListView
的项目,当我单击其中一个listView的元素时,将Pane
的内容设置为其控制器内容,
例如,我有FruitsController
和VegetablesController
,当然还有每个控制器的相应.fxml
,当我点击第一个元素时,设置Pane
个元素a tableView的水果,否则是蔬菜的tableview。我试过whith <fx:include source=Fruits.fxml>
等等但我不知道如何切换内容,以及如何在ListView中显示自定义名称作为元素名称。所以你有什么想法吗?
编辑:
我在How can I Populate a ListView in JavaFX using Custom Objects?和JavaFX - ListView Item with an Image Button找到了部分解决方案
但问题仍然存在,我不知道如何以及在何处放置<fx:include>
标签,以便在我点击某个项目时加载它。
答案 0 :(得分:1)
您可以使用列表视图的选择模型注册侦听器,并在选择更改时加载相应的视图。
,例如,假设你有
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 ;
}
}
然后在FXML中:
<!-- 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
),并在加载新FXML后使用ProductsController currentController = loader.getController();
从加载器中检索当前控制器。 (在这种情况下,您还可以将controllerType
中View
的类型更改为Class<? extends ProductsController>
。)