问题
I have some abstract form :
@FormData(value = AbstractMyFormData.class, sdkCommand = FormData.SdkCommand.CREATE)
public abstract class AbstractMyForm extends AbstractForm {
...
@Order(10.0)
@ClassId("MyForm.MyTable")
public class MyTable extends AbstractMyTableField {
...
}
}
This form data has some table (MyTable class as template) inside :
public abstract class AbstractMyFormData extends AbstractFormData {
private static final long serialVersionUID = 1L;
public AbstractMyFormData() {}
public MyTable getMyTable() {
return getFieldByClass(MyTable.class);
}
public static class MyTable extends AbstractMyTableData {
private static final long serialVersionUID = 1L;
public MyTable() {}
}
}
My real form extends AbstractMyForm :
@FormData(value = MyFormData.class, sdkCommand = FormData.SdkCommand.CREATE)
public class MyForm extends AbstractMyForm {
...
@Order(10.0)
@ClassId("MyForm.MyTable")
public class MyTable extends AbstractMyTableField {
...
}
}
form data for this is :
public class MyFormData extends AbstractMyFormData {
public MyTable getMyTable() {
return getFieldByClass(MyTable.class);
}
public static class MyTable extends AbstractMyTableData {
private static final long serialVersionUID = 1L;
public MyTable() {}
}
.....
.....
}
The problem is that both form datas (AbstractMyFormData and MyFormData) has implemented
public static class MyTable extends AbstractMyTableData
and than scout complains that has duplicate method getMyTable()
.
But I don't understand this. If MyFormData is extend from AbstractMyFormData than MyFormData must not have this method inside because it already has it his parent.
How to do this? I see FormData.SdkCommand.USE
that by description might be it, but I don't now how to use it.
Second question witch might be related is how to inject table in AbstractMyForm like normal AbstractForm inject Cancel button?
EDIT :
Code for classes :
ABSTRACT FORM
@FormData(value = AbstractPurchasePriceFormData.class, sdkCommand = FormData.SdkCommand.CREATE)
@ClassId("41f0f405-b257-47e7-accf-270f5be158ce")
public abstract class AbstractMyForm extends AbstractForm {
/**
* @throws org.eclipse.scout.commons.exception.ProcessingException
*/
public AbstractMyForm() throws ProcessingException {
super();
}
@Order(10.0)
public class MainBox extends AbstractGroupBox {
@Order(10.0)
public class MyTable extends AbstractMyTableField {
}
}
@Override
protected String getConfiguredTitle() {
return TEXTS.get("AbstractMyForm");
}
}
AbstractMyTableField template :
import org.eclipse.scout.commons.annotations.FormData;
import org.eclipse.scout.commons.annotations.Order;
import org.eclipse.scout.rt.client.ui.basic.table.columns.AbstractIntegerColumn;
import org.eclipse.scout.rt.client.ui.basic.table.columns.AbstractStringColumn;
import org.eclipse.scout.rt.client.ui.form.fields.tablefield.AbstractTableField;
import org.eclipse.scout.rt.extension.client.ui.basic.table.AbstractExtensibleTable;
@FormData(value = AbstractMyTableFieldData.class, sdkCommand = FormData.SdkCommand.CREATE, defaultSubtypeSdkCommand = FormData.DefaultSubtypeSdkCommand.CREATE)
public abstract class AbstractMyTableField extends AbstractTableField<AbstractMyTableField.Table> {
@Order(10.0)
public class Table extends AbstractExtensibleTable {
@Order(10.0)
public class NameColumn extends AbstractStringColumn {
}
@Order(20.0)
public class AgeColumn extends AbstractIntegerColumn {
}
}
}
FOR REAL FORM you just create form from template :
and in main box add MyTable like :
insted :
@Order(10.0)
public class MainBox extends AbstractGroupBox {
}
do :
@Order(10.0)
public class MainBox extends AbstractGroupBox {
@Order(10.0)
public class MyTable extends AbstractMyTableField {
}
}
I hope I was more explicit this time.
EDIT 2
I admit that creating main box inside abstract form is maybe not the right approach, but what I want to achive is to have AbstractMyTableField
in AbstractMyFormData, so I can rely on server side that all forms that extend from AbstractMyForm has this in form data so I can write only one server method for all forms (returning AbstractMyFormData).
回答1:
FormData and Form hierarchy
The formData hierarchy reflects the form hierarchy. If you form hierarchy looks like this:
MyForm
|-- PersonForm
| \-- VipForm.
\-- CompanyForm
Your formData hierarchy looks like this:
MyFormData
|-- PersonFormData
| \-- VipFormData
\-- CompanyFormData
Do not define the MainBox twice
With you example, You have absolutely right the code generated by the SDK contains compilation errors.
I have tried to explain it in your question about form template, but it doesn’t make any sense to have a main box in the form template and in one in the concrete form.
Each form contains:
- 0..n variables
- 0..n Key Strokes (inner classes implementing IKeyStroke)
- exactly 1 Main Box (inner class implementing IGroupBox)
- 0..n ToolButtons (inner classes implementing IToolButton)
- 1..n Form Handler (usually defined as inner classes implementing IFormHandler, but since the handler is set as parameter of AbstractForm.startInternal(IFormHandler) the handler can be defined everywhere)
In your case, when you consider how the concrete form (MyForm) looks like, you notice that it have two MainBox:
- one corresponding to
ConcreteForm.MainBox
- one contributed by the abstract class and corresponding to
AbstractMyForm.MainBox
I would have expected a compile error (from a pure jave point of view) but it seems to work.
At runtime scout pick one of the two MainBox
classes and use it as root of the field tree. I am not even sure if the selected MainBox
is well defined by scout or if you just randomly get one of the two (depending on what the java introspection Class.getClasses()
will return).
I do not see what is ensured with the pattern you have used. You can define something else in the main box of the concrete form:
@Order(10.0)
public class MainBox extends AbstractGroupBox {
@Order(10.0)
public class NameField extends AbstractStringField {
@Override
protected String getConfiguredLabel() {
return TEXTS.get("Name");
}
}
@Order(20.0)
public class OkButton extends AbstractOkButton {
}
@Order(30.0)
public class CancelButton extends AbstractCancelButton {
}
}
In this case I do not have any table extending AbstractMyTableField
in the concrete form, even if one table is defined in the abstract class used as form template.
@FormData configuration
You can influence the generation of the formData with the formData annotation. Here two examples:
1/ If you work with group boxes defined as templates you can decide if the GroupBoxData should be an external class or not. You can try it by ourself:
Check or uncheck the checkbox "Create external FormData". You can compare the output (generated classes) and the @FormData
annotation.
2/ For TableData you can decided how the structure in the formData will look like (bean based or array based). See TableData on the eclipse wiki
Usage of the different options is described in the JavaDoc of the @FormData
annotation.
If you have moved some field from one class to another, I recommend you to regenerate all the FormDatas with the SDK. (“Update all formData classes” in the scout explorer). This might solve your compilations problem.
来源:https://stackoverflow.com/questions/25994014/extends-form-data-in-scout-eclipse