[英]JavaFx Generate multiple scene from single FXML
我启动了一个与数据库交互的javafx项目(添加,编辑,删除,查找等)。
我的数据库包含很多表,每个表需要自己的场景(几乎相同!!!)。
所以我的问题是:不是实现〜20 fxml文件,而是可以制作一个单独的fxml文件,该文件将根据传递给其控制器的类名(例如)来更改其内容?
如果是,有什么技巧可以实现吗?
这是我尝试过的:
为每个TableClass添加了一个HashMap,其中包含场景中所需的所有属性,并在ControllerClass中对其进行迭代以将控件添加到场景中! 但是失败了!
TableSampleClass:
public class TableSampleClass{
public static final HashMap<String, String> attr;
static {
attr = new HashMap<String, String>();
attr.put("ref", "text");
attr.put("name", "text");
attr.put("adress", "text");
attr.put("Mobile", "tel");
attr.put("mail", "mail");
attr.put("isalive", "checkbox");//just to illustrate what i want !
}
........
}
ControllerClass:
@FXML
private AnchorPane pane;
@Override
public void initialize(URL location, ResourceBundle resources)
{ Iterator it = TableSampleClass.attr.entrySet().iterator();
while(it.hasNext())
{
Map.Entry pair = (Map.Entry)it.next();
switch (pair.getValue().toString()){
case "text":
TextField txt =new TextField(pair.getValue().toString());
txt.setPromptText(pair.getKey().toString());
Label lbl =new Label(pair.getKey().toString());
pane.getChildren().add(txt);
break;
}
}
}
我希望我确实清楚地解释了自己!
使用自定义组件FXML模式 。 它的工作方式是编写一个控制器类,该类将相应的FXML文件加载到构造函数中。 由于通过调用构造函数来使用此功能,因此可以允许构造函数获取参数,并在加载FXML之后使用这些参数来配置组件。
您显示的代码对我来说不是很清楚,但是这种结构看起来像:
public class MyCustomTableDisplay extends AnchorPane {
@FXML
private AnchorPane pane ;
public MyCustomTableDisplay(Map<String, String> config) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/fxml"));
loader.setRoot(this);
loader.setController(this);
loader.load();
} catch (IOException exc) {
throw new RuntimeException(exc);
}
// now configure pane based on config passed in...
}
}
FXML文件必须使用“动态根”,这意味着根元素是通过在FXMLLoader
上调用setRoot(...)
来FXMLLoader
(如上面的代码所示)。 所以看起来
<!-- imports omitted -->
<fx:root type="AnchorPane" xmlns:fx="..." ... >
<!-- usual fxml stuff -->
<AnchorPane fx:id="pane" ...>
<AnchorPane>
</fx:root>
现在你要做
Map<String, String> config = new HashMap<>();
// populate config...
MyCustomTableDisplay display = new MyCustomTableDisplay(config);
Scene scene = new Scene(display);
// etc...
该type
的的fx:root
可以是基本上任何节点类型,但必须类的类型相匹配。 然后,您可以包含所需的任何fxml内容。 该类充当控制器,因此您可以按常规方式从FXML注入值:在加载程序上调用load()
方法时,它们将被初始化(照常)。
潜在方法
有一些第三方库可以为JavaFX动态生成表单和界面UI,例如FXForm2和ControlsFX PropertySheets 。
也可以从数据动态生成表 ,这似乎是您实际上要尝试执行的操作。
在FXML上
对于大多数这些系统,您无需使用FXML定义小部件的内部GUI。 相反,可以通过对数据或Java类进行自省来动态生成低级字段。 您要做的就是将适当的库添加到SceneBuilder中,并导入高级控件(例如ControlsFX PropertySheet),仅在FXML中声明,而不在FXML中定义控件的详细字段。
如果需要,并且链接库中的系统不是您所需要的,则您还可以创建自定义控件并将其导入在SceneBuilder中使用 ,尽管它们仍然可能以类似的方式工作,即从数据或数据中动态生成详细信息字段。通过反射进行 Java类自省。
通过自省生成动态场
基于反射创建自定义控件是一个高级主题,仅建议有经验的Java和JavaFX开发人员使用。 您可以查看PropertySheet实现的示例代码,以了解这种方法,该方法通过BeanPropertyUtils实用程序类使用Java Bean和Introspector 。 Java bean是一个很大的话题,在这里我无法详细介绍。 只有Java Bean规范的某些功能才能实现所需的功能,因为该规范的其他部分已被较新的JavaFX功能(如属性和绑定)所取代。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.