GWT TextBox、DateBox 等不共享相同的基本输入-class
GWT TextBox, DateBox, and such doesn't share same base input-class
我目前正在处理现有的 GWT 项目。在这个项目中,我在视图中添加了一个列表,如下所示:
- 标签 1 : [文本框]
- 标签 2 : [日期框]
- 标签 3 : [文本框]
- 标签 4 : [文本框]
- 标签 5 : [日期框]
- 标签 6 : [文本框]
我制作了一个派生自 FlowPanel
的小部件,我在其中创建了这些 Label-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);
}
}
}
而且我还想在用户输入内容时验证输入(待办事项/正在进行的工作)。
如您所见,将常规 com.google.gwt.user.client.ui.Widget
用作 TextBox 和 DateBox 的共享基础 class 非常难看。因为它们不共享 InputBox-class 之类的东西,所以我必须在确定使用哪个 (Input)Widget 后设置它们的值,并且可能对 ValueChangedHandlers 做同样的事情来验证用户输入,我只是即将创建。
有谁知道在 LabelInputWidgets
的同一个列表中同时使用 TextBoxes 和 DateBoxes 的更好解决方案,而不是几乎在所有地方都使用丑陋的 instanceof
,只使用一种通用方法?
如果不是,我可能会将此行为隐藏在某处以使代码更具可读性..
PS:我不是 100% 确定这是一个适合 Whosebug 的问题,所以我也在 CodeReview.StackExchange.com 上做了一个交叉问题。我也把它贴在这里,但是有两个原因:
- 有人可能以完全不同的方式对此有合适的解决方案。
- 这里的社区更大,所以我可能会更快得到答案..
您可以使用
public class LabelInputWidget<T> extends FlowPanel {
private final Label label;
private final HasValue<T> inputField;
...
其中 <T>
可以是字符串或日期。
好吧,您可以将 LabelInputWidget 抽象化,并使用重载方法对其进行两种实现(基于日期的一种和基于文本框的一种)。
我目前正在处理现有的 GWT 项目。在这个项目中,我在视图中添加了一个列表,如下所示:
- 标签 1 : [文本框]
- 标签 2 : [日期框]
- 标签 3 : [文本框]
- 标签 4 : [文本框]
- 标签 5 : [日期框]
- 标签 6 : [文本框]
我制作了一个派生自 FlowPanel
的小部件,我在其中创建了这些 Label-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);
}
}
}
而且我还想在用户输入内容时验证输入(待办事项/正在进行的工作)。
如您所见,将常规 com.google.gwt.user.client.ui.Widget
用作 TextBox 和 DateBox 的共享基础 class 非常难看。因为它们不共享 InputBox-class 之类的东西,所以我必须在确定使用哪个 (Input)Widget 后设置它们的值,并且可能对 ValueChangedHandlers 做同样的事情来验证用户输入,我只是即将创建。
有谁知道在 LabelInputWidgets
的同一个列表中同时使用 TextBoxes 和 DateBoxes 的更好解决方案,而不是几乎在所有地方都使用丑陋的 instanceof
,只使用一种通用方法?
如果不是,我可能会将此行为隐藏在某处以使代码更具可读性..
PS:我不是 100% 确定这是一个适合 Whosebug 的问题,所以我也在 CodeReview.StackExchange.com 上做了一个交叉问题。我也把它贴在这里,但是有两个原因:
- 有人可能以完全不同的方式对此有合适的解决方案。
- 这里的社区更大,所以我可能会更快得到答案..
您可以使用
public class LabelInputWidget<T> extends FlowPanel {
private final Label label;
private final HasValue<T> inputField;
...
其中 <T>
可以是字符串或日期。
好吧,您可以将 LabelInputWidget 抽象化,并使用重载方法对其进行两种实现(基于日期的一种和基于文本框的一种)。