通过构建一些应用程序,我可以使用生成动态表单的功能来填充任意变量列表。例如,当运行以任意文件格式读取的Lua脚本时,该脚本可能需要唯一的信息才能对该格式进行解码(例如,为CSV分隔字符)。本质上,我想要的东西类似于Unity的检查器。
我有一个HashMap
可以将Class
映射到Handler
:
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));
}
};
创建表单时,它使用getFields()
从传递的Class
中获取字段列表,构造表单时,它会创建一个简单的GridPane
并将其填充带有标签和控件。
从理论上讲,这应该可以正常工作,但是我在Path
类中注意到,该类并不总是与其预期用途保持一致。 Path
可能指向文件或目录,这需要对浏览对话框进行不同的设置。同样,String
可以用于许多事物,并且可能需要进行某些验证。
最有效的方法是重写类型检查并明确说明要使用的表单输入?我考虑使用Decorator,但这些装饰似乎是为了扩展装饰对象的现有功能,而我想向它们灌输额外的信息。
编辑:对于进一步的上下文,我希望能够做类似Unity的[Range()]装饰器之类的事情,从而使数值类由最小值和最大值之间的滑块表示。
edit 2:为澄清和简化:Form
类基于类生成自动表单。例如,将其传递给以下类
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;
}
结果采用以下形式:
我希望能够在课堂上指出哪些字段应以不同的方式处理。理想情况下,我还希望通过传递混合变量数组来实现此目的,并且希望能够定义自定义模式,就像使用Unity和自定义检查器可以做到的那样。
答案 0 :(得分:0)
我想出的最好方法涉及到一些重新排列。它仅对自定义类自动起作用,但允许在初始化后进行一些自定义。
首先,为自定义类编写一个公共接口以实现,以允许它们定义自定义控件列表:
public interface FormLayout {
List<Input> getLayout();
}
然后,在构造函数中,而不是初始化字段列表,而是检查对象是否定义了自己的布局:
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())));
}
}
}
现在,您已经获得了可在构造表单之前进行操作的已定义输入列表,并且能够为类定义自定义布局。
还需要做更多工作来处理将输入与字段相关联,以便用户输入实际上可以到达正确的变量,但这似乎是最合理的方法。