2016-02-12 60 views
0

我目前正在研究現有的GWT項目。在這個項目中我已經添加視圖中的一個列表,它看起來是這樣的:GWT TextBox,DateBox等不共享相同的基本輸入類

  • 的Label1:[文本框]
  • Label2的:DateBox]
  • LABEL3:[文本框]
  • Label4: [文本框]
  • Label5:[DateBox]
  • Label6:[文本框]

我已導出的插件從FlowPanel中,我創建這些標籤-的InputBox對:

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的共享Base類非常難看。由於它們不共享類似於InputBox類的東西,我必須在確定使用哪個(Input)Widget之後設置它們的值,並且可能對ValueChangedHandlers執行相同的操作以驗證我剛剛要創建的用戶輸入。

有誰知道一個更好的解決方案,在LabelInputWidgets的同一個列表中使用TextBoxes和DateBoxes,但幾乎在任何地方都不使用醜陋instanceof,只需使用一種通用方法?

如果不是我可能會躲在某處爲了使代碼更易讀有點這種行爲..

PS:我不是100%肯定這是對的StackOverflow合適的問題,所以我做了還有一個關於CodeReview.StackExchange.com的交叉問題。我在這裏也發佈了它,但有兩個原因:

  • 有人可能有一個完全不同的方式適合於此解決方案。
  • 這裏的社區更大,所以我可能會得到答案快..
+1

那麼你可以使LabelInputWidget抽象,並有兩個它的實現(基於日期的和基於文本框的)重載方法 –

+0

@РоманГуйван我很笨,doh ..幸運的是它幾乎是週末..感謝這個明顯的解。你可以做出答案,如果你想,所以我可以接受它。 (不能相信我甚至不能想到那些簡單的事情..)。無論如何,謝謝,馬上就要開始了。代碼當然需要大量的重構和同事審閱。 –

+0

@Kevin - 您可以使用InlineLabel而不是Label。 –

回答

1

那麼你可以使LabelInputWidget抽象,並有兩種實現它(基於日期的和基於文本框的)與方法重載。

4

您可以使用

public class LabelInputWidget<T> extends FlowPanel { 

    private final Label   label; 
    private final HasValue<T> inputField; 

... 

其中<T>可以是一個字符串或日期。

+0

'HasValue '實現似乎確實是兩者之間的良好共享類。我將同時使用您和РоманГуйван的解決方案。 –