繁体   English   中英

JavaFx从单个FXML生成多个场景

[英]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,例如FXForm2ControlsFX PropertySheets

也可以从数据动态生成 ,这似乎是您实际上要尝试执行的操作。

在FXML上

对于大多数这些系统,您无需使用FXML定义小部件的内部GUI。 相反,可以通过对数据或Java类进行自省来动态生成低级字段。 您要做的就是将适当的库添加到SceneBuilder中,并导入高级控件(例如ControlsFX PropertySheet),仅在FXML中声明,而不在FXML中定义控件的详细字段。

如果需要,并且链接库中的系统不是您所需要的,则您还可以创建自定义控件并将其导入在SceneBuilder中使用 ,尽管它们仍然可能以类似的方式工作,即从数据或数据中动态生成详细信息字段。通过反射进行 Java类自省。

通过自省生成动态场

基于反射创建自定义控件是一个高级主题,仅建议有经验的Java和JavaFX开发人员使用。 您可以查看PropertySheet实现的示例代码,以了解这种方法,该方法通过BeanPropertyUtils实用程序类使用Java BeanIntrospector Java bean是一个很大的话题,在这里我无法详细介绍。 只有Java Bean规范的某些功能才能实现所需的功能,因为该规范的其他部分已被较新的JavaFX功能(如属性和绑定)所取代。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM