如何将与构建场景或控件(视图)相关的所有逻辑放在单独的类中,并使用它来构建和分配适当的样式表?
例如,我创建了FXMLBuilder 类。它只是基于控制器类加载 FXML,然后遍历控制器的层次结构并应用与层次结构中相应控制器相关的样式表。在文件系统中,我有以下层次结构:
|
+- controllers
| |
| +- BaseController.java
| +- BaseController.fxml
| +- BaseController.css
|
...
|
+- MyController.java (inherited from BaseController)
+- MyController.fxml
+- MyController.css
所以,当我构建 MyController 的实例时,
MyController myController = new MyController(...);
Parent myControllerRootNode = FXMLBuilder.build(myController);
...
它应用来自 MyController.css 和 BaseController.css 文件的样式表。
这是我的FXMLBuilder:
public class FXMLBuilder {
public static final String FXML_EXTENSION = "fxml";
public static final String CSS_EXTENSION = "css";
public static Parent build(Object controller) throws IOException {
Class<?> controllerClass = controller.getClass();
URL fxmlURL = getResourceURL(controllerClass, FXML_EXTENSION);
FXMLLoader fxmlLoader = new FXMLLoader(fxmlURL);
fxmlLoader.setControllerFactory(param -> controller);
Parent rootNode = fxmlLoader.load();
loadStylesheets(rootNode, controllerClass);
return rootNode;
}
private static void loadStylesheets(Parent rootNode, Class<?> controllerClass) {
Class<?> currentControllerClass = controllerClass;
while (!currentControllerClass.equals(Object.class)) {
if (getResourceURL(currentControllerClass, CSS_EXTENSION) != null) {
rootNode.getStylesheets().add(getResourcePath(currentControllerClass, CSS_EXTENSION));
}
currentControllerClass = currentControllerClass.getSuperclass();
}
}
public static String getResourcePath(Class<?> resourceClass, String extension) {
return String.format("/%s.%s", resourceClass.getCanonicalName().replace(".", "/"), extension);
}
public static URL getResourceURL(Class<?> resourceClass, String extension) {
return resourceClass.getResource(getResourcePath(resourceClass, extension));
}
}
我认为您可以编写类似这样的内容来加载适用于所有视图的基本样式表,然后加载为视图指定的自定义样式表。
附:从基础控制器开始遍历层次结构会更好。