final Method setMethod = pd.getWriteMethod();
final Class<?> type = pd.getPropertyType();
final String name = pd.getName();
- final Property p = new MethodProperty(type, bean, getMethod,
- setMethod);
+ final Property p = new MethodProperty<Object>(type, bean,
+ getMethod, setMethod);
addItemProperty(name, p);
}
final Method getMethod = pd.getReadMethod();
final Method setMethod = pd.getWriteMethod();
final Class<?> type = pd.getPropertyType();
- final Property p = new MethodProperty(type, bean, getMethod,
- setMethod);
+ final Property p = new MethodProperty<Object>(type, bean,
+ getMethod, setMethod);
addItemProperty(name, p);
}
}
}
if (propertyId.equals(PROPERTY_NAME)) {
- return new MethodProperty(getType(propertyId), new FileItem(
- (File) itemId), FILEITEM_NAME, null);
+ return new MethodProperty<Object>(getType(propertyId),
+ new FileItem((File) itemId), FILEITEM_NAME, null);
}
if (propertyId.equals(PROPERTY_ICON)) {
- return new MethodProperty(getType(propertyId), new FileItem(
- (File) itemId), FILEITEM_ICON, null);
+ return new MethodProperty<Object>(getType(propertyId),
+ new FileItem((File) itemId), FILEITEM_ICON, null);
}
if (propertyId.equals(PROPERTY_SIZE)) {
- return new MethodProperty(getType(propertyId), new FileItem(
- (File) itemId), FILEITEM_SIZE, null);
+ return new MethodProperty<Object>(getType(propertyId),
+ new FileItem((File) itemId), FILEITEM_SIZE, null);
}
if (propertyId.equals(PROPERTY_LASTMODIFIED)) {
- return new MethodProperty(getType(propertyId), new FileItem(
- (File) itemId), FILEITEM_LASTMODIFIED, null);
+ return new MethodProperty<Object>(getType(propertyId),
+ new FileItem((File) itemId), FILEITEM_LASTMODIFIED, null);
}
return null;
* @since 3.0
*/
@SuppressWarnings("serial")
-public class MethodProperty implements Property, Property.ValueChangeNotifier,
- Property.ReadOnlyStatusChangeNotifier {
+public class MethodProperty<T> implements Property,
+ Property.ValueChangeNotifier, Property.ReadOnlyStatusChangeNotifier {
/**
* The object that includes the property the MethodProperty is bound to.
/**
* Type of the property.
*/
- private transient Class<?> type;
+ private transient Class<? extends T> type;
/**
* List of listeners who are interested in the read-only status changes of
ClassNotFoundException {
in.defaultReadObject();
try {
- type = SerializerHelper.readClass(in);
+ @SuppressWarnings("unchecked")
+ // business assumption; type parameters not checked at runtime
+ Class<T> class1 = (Class<T>) SerializerHelper.readClass(in);
+ type = class1;
instance = in.readObject();
setArgs = (Object[]) in.readObject();
getArgs = (Object[]) in.readObject();
* </p>
*
* <p>
- * Method names are constucted from the bean property by adding
+ * Method names are constructed from the bean property by adding
* get/is/are/set prefix and capitalising the first character in the name of
* the given bean property.
* </p>
getMethod = beanClass.getMethod("are" + beanPropertyName,
new Class[] {});
} catch (final java.lang.NoSuchMethodException e) {
- throw new MethodProperty.MethodException("Bean property "
+ throw new MethodException(this, "Bean property "
+ beanPropertyName + " can not be found");
}
}
}
// In case the get method is found, resolve the type
- type = getMethod.getReturnType();
+ Class<?> returnType = getMethod.getReturnType();
// Finds the set method
setMethod = null;
try {
setMethod = beanClass.getMethod("set" + beanPropertyName,
- new Class[] { type });
+ new Class[] { returnType });
} catch (final java.lang.NoSuchMethodException skipped) {
}
// Gets the return type from get method
- if (type.isPrimitive()) {
- if (type.equals(Boolean.TYPE)) {
- type = Boolean.class;
- } else if (type.equals(Integer.TYPE)) {
- type = Integer.class;
- } else if (type.equals(Float.TYPE)) {
- type = Float.class;
- } else if (type.equals(Double.TYPE)) {
- type = Double.class;
- } else if (type.equals(Byte.TYPE)) {
- type = Byte.class;
- } else if (type.equals(Character.TYPE)) {
- type = Character.class;
- } else if (type.equals(Short.TYPE)) {
- type = Short.class;
- } else if (type.equals(Long.TYPE)) {
- type = Long.class;
+ if (returnType.isPrimitive()) {
+ if (returnType.equals(Boolean.TYPE)) {
+ type = (Class<T>) Boolean.class;
+ } else if (returnType.equals(Integer.TYPE)) {
+ type = (Class<T>) Integer.class;
+ } else if (returnType.equals(Float.TYPE)) {
+ type = (Class<T>) Float.class;
+ } else if (returnType.equals(Double.TYPE)) {
+ type = (Class<T>) Double.class;
+ } else if (returnType.equals(Byte.TYPE)) {
+ type = (Class<T>) Byte.class;
+ } else if (returnType.equals(Character.TYPE)) {
+ type = (Class<T>) Character.class;
+ } else if (returnType.equals(Short.TYPE)) {
+ type = (Class<T>) Short.class;
+ } else if (returnType.equals(Long.TYPE)) {
+ type = (Class<T>) Long.class;
+ } else {
+ throw new MethodException(this, "Bean property "
+ + beanPropertyName
+ + " getter return type must not be void");
}
+ } else {
+ type = (Class<T>) returnType;
}
setArguments(new Object[] {}, new Object[] { null }, 0);
*
*/
@SuppressWarnings("unchecked")
- public MethodProperty(Class type, Object instance, String getMethodName,
- String setMethodName) {
+ public MethodProperty(Class<? extends T> type, Object instance,
+ String getMethodName, String setMethodName) {
this(type, instance, getMethodName, setMethodName, new Object[] {},
new Object[] { null }, 0);
}
* the setter method.
*/
@SuppressWarnings("unchecked")
- public MethodProperty(Class type, Object instance, Method getMethod,
- Method setMethod) {
+ public MethodProperty(Class<? extends T> type, Object instance,
+ Method getMethod, Method setMethod) {
this(type, instance, getMethod, setMethod, new Object[] {},
new Object[] { null }, 0);
}
* {@link #setValue(Object newValue)} is called.
*/
@SuppressWarnings("unchecked")
- public MethodProperty(Class type, Object instance, String getMethodName,
- String setMethodName, Object[] getArgs, Object[] setArgs,
- int setArgumentIndex) {
+ public MethodProperty(Class<? extends T> type, Object instance,
+ String getMethodName, String setMethodName, Object[] getArgs,
+ Object[] setArgs, int setArgumentIndex) {
// Check the setargs and setargs index
if (setMethodName != null && setArgs == null) {
// all paramteters matched
if (found == true) {
- throw new MethodProperty.MethodException(
+ throw new MethodException(this,
"Could not uniquely identify " + getMethodName
+ "-method");
} else {
}
}
if (found != true) {
- throw new MethodProperty.MethodException("Could not find "
- + getMethodName + "-method");
+ throw new MethodException(this, "Could not find " + getMethodName
+ + "-method");
}
// Finds set method
// all parameters match
if (found == true) {
- throw new MethodProperty.MethodException(
+ throw new MethodException(this,
"Could not identify unique " + setMethodName
+ "-method");
} else {
}
}
if (found != true) {
- throw new MethodProperty.MethodException("Could not identify "
+ throw new MethodException(this, "Could not identify "
+ setMethodName + "-method");
}
}
// Gets the return type from get method
if (type.isPrimitive()) {
if (type.equals(Boolean.TYPE)) {
- this.type = Boolean.class;
+ this.type = (Class<T>) Boolean.class;
} else if (type.equals(Integer.TYPE)) {
- this.type = Integer.class;
+ this.type = (Class<T>) Integer.class;
} else if (type.equals(Float.TYPE)) {
- this.type = Float.class;
+ this.type = (Class<T>) Float.class;
} else if (type.equals(Double.TYPE)) {
- this.type = Double.class;
+ this.type = (Class<T>) Double.class;
} else if (type.equals(Byte.TYPE)) {
- this.type = Byte.class;
+ this.type = (Class<T>) Byte.class;
} else if (type.equals(Character.TYPE)) {
- this.type = Character.class;
+ this.type = (Class<T>) Character.class;
} else if (type.equals(Short.TYPE)) {
- this.type = Short.class;
+ this.type = (Class<T>) Short.class;
} else if (type.equals(Long.TYPE)) {
- this.type = Long.class;
+ this.type = (Class<T>) Long.class;
}
}
int setArgumentIndex) {
if (getMethod == null) {
- throw new MethodProperty.MethodException(
+ throw new MethodException(this,
"Property GET-method cannot not be null: " + type);
}
try {
return getMethod.invoke(instance, getArgs);
} catch (final Throwable e) {
- throw new MethodProperty.MethodException(e);
+ throw new MethodException(this, e);
}
}
}
} catch (final InvocationTargetException e) {
final Throwable targetException = e.getTargetException();
- throw new MethodProperty.MethodException(targetException);
+ throw new MethodException(this, targetException);
} catch (final Exception e) {
- throw new MethodProperty.MethodException(e);
+ throw new MethodException(this, e);
}
}
* @VERSION@
* @since 3.0
*/
- public class MethodException extends RuntimeException {
+ @SuppressWarnings("rawtypes")
+ // Exceptions cannot be parameterized, ever.
+ public static class MethodException extends RuntimeException {
+
+ /**
+ * The method property from which the exception originates from
+ */
+ private final MethodProperty methodProperty;
/**
* Cause of the method exception
* Constructs a new <code>MethodException</code> with the specified
* detail message.
*
+ * @param methodProperty
+ * the method property.
* @param msg
* the detail message.
*/
- public MethodException(String msg) {
+ public MethodException(MethodProperty methodProperty, String msg) {
super(msg);
+ this.methodProperty = methodProperty;
}
/**
* Constructs a new <code>MethodException</code> from another exception.
*
+ * @param methodProperty
+ * the method property.
* @param cause
* the cause of the exception.
*/
- public MethodException(Throwable cause) {
+ public MethodException(MethodProperty methodProperty, Throwable cause) {
+ this.methodProperty = methodProperty;
this.cause = cause;
}
* Gets the method property this exception originates from.
*/
public MethodProperty getMethodProperty() {
- return MethodProperty.this;
+ return methodProperty;
}
}
* @param source
* source object of the event.
*/
- protected ReadOnlyStatusChangeEvent(MethodProperty source) {
+ protected ReadOnlyStatusChangeEvent(MethodProperty<T> source) {
super(source);
}
private void fireReadOnlyStatusChange() {
if (readOnlyStatusChangeListeners != null) {
final Object[] l = readOnlyStatusChangeListeners.toArray();
- final Property.ReadOnlyStatusChangeEvent event = new MethodProperty.ReadOnlyStatusChangeEvent(
+ final Property.ReadOnlyStatusChangeEvent event = new ReadOnlyStatusChangeEvent(
this);
for (int i = 0; i < l.length; i++) {
((Property.ReadOnlyStatusChangeListener) l[i])
* @param source
* source object of the event.
*/
- protected ValueChangeEvent(MethodProperty source) {
+ protected ValueChangeEvent(MethodProperty<T> source) {
super(source);
}
public void fireValueChange() {
if (valueChangeListeners != null) {
final Object[] l = valueChangeListeners.toArray();
- final Property.ValueChangeEvent event = new MethodProperty.ValueChangeEvent(
- this);
+ final Property.ValueChangeEvent event = new ValueChangeEvent(this);
for (int i = 0; i < l.length; i++) {
((Property.ValueChangeListener) l[i]).valueChange(event);
}
MyTest myTest = new MyTest();
- MethodProperty methodProperty2 = new MethodProperty(Integer.TYPE,
- myTest, "getInt", "setInt", new Object[0],
+ MethodProperty<Integer> methodProperty2 = new MethodProperty<Integer>(
+ Integer.TYPE, myTest, "getInt", "setInt", new Object[0],
new Object[] { null }, 0);
methodProperty2.setValue("3");
private static HorizontalLayout createHorizontalLayout(Component c) {
HorizontalLayout layout = new HorizontalLayout();
- Button b = new Button("immediate", new MethodProperty(c, "immediate"));
+ Button b = new Button("immediate", new MethodProperty<Boolean>(c,
+ "immediate"));
layout.addComponent(b);
- b = new Button("selectable", new MethodProperty(c, "selectable"));
+ b = new Button("selectable", new MethodProperty<Boolean>(c,
+ "selectable"));
layout.addComponent(b);
- b = new Button("nullsel", new MethodProperty(c, "nullSelectionAllowed"));
+ b = new Button("nullsel", new MethodProperty<Boolean>(c,
+ "nullSelectionAllowed"));
layout.addComponent(b);
- b = new Button("multi", new MethodProperty(c, "multiSelect"));
+ b = new Button("multi", new MethodProperty<Boolean>(c, "multiSelect"));
layout.addComponent(b);
return layout;
}
addComponent(updateButton);
TextField tableHeight = new TextField("Table height",
- new MethodProperty(this, "tableHeight"));
+ new MethodProperty<String>(this, "tableHeight"));
tableHeight.setImmediate(true);
addComponent(tableHeight);
}
public void testForm() throws Exception {
Form f = new Form();
String propertyId = "My property";
- f.addItemProperty(propertyId, new MethodProperty(new Data(),
+ f.addItemProperty(propertyId, new MethodProperty<Object>(new Data(),
"dummyGetterAndSetter"));
f.replaceWithSelect(propertyId, new Object[] { "a", "b", null },
new String[] { "Item a", "ITem b", "Null item" });
}
public void testMethodPropertyGetter() throws Exception {
- MethodProperty mp = new MethodProperty(new Data(), "dummyGetter");
+ MethodProperty<?> mp = new MethodProperty<Object>(new Data(),
+ "dummyGetter");
serializeAndDeserialize(mp);
}
public void testMethodPropertyGetterAndSetter() throws Exception {
- MethodProperty mp = new MethodProperty(new Data(),
+ MethodProperty<?> mp = new MethodProperty<Object>(new Data(),
"dummyGetterAndSetter");
serializeAndDeserialize(mp);
}
public void testMethodPropertyInt() throws Exception {
- MethodProperty mp = new MethodProperty(new Data(), "dummyInt");
+ MethodProperty<?> mp = new MethodProperty<Object>(new Data(),
+ "dummyInt");
serializeAndDeserialize(mp);
}
LayoutTestingPanel oltp = new LayoutTestingPanel("OrderedLayout",\r
orderedLayout);\r
hidingControls.addComponent(new Button("OrderedLayout",\r
- new MethodProperty(oltp, "visible")));\r
+ new MethodProperty<Boolean>(oltp, "visible")));\r
lo.addComponent(oltp);\r
orderedLayout.setSpacing(false);\r
addFields(orderedLayout);\r
GridLayout grid = new GridLayout(1, 1);\r
Panel g1tp = new LayoutTestingPanel("Gridlayout with 1 column", grid);\r
hidingControls.addComponent(new Button("GridLayout (1col)",\r
- new MethodProperty(g1tp, "visible")));\r
+ new MethodProperty<Boolean>(g1tp, "visible")));\r
g1tp.setVisible(false);\r
lo.addComponent(g1tp);\r
grid.setSpacing(true);\r
GridLayout grid2 = new GridLayout(2, 1);\r
Panel g2tp = new LayoutTestingPanel("Gridlayout with 2 columns", grid2);\r
hidingControls.addComponent(new Button("GridLayout (2cols)",\r
- new MethodProperty(g2tp, "visible")));\r
+ new MethodProperty<Boolean>(g2tp, "visible")));\r
g2tp.setVisible(false);\r
lo.addComponent(g2tp);\r
grid2.setSpacing(true);\r
Panel elp = new LayoutTestingPanel(\r
"ExpandLayout width first component expanded", el);\r
hidingControls.addComponent(new Button("ExpandLayout (vertical)",\r
- new MethodProperty(elp, "visible")));\r
+ new MethodProperty<Boolean>(elp, "visible")));\r
elp.setVisible(false);\r
el.setHeight(700);\r
addFields(el);\r
Panel elhp = new LayoutTestingPanel(\r
"ExpandLayout width first component expanded; horizontal", elh);\r
hidingControls.addComponent(new Button("ExpandLayout (horizontal)",\r
- new MethodProperty(elhp, "visible")));\r
+ new MethodProperty<Boolean>(elhp, "visible")));\r
elhp.setVisible(false);\r
elhp.setScrollable(true);\r
elh.setWidth(2000);\r
OrderedLayout cl = new OrderedLayout();\r
Panel clp = new LayoutTestingPanel("CustomLayout", cl);\r
hidingControls.addComponent(new Button("CustomLayout",\r
- new MethodProperty(clp, "visible")));\r
+ new MethodProperty<Boolean>(clp, "visible")));\r
clp.setVisible(false);\r
lo.addComponent(clp);\r
cl.addComponent(new Label("<<< Add customlayout testcase here >>>"));\r
\r
// Form\r
Panel formPanel = new Panel("Form");\r
- hidingControls.addComponent(new Button("Form", new MethodProperty(\r
- formPanel, "visible")));\r
+ hidingControls.addComponent(new Button("Form",\r
+ new MethodProperty<Boolean>(formPanel, "visible")));\r
formPanel.setVisible(false);\r
formPanel.addComponent(getFormPanelExample());\r
lo.addComponent(formPanel);\r
controls.setSpacing(true);\r
controls.setMargin(false);\r
controls.addComponent(new Label("width"));\r
- controls.addComponent(new TextField(new MethodProperty(\r
+ controls.addComponent(new TextField(new MethodProperty<Float>(\r
testedLayout, "width")));\r
- controls.addComponent(new Button("%", new MethodProperty(this,\r
- "widthPercents")));\r
+ controls.addComponent(new Button("%", new MethodProperty<Boolean>(\r
+ this, "widthPercents")));\r
controls.addComponent(new Label("height"));\r
- controls.addComponent(new TextField(new MethodProperty(\r
+ controls.addComponent(new TextField(new MethodProperty<Float>(\r
testedLayout, "height")));\r
- controls.addComponent(new Button("%", new MethodProperty(this,\r
- "heightPercents")));\r
+ controls.addComponent(new Button("%", new MethodProperty<Boolean>(\r
+ this, "heightPercents")));\r
controls.addComponent(marginLeft);\r
controls.addComponent(marginRight);\r
controls.addComponent(marginTop);\r
\r
s = new Select("Testcase from the ticket #1804");\r
s.setNullSelectionAllowed(false);\r
- s.setPropertyDataSource(new MethodProperty(new TestPojo(), "id"));\r
+ s.setPropertyDataSource(new MethodProperty<String>(new TestPojo(), "id"));\r
s.addValidator(new EmptyStringValidator(\r
"Selection required for test-field"));\r
s.setRequired(true);\r
\r
s = new Select("Testcase from the ticket #1804, but without validator");\r
s.setNullSelectionAllowed(false);\r
- s.setPropertyDataSource(new MethodProperty(new TestPojo(), "id"));\r
+ s.setPropertyDataSource(new MethodProperty<String>(new TestPojo(), "id"));\r
s.setRequired(true);\r
listOfAllFields.add(s);\r
\r
s = new Select(\r
"Testcase from the ticket #1804, but with required=false");\r
s.setNullSelectionAllowed(false);\r
- s.setPropertyDataSource(new MethodProperty(new TestPojo(), "id"));\r
+ s.setPropertyDataSource(new MethodProperty<String>(new TestPojo(), "id"));\r
s.addValidator(new EmptyStringValidator(\r
"Selection required for test-field"));\r
listOfAllFields.add(s);\r
s = new Select(\r
"Testcase from the ticket #1804, but without validator and with required=false");\r
s.setNullSelectionAllowed(false);\r
- s.setPropertyDataSource(new MethodProperty(new TestPojo(), "id"));\r
+ s.setPropertyDataSource(new MethodProperty<String>(new TestPojo(), "id"));\r
listOfAllFields.add(s);\r
\r
s = new Select(\r
"Required=true, custom error message, null selection not allowed");\r
s.setRequired(true);\r
s.setNullSelectionAllowed(false);\r
- s.setPropertyDataSource(new MethodProperty(new TestPojo(), "id"));\r
+ s.setPropertyDataSource(new MethodProperty<String>(new TestPojo(), "id"));\r
s.setValue(null);\r
s.setComponentError(new SystemError("Test error message"));\r
listOfAllFields.add(s);\r
"readOnly", "readThrough", "invalidCommitted",
"validationVisible" };
for (int i = 0; i < visibleProps.length; i++) {
- Button b = new Button(visibleProps[i], new MethodProperty(tx,
- visibleProps[i]));
+ Button b = new Button(visibleProps[i], new MethodProperty<Boolean>(
+ tx, visibleProps[i]));
b.setImmediate(true);
mainWin.addComponent(b);
}
layout.setSpacing(true);\r
\r
TextField f1 = new TextField("Non-immediate/Long text field",\r
- new MethodProperty(this, "long1"));\r
+ new MethodProperty<Long>(this, "long1"));\r
f1.setImmediate(false);\r
f1.setNullSettingAllowed(true);\r
TextField f2 = new TextField("Immediate/Long text field",\r
- new MethodProperty(this, "long2"));\r
+ new MethodProperty<Long>(this, "long2"));\r
f2.setImmediate(true);\r
f2.setNullSettingAllowed(true);\r
\r
OrderedLayout ol = new OrderedLayout(
OrderedLayout.ORIENTATION_HORIZONTAL);
main.addComponent(ol);
- Button b = new Button("immediate",
- new MethodProperty(tree, "immediate"));
+ Button b = new Button("immediate", new MethodProperty<Boolean>(tree,
+ "immediate"));
b.setImmediate(true);
ol.addComponent(b);
- b = new Button("selectable", new MethodProperty(tree, "selectable"));
+ b = new Button("selectable", new MethodProperty<Boolean>(tree,
+ "selectable"));
b.setImmediate(true);
ol.addComponent(b);
- b = new Button("nullsel", new MethodProperty(tree,
+ b = new Button("nullsel", new MethodProperty<Boolean>(tree,
"nullSelectionAllowed"));
b.setImmediate(true);
ol.addComponent(b);
- b = new Button("multi", new MethodProperty(tree, "multiSelect"));
+ b = new Button("multi",
+ new MethodProperty<Boolean>(tree, "multiSelect"));
b.setImmediate(true);
ol.addComponent(b);
b = new Button("icon", new Button.ClickListener() {
ol = new OrderedLayout(OrderedLayout.ORIENTATION_HORIZONTAL);
main.addComponent(ol);
- b = new Button("immediate", new MethodProperty(table, "immediate"));
+ b = new Button("immediate", new MethodProperty<Boolean>(table,
+ "immediate"));
b.setImmediate(true);
ol.addComponent(b);
- b = new Button("selectable", new MethodProperty(table, "selectable"));
+ b = new Button("selectable", new MethodProperty<Boolean>(table,
+ "selectable"));
b.setImmediate(true);
ol.addComponent(b);
- b = new Button("nullsel", new MethodProperty(table,
+ b = new Button("nullsel", new MethodProperty<Boolean>(table,
"nullSelectionAllowed"));
b.setImmediate(true);
ol.addComponent(b);
- b = new Button("multi", new MethodProperty(table, "multiSelect"));
+ b = new Button("multi", new MethodProperty<Boolean>(table,
+ "multiSelect"));
b.setImmediate(true);
ol.addComponent(b);
main.addComponent(table);
}
});
- Button b = new Button("editmode", new MethodProperty(table,
- "editable"));
+ Button b = new Button("editmode", new MethodProperty<Boolean>(
+ table, "editable"));
b.setImmediate(true);
addComponent(b);
}
"readOnly", "readThrough", "writeThrough", "invalidCommitted",
"validationVisible", "immediate" };
for (int i = 0; i < visibleProps.length; i++) {
- Button b = new Button(visibleProps[i], new MethodProperty(f,
- visibleProps[i]));
+ Button b = new Button(visibleProps[i], new MethodProperty<Boolean>(
+ f, visibleProps[i]));
b.setImmediate(true);
formProperties.addComponent(b);
}
"readOnly", "readThrough", "invalidCommitted",
"validationVisible" };
for (int i = 0; i < visibleProps.length; i++) {
- Button b = new Button(visibleProps[i], new MethodProperty(tx,
- visibleProps[i]));
+ Button b = new Button(visibleProps[i], new MethodProperty<Boolean>(
+ tx, visibleProps[i]));
b.setImmediate(true);
mainWin.addComponent(b);
}
+ (tx.isValid() ? "" : "not ") + "valid");
};
}));
- TextField caption = new TextField("Caption", new MethodProperty(tx,
- "caption"));
+ TextField caption = new TextField("Caption",
+ new MethodProperty<String>(tx, "caption"));
caption.setImmediate(true);
mainWin.addComponent(caption);
}