我启动了一个与数据库交互的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;
}
}
}
我希望我能清楚地解释自己!!
答案 0 :(得分:0)
使用Custom component FXML pattern。这种方式的工作方式是编写一个控制器类,在构造函数中加载相应的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文件必须使用“动态根”,这意味着通过调用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
的{{1}}基本上可以是任何节点类型,但必须与类的类型匹配。然后,您可以包含所需的任何fxml内容。该类充当控制器,因此您可以通常的方式从FXML注入值:当在加载器上调用fx:root
方法时,它们将被初始化(像往常一样)。
答案 1 :(得分:0)
潜在方法
有一些第三方库可动态生成JavaFX的表单和界面UI,例如FXForm2和ControlsFX PropertySheets。
也可以生成一个table from data dynamically,看起来它可能就像你实际上要做的那样。
关于FXML
对于大多数系统,您不使用FXML定义窗口小部件的内部GUI。而是通过内省数据或Java类动态生成低级字段。您要做的就是将相应的库添加到SceneBuilder并导入高级控件(例如ControlsFX PropertySheet),只是在FXML中声明它而不是在FXML中定义控件的详细字段。
如果需要,并且链接库中的系统不是您所需要的,您还可以创建自定义控件和import those for use in SceneBuilder,尽管这些仍然可以以类似方式动态生成详细信息字段通过reflection进行数据或Java类内省。
通过内省生成动态字段
基于反射创建自定义控件是仅为经验丰富的Java和JavaFX开发人员推荐的高级主题。您可以通过PropertySheet implementation实用程序类查看java beans这种方法的示例代码,该代码使用Introspector和BeanPropertyUtils。 Java bean是一个非常大的主题,我在这里不能详细介绍。只需要java bean规范的某些功能即可实现所需,因为规范的其他部分已被新的JavaFX功能(如属性和绑定)废弃。