本文介绍了在侦察蚀中扩展表单数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些抽象形式:

 @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 {
    ...
    }

 }

此表单数据内部有一些表(以MyTable类作为模板):

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() {}
    }
}

我的真实表单扩展了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 {
    ...
    }

}

此表单数据为:

 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() {}
      }
      .....
      .....
 }

问题在于两个表单数据(AbstractMyFormData和MyFormData)都已实现

public static class MyTable extends AbstractMyTableData

,然后侦察员抱怨具有重复的方法getMyTable().

但是我不明白这一点.如果MyFormData是从AbstractMyFormData扩展而来的,则MyFormData一定不能在其中包含此方法,因为它已经具有它的父项.

如何执行此操作?我看到FormData.SdkCommand.USE可能是它的描述,但我现在不知道如何使用它.

第二个问题可能与如何像正常的AbstractForm注入取消按钮一样在AbstractMyForm中注入表一样?

课程代码:

摘要表

@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模板:

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 {
    }
  }
}

对于真实表单,您只需从模板创建表单:

并在主框中添加MyTable,如:

插入:

@Order(10.0)
public class MainBox extends AbstractGroupBox {

}

要做:

 @Order(10.0)
 public class MainBox extends AbstractGroupBox {

     @Order(10.0)
     public class MyTable extends AbstractMyTableField {

     }
 }

希望这次我更加明确.

编辑2

我承认在抽象形式内创建主框可能不是正确的方法,但我想实现的是在AbstractMyFormData中包含AbstractMyTableField,因此我可以依靠服务器端,所有从AbstractMyForm扩展的形式都具有此功能在表单数据中,因此我只能为所有表单编写一个服务器方法(返回AbstractMyFormData).

解决方案

FormData和表单层次结构

formData层次结构反映了表单层次结构.如果您形成层次结构,则如下所示:

MyForm
  |-- PersonForm
  |     \-- VipForm.
  \-- CompanyForm

您的formData层次结构如下:

MyFormData
  |-- PersonFormData
  |     \-- VipFormData
  \-- CompanyFormData


不要两次定义MainBox

以您的示例为准,您绝对正确,SDK生成的代码包含编译错误.

我试图在您对表单模板的问题中进行解释,但是拥有它没有任何意义表单模板中的一个主框,具体表单中的一个.

每个表单包含:

  • 0..n个变量
  • 0..n击键(实现IKeyStroke的内部类)
  • 恰好是1个Main Box(实现IGroupBox的内部类)
  • 0..n ToolButtons(实现IToolButton的内部类)
  • 1..n Form Handler(通常定义为实现IFormHandler的内部类,但是由于将处理程序设置为AbstractForm.startInternal(IFormHandler)的参数,因此可以在任何地方定义处理程序)

在您的情况下,当您考虑具体表单(MyForm)的外观时,您会注意到它具有两个MainBox:

  • ConcreteForm.MainBox
  • 对应的一个
  • 由抽象类贡献的一个,对应于AbstractMyForm.MainBox我本来希望有一个编译错误(从纯粹的角度来看),但它似乎可以工作.

在运行时侦察器中,选择两个MainBox类之一,并将其​​用作字段树的根.我什至不确定所选的MainBox是否已由侦查员很好地定义,或者您只是随机地获得了两者之一(取决于java内省Class.getClasses()将返回的内容).

我看不到您使用的模式可以确保什么.您可以在具体表单的主框中定义其他内容:

@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 {
  }
}

在这种情况下,即使在用作表单模板的抽象类中定义了一个表,我也没有任何扩展AbstractMyTableField的表.


@FormData配置

您可以使用formData批注影响formData的生成.这里有两个例子:

1/如果使用定义为模板的组框,则可以决定GroupBoxData是否应为外部类.您可以自己尝试:

选中或取消选中创建外部FormData"复选框.您可以比较输出(生成的类)和@FormData批注.

2/对于TableData,您可以决定formData中的结构是什么样(基于bean或基于数组).请参阅Eclipse Wiki上的 TableData

@FormData批注的JavaDoc中描述了各种选项的用法.


如果您将某个字段从一个类移到了另一个类,则建议您使用SDK重新生成所有FormData. (在Scout资源管理器中更新所有formData类").这可能会解决您的编译问题.

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).

解决方案

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.MainBoxI 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.

这篇关于在侦察蚀中扩展表单数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 07:20