Adds UiBinder support for ListBox.
Fixes http://code.google.com/p/google-web-toolkit/issues/detail?id=4654
Patch by http://code.google.com/u/markovuksanovic/
Review by rjrjr@google.com http://gwt-code-reviews.appspot.com/153804
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7619 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/ListBoxParser.java b/user/src/com/google/gwt/uibinder/elementparsers/ListBoxParser.java
new file mode 100644
index 0000000..3a9993a
--- /dev/null
+++ b/user/src/com/google/gwt/uibinder/elementparsers/ListBoxParser.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.uibinder.elementparsers;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.uibinder.rebind.UiBinderWriter;
+import com.google.gwt.uibinder.rebind.XMLElement;
+
+/**
+ * A parser for ListBox items.
+ */
+public class ListBoxParser implements ElementParser {
+
+ private static final String ITEM_TAG = "item";
+
+ public void parse(XMLElement elem, String fieldName, JClassType type,
+ UiBinderWriter writer) throws UnableToCompleteException {
+ // Parse children.
+ for (XMLElement child : elem.consumeChildElements()) {
+ String tagName = child.getLocalName();
+ if (!tagName.equals(ITEM_TAG)) {
+ writer.die("Invalid ListBox child element: " + tagName);
+ }
+ String value = child.consumeStringAttribute("value");
+ String innerText = child.consumeInnerTextEscapedAsHtmlStringLiteral(new TextInterpreter(writer));
+ if (value != null) {
+ writer.addStatement("%s.addItem(\"%s\", %s);", fieldName, innerText, value);
+ } else {
+ writer.addStatement("%s.addItem(\"%s\");", fieldName, innerText);
+ }
+ }
+ }
+
+}
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
index f168d1a..a013d27 100644
--- a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
+++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
@@ -949,6 +949,7 @@
addWidgetParser("StackLayoutPanel");
addWidgetParser("TabLayoutPanel");
addWidgetParser("Image");
+ addWidgetParser("ListBox");
}
/**
diff --git a/user/src/com/google/gwt/user/client/ui/ListBox.java b/user/src/com/google/gwt/user/client/ui/ListBox.java
index 3029329..4715f94 100644
--- a/user/src/com/google/gwt/user/client/ui/ListBox.java
+++ b/user/src/com/google/gwt/user/client/ui/ListBox.java
@@ -41,6 +41,29 @@
* <h3>Example</h3>
* {@example com.google.gwt.examples.ListBoxExample}
* </p>
+ *
+ * <h3>Use in UiBinder Templates</h3>
+ * <p>
+ * The items of a ListBox element are laid out in <g:item> elements.
+ * Each item contains text that will be added to the list of available
+ * items that will be shown, either in the drop down or list. (Note that
+ * the tags of the item elements are not capitalized. This is meant to
+ * signal that the item is not a runtime object, and so cannot have a
+ * <code>ui:field</code> attribute.) It is also possible to explicitly
+ * specify item's value using value attribute as shown below.
+ * <p>
+ * For example:
+ *
+ * <pre>
+ * <g:ListBox>
+ * <g:item>
+ * first
+ * </g:item>
+ * <g:item value='2'>
+ * second
+ * </g:item>
+ * </g:ListBox>
+ * </pre>
*/
@SuppressWarnings("deprecation")
public class ListBox extends FocusWidget implements SourcesChangeEvents,
diff --git a/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java b/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java
index 9ff047d..e828dba 100644
--- a/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java
+++ b/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java
@@ -27,6 +27,7 @@
import com.google.gwt.uibinder.elementparsers.ImageParserTest;
import com.google.gwt.uibinder.elementparsers.IsEmptyParserTest;
import com.google.gwt.uibinder.elementparsers.LayoutPanelParserTest;
+import com.google.gwt.uibinder.elementparsers.ListBoxParserTest;
import com.google.gwt.uibinder.elementparsers.StackLayoutPanelParserTest;
import com.google.gwt.uibinder.elementparsers.TabLayoutPanelParserTest;
import com.google.gwt.uibinder.elementparsers.UIObjectParserTest;
@@ -76,6 +77,7 @@
suite.addTestSuite(ImageParserTest.class);
suite.addTestSuite(IsEmptyParserTest.class);
suite.addTestSuite(LayoutPanelParserTest.class);
+ suite.addTestSuite(ListBoxParserTest.class);
suite.addTestSuite(StackLayoutPanelParserTest.class);
suite.addTestSuite(TabLayoutPanelParserTest.class);
suite.addTestSuite(UIObjectParserTest.class);
diff --git a/user/test/com/google/gwt/uibinder/elementparsers/ListBoxParserTest.java b/user/test/com/google/gwt/uibinder/elementparsers/ListBoxParserTest.java
new file mode 100644
index 0000000..b90eb0b
--- /dev/null
+++ b/user/test/com/google/gwt/uibinder/elementparsers/ListBoxParserTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.uibinder.elementparsers;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+/**
+ * A unit test. Guess what of.
+ */
+public class ListBoxParserTest extends TestCase {
+ private static final String PARSED_TYPE = "com.google.gwt.user.client.ui.ListBox";
+
+ private ElementParserTester tester;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ tester = new ElementParserTester(PARSED_TYPE, new ListBoxParser());
+ }
+
+ public void testChildWithWhitespaces() throws UnableToCompleteException, SAXException, IOException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:ListBox>");
+ b.append(" <g:item> </g:item>");
+ b.append("</g:ListBox>");
+
+ String[] expected = {
+ "fieldName.addItem(\"\");" };
+
+ tester.parse(b.toString());
+
+ Iterator<String> i = tester.writer.statements.iterator();
+ for (String e : expected) {
+ assertEquals(e, i.next());
+ }
+ assertFalse(i.hasNext());
+ assertNull(tester.logger.died);
+ }
+
+ public void testEmtpyChild() throws UnableToCompleteException, SAXException, IOException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:ListBox>");
+ b.append(" <g:item></g:item>");
+ b.append("</g:ListBox>");
+
+ String[] expected = {
+ "fieldName.addItem(\"\");" };
+
+ tester.parse(b.toString());
+
+ Iterator<String> i = tester.writer.statements.iterator();
+ for (String e : expected) {
+ assertEquals(e, i.next());
+ }
+ assertFalse(i.hasNext());
+ assertNull(tester.logger.died);
+ }
+
+ public void testInvalidChild() throws SAXException, IOException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:ListBox>");
+ b.append(" <foo/>");
+ b.append("</g:ListBox>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertNotNull(tester.logger.died);
+ }
+ }
+
+ public void testValidChild() throws UnableToCompleteException, SAXException,
+ IOException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:ListBox>");
+ b.append(" <g:item>");
+ b.append(" test item");
+ b.append(" </g:item>");
+
+ b.append(" <g:item value='testValue'>");
+ b.append(" item with test value");
+ b.append(" </g:item>");
+ b.append("</g:ListBox>");
+
+ String[] expected = {
+ "fieldName.addItem(\"test item\");",
+ "fieldName.addItem(\"item with test value\", \"testValue\");" };
+
+ tester.parse(b.toString());
+
+ Iterator<String> i = tester.writer.statements.iterator();
+ for (String e : expected) {
+ assertEquals(e, i.next());
+ }
+ assertFalse(i.hasNext());
+ assertNull(tester.logger.died);
+ }
+
+ public void testWidgetAsChild() throws SAXException, IOException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:ListBox>");
+ b.append(" <g:item>");
+ b.append(" <g:Label> Test Label </g:Label>");
+ b.append(" </g:item>");
+ b.append("</g:ListBox>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertNotNull(tester.logger.died);
+ }
+ }
+}
diff --git a/user/test/com/google/gwt/uibinder/test/UiJavaResources.java b/user/test/com/google/gwt/uibinder/test/UiJavaResources.java
index cb93041..861a0a7 100644
--- a/user/test/com/google/gwt/uibinder/test/UiJavaResources.java
+++ b/user/test/com/google/gwt/uibinder/test/UiJavaResources.java
@@ -221,6 +221,17 @@
return code;
}
};
+ public static final MockJavaResource LIST_BOX = new MockJavaResource(
+ "com.google.gwt.user.client.ui.ListBox") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package com.google.gwt.user.client.ui;\n");
+ code.append("public class ListBox extends Widget {\n");
+ code.append("}\n");
+ return code;
+ }
+ };
public static final MockJavaResource MOUSE_OVER_EVENT = new MockJavaResource(
"com.google.gwt.event.dom.client.MouseOverEvent") {
@Override
@@ -360,6 +371,7 @@
rtn.add(HAS_VERTICAL_ALIGNMENT);
rtn.add(LABEL);
rtn.add(LAYOUT_PANEL);
+ rtn.add(LIST_BOX);
rtn.add(MOUSE_OVER_EVENT);
rtn.add(MOUSE_OVER_HANDLER);
rtn.add(SPLIT_LAYOUT_PANEL);
diff --git a/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java b/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java
index e149b21..9e19e29 100644
--- a/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java
+++ b/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java
@@ -294,6 +294,14 @@
public void testFieldInPlaceholderedElement() {
assertEquals("named portions", widgetUi.spanInMsg.getInnerText());
}
+
+ public void testListBox() {
+ assertEquals(2, widgetUi.fooListBox.getItemCount());
+ assertEquals("bar", widgetUi.fooListBox.getItemText(0));
+ assertEquals("bar", widgetUi.fooListBox.getValue(0));
+ assertEquals("bar 2", widgetUi.fooListBox.getItemText(1));
+ assertEquals("bar2", widgetUi.fooListBox.getValue(1));
+ }
public void testMenuAttributes() {
assertEquals(widgetUi.dropdownMenuBar.getStyleName(),
diff --git a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java
index ca6cdb0..a74ceac 100644
--- a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java
+++ b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java
@@ -39,6 +39,7 @@
import com.google.gwt.user.client.ui.HasHTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.PushButton;
@@ -154,6 +155,7 @@
@UiField ToggleButton toggle;
@UiField HTML styleLess;
@UiField FooDialog fooDialog;
+ @UiField ListBox fooListBox;
public WidgetBasedUi() {
external.style().ensureInjected();
diff --git a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
index fb21f67..476437b 100644
--- a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
+++ b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
@@ -596,6 +596,11 @@
<gwt:Button ui:field='ok'>Okay</gwt:Button>
</gwt:HTMLPanel>
</gwt:DialogBox>
+
+ <gwt:ListBox ui:field='fooListBox'>
+ <gwt:item>bar</gwt:item>
+ <gwt:item value='bar2'>bar 2</gwt:item>
+ </gwt:ListBox>
</gwt:HTMLPanel>
</gwt:Dock>