您只需向列表視圖的選擇模型註冊偵聽器,並在選擇更改時加載相應的視圖。
例如,假設你在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保存在內存中。也許如果你不能以簡單的方式使用監聽器發佈一些代碼來展示你如何去做。 –