代码之家  ›  专栏  ›  技术社区  ›  Kevin Cruijssen

GWT TextBox、DateBox等不共享相同的基本输入类

  •  0
  • Kevin Cruijssen  · 技术社区  · 10 年前

    我目前正在进行一个现有的GWT项目。在这个项目中,我在视图上添加了一个列表,如下所示:

    • 标签1:[文本框]
    • 标签2:[日期框]
    • 标签3:[文本框]
    • 标签4:[文本框]
    • 标签5:[日期框]
    • 标签6:[文本框]

    我制作了一个衍生自 FlowPanel 我在其中创建了这些标签输入框对:

    import java.sql.Date;
    
    import com.google.gwt.dom.client.Style.Display;
    import com.google.gwt.user.client.ui.FlowPanel;
    import com.google.gwt.user.client.ui.Label;
    import com.google.gwt.user.client.ui.TextBox;
    import com.google.gwt.user.client.ui.Widget;
    import com.google.gwt.user.datepicker.client.DateBox;
    
    public class LabelInputWidget extends FlowPanel {
    
      private final Label      label;
      private final Widget     inputField;
    
      private static final int LABEL_AND_INPUTFIELD_WIDTH = 200;
    
      public LabelInputWidget(final String labelText, final Widget inputField) {
        super();
    
        this.label = new Label(labelText);
        this.label.getElement().getStyle().setDisplay(Display.INLINE_BLOCK); // Used to put the inputfield next to the label, instead of below it
        this.label.setWidth(LABEL_AND_INPUTFIELD_WIDTH + "px");
        this.add(this.label);
    
        this.inputField = inputField;
        // The DateBox width looks smaller when the same width is set, so we'll add 4 pixels to line it up with the other Input-Widgets
        int inputWidth = LABEL_AND_INPUTFIELD_WIDTH;
        if (inputField instanceof DateBox) {
          inputWidth += 4;
        }
        this.inputField.setWidth(inputWidth + "px");
        this.add(this.inputField);
      }
    
      // TODO KC: Use a less ugly way of determine which InputField is used
      // POTENTIAL TODO KC: Use custom widgets for Numeric / Currency input fields
      public void setInputValue(final String value) {
        if (this.inputField instanceof TextBox) {
          ((TextBox) this.inputField).setValue(value);
        } else if (this.inputField instanceof DateBox) {
          ((DateBox) this.inputField).setValue(value != null && value.length() > 0 ? Date.valueOf(value) : null);
        }
      }
    }
    

    在我创建这些字段的文件中,我有以下内容:

    private void fillEditedProperties(final List<Property> list) {
      for (final Property p : list) {
        if (!containsProperty(p)) {
          this.editedProperties.add(p);
    
          // The moment the property is loaded and known, we add it to the view
          Widget inputWidget = new TextBox();
          if (Type.DATUM.name().equals(p.getPdf().getType().name())) {
            final DateBox dateBox = new DateBox();
            dateBox.setFormat(new DateBox.DefaultFormat(DateTimeFormat.getFormat("dd-MM-yyyy")));
            inputWidget = new DateBox();
          }
          final LabelInputWidget labelInput = new LabelInputWidget(p.getPdf().getName(), inputWidget);
          labelInput.setInputValue(p.getValue());
          labelInput.getElement().getStyle().setDisplay(Display.BLOCK); // Used to put the LabelInputWidgets below each other
          this.labelInputFieldsContainer.add(labelInput);
        }
      }
    }
    

    我还想在用户输入某个内容时验证输入(TODO/正在进行的工作)。

    正如你所看到的,普通的 com.google.gwt.user.client.ui.Widget 用作TextBox和DateBox的共享基类。因为它们不共享类似于InputBox类的东西,所以我必须在确定使用哪个(Input)Widget之后设置它们的值,并且可能对ValueChangedHandlers执行同样的操作,以验证用户输入,我刚刚要创建的用户输入。

    有人知道在同一列表中同时使用TextBox和DateBox的更好的解决方案吗 LabelInputWidgets ,但不是使用丑陋 instanceof 几乎所有地方,只使用一种通用方法?

    如果不是,我可能会将此行为隐藏在某个地方,以使代码更具可读性。。

    PS:我不是100%确定这是一个适合StackOverflow的问题,所以我在 CodeReview.StackExchange.com 也我也把它贴在这里,但有两个原因:

    • 有人可能会以完全不同的方式找到一个合适的解决方案。
    • 这里的社区更大,所以我可能会更快地得到答案。。
    2 回复  |  直到 9 年前
        1
  •  4
  •   Andrei Volgin    10 年前

    您可以使用

    public class LabelInputWidget<T> extends FlowPanel {
    
        private final Label         label;
        private final HasValue<T>   inputField;
    
    ...
    

    哪里 <T> 可以是字符串或日期。

        2
  •  1
  •   Роман Гуйван    10 年前

    您可以使LabelInputWidget抽象化,并有两个方法重载的实现(基于日期的实现和基于文本框的实现)。