简体   繁体   English

根据类型生成表格元素,并带有覆盖

[英]Generate form elements based on type, with overrides

With a few applications I'm building, I could use the ability to generate dynamic forms for filling in arbitrary lists of variables. 通过构建一些应用程序,我可以使用生成动态表单的功能来填写任意变量列表。 For example, when running a Lua script that reads in an arbitrary file format, the script may need unique information to decode that format (eg separating character for a CSV). 例如,当运行以任意文件格式读取的Lua脚本时,该脚本可能需要唯一的信息来解码该格式(例如,分隔CSV字符)。 Essentially, I want something similar to Unity 's inspector. 本质上,我想要类似于Unity的检查器的东西。

I have a HashMap that maps a Class to a Handler : 我有一个将Class映射到HandlerHashMap

private interface Handler {
    Control handle(GridPane grid, Integer row);
}

private static final HashMap<Class, Handler> FormInputs =
        new HashMap<Class, Handler>() {
    {
        // String
        put(String.class, (grid, row) -> CreateStringInput(grid, row));

        // Integer
        put(int.class, (grid, row) -> CreateIntegerInput(grid, row));
        put(Integer.class, (grid, row) -> CreateIntegerInput(grid, row));

        // Float
        put(float.class, (grid, row) -> CreateFloatInput(grid, row));

        // Directory
        put(Path.class, (grid, row) -> CreateFileInput(grid, row));
        put(File.class, (grid, row) -> CreateFileInput(grid, row));

    }
};

When the form is created, it uses getFields() to get the list of fields from the passed Class , and when the form is constructed, it creates a simple GridPane and fills it with labels and controls. 创建表单时,它使用getFields()从传递的Class获取字段列表,构造表单时,它创建一个简单的GridPane并用标签和控件填充它。

In theory, this should work fine, but I noticed with the Path class that the class does not always line up with its intended use. 从理论上讲,这应该可以正常工作,但是我在Path类中注意到该类并不总是与其预期用途保持一致。 A Path may point to a file or a directory, which require different settings for the browsing dialog. Path可能指向文件或目录,这需要对浏览对话框进行不同的设置。 Similarly, a String may be used for any number of things, and may need certain validation. 类似地, String可以用于许多事物,并且可能需要某些验证。

What would be the most friendly approach for overriding the type check and explicitly stating which form input to use? 覆盖类型检查并明确说明要使用哪种表单输入的最友好方法是什么? I looked into using Decorators, but those seem to be for extending existing functions of the decorated object, whereas I want to imbue them with extra information. 我考虑使用Decorator,但这些装饰似乎是为了扩展装饰对象的现有功能,而我想向它们灌输额外的信息。

edit: For further context, I would like to be able to do things like Unity's [Range()] decorator, whereby numeric classes become represented by a slider between the min and max values. 编辑:对于进一步的上下文,我希望能够做类似Unity的[Range()]装饰器之类的事情,从而使数值类由最小值和最大值之间的滑块表示。

edit 2: To clarify and simplify: The Form class generates an automatic form based on a class. 编辑2:澄清和简化: Form类基于一个类生成一个自动表单。 For example, passing it the following class 例如,将其传递给以下类

public class TestClass {
    public boolean bool1;
    public Boolean bool2;
    public String string1;
    public String string2;
    public Integer int1;
    public int int2;
    public Path path1;
    public File file1;
}

results in the following form: 结果为以下形式:

自动生成的表格

I want to be able to indicate, in the class, which fields should be handled differently. 我希望能够在课堂上指出哪些字段应以不同的方式处理。 Ideally I also want this to work by passing in an array of mixed variables, and I want to be able to define a custom schema, like can be done with Unity and custom inspectors. 理想情况下,我还希望通过传递混合变量数组来实现此目的,并且希望能够定义自定义模式,就像使用Unity和自定义检查器可以完成的那样。

The best method I have come up with involves a bit of rearranging. 我想出的最好方法涉及一些重新排列。 It only works automatically for custom classes, but it allows for some customisation after initialisation. 它仅对自定义类自动起作用,但允许在初始化后进行一些自定义。

First, write a public interface for custom classes to implement that allows them to define a custom list of controls: 首先,为自定义类编写一个公共接口以实现,以允许它们定义自定义控件列表:

public interface FormLayout {
    List<Input> getLayout();
}

Then, in the constructor, instead of initialising a list of fields, check if the object defines its own layout: 然后,在构造函数中,而不是初始化字段列表,而是检查对象是否定义了自己的布局:

public Form (Object objRef) {
    Field[] fields = objRef.getClass().getFields();
    if(objRef instanceof Form.FormLayout) {
        inputs = ((FormLayout) objRef).getLayout();
    }
    else {
        inputs = new ArrayList<>();
        for (int i = 0; i < fields.length; i++) {
            inputs.add(new Input(fields[i].getName(), FormInputs.get(fields[i].getType())));
        }
    }
}

Now you have a list of defined inputs that can be manipulated before constructing the form, and the ability to define a custom layout for a class. 现在,您有了定义的输入列表,可以在构造表单之前对其进行操作,并且可以为类定义自定义布局。

Further work will need to be done to handle associating an input with a field so the user input actually makes its way to the right variable, but this seems to be the most reasonable approach. 需要做进一步的工作来处理将输入与字段相关联的操作,以便用户输入实际上可以到达正确的变量,但这似乎是最合理的方法。

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

相关问题 lombok 可以仅根据类型生成构建器吗? - Can lombok generate builder based on the type solely? 根据参数类型向ArrayList添加随机元素? - Add random elements to ArrayList based on argument type? 是否可以根据窗口元素的时间戳动态生成BigQuery表名? - Is it possible to dynamically generate BigQuery table names based on the timestamps of the elements of a window? 您可以使用Java批注生成覆盖方法的代码吗? - Can you generate code the overrides a method using Java annotations? 根据公共元素对元素进行分组,形成一个json对象数组 - Grouping elements based on common element to form a json array of objects 根据对象属性类型从列表中提取元素 - Extract elements from list based on object property type 任何基于输入数字类型生成相同类型数值的优雅方法? - Any elegant way to generate numeric value of the same type based on input numeric type? JAXB / xjc:从子元素生成类并根据类类型加载它们 - JAXB/xjc: Generate classes from child elements and load them based on class types 如何根据表单字段选择要实例化的对象类型? - how to choose what type of object to instantiate based on form field? 我是否可以根据Annotated字段的类型生成编译时错误 - Can I generate a compile time error based on the type of the field being Annotated
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM