From: Jouni Koivuviita Date: Fri, 15 Jun 2007 13:48:32 +0000 (+0000) Subject: Select component now has an abstract superclass IOptionGroupBase and two implementati... X-Git-Tag: 6.7.0.beta1~6236 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=f995b31513e6269ffd6248f5a8478277258cb199;p=vaadin-framework.git Select component now has an abstract superclass IOptionGroupBase and two implementations: ISelect (dropdown mode) and IOptionGroup (optiongroup style). New item allowed also implemented. svn changeset:1751/svn branch:trunk --- diff --git a/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java b/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java index ee4a009b3e..08a58fa62a 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java @@ -2,16 +2,16 @@ package com.itmill.toolkit.terminal.gwt.client; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.ui.Widget; -import com.itmill.toolkit.terminal.gwt.client.ui.ICustomLayout; -import com.itmill.toolkit.terminal.gwt.client.ui.IPasswordField; import com.itmill.toolkit.terminal.gwt.client.ui.IButton; import com.itmill.toolkit.terminal.gwt.client.ui.ICheckBox; +import com.itmill.toolkit.terminal.gwt.client.ui.ICustomLayout; import com.itmill.toolkit.terminal.gwt.client.ui.IEmbedded; import com.itmill.toolkit.terminal.gwt.client.ui.IGridLayout; import com.itmill.toolkit.terminal.gwt.client.ui.IHorizontalLayout; import com.itmill.toolkit.terminal.gwt.client.ui.ILabel; -import com.itmill.toolkit.terminal.gwt.client.ui.IVerticalLayout; +import com.itmill.toolkit.terminal.gwt.client.ui.IOptionGroup; import com.itmill.toolkit.terminal.gwt.client.ui.IPanel; +import com.itmill.toolkit.terminal.gwt.client.ui.IPasswordField; import com.itmill.toolkit.terminal.gwt.client.ui.ISelect; import com.itmill.toolkit.terminal.gwt.client.ui.ITable; import com.itmill.toolkit.terminal.gwt.client.ui.ITabsheet; @@ -19,6 +19,7 @@ import com.itmill.toolkit.terminal.gwt.client.ui.ITextArea; import com.itmill.toolkit.terminal.gwt.client.ui.ITextField; import com.itmill.toolkit.terminal.gwt.client.ui.ITree; import com.itmill.toolkit.terminal.gwt.client.ui.IUnknownComponent; +import com.itmill.toolkit.terminal.gwt.client.ui.IVerticalLayout; import com.itmill.toolkit.terminal.gwt.client.ui.IWindow; public class DefaultWidgetFactory implements WidgetFactory { @@ -46,8 +47,11 @@ public class DefaultWidgetFactory implements WidgetFactory { return new IGridLayout(); if ("tree".equals(tag)) return new ITree(); - if ("select".equals(tag)) + if ("select".equals(tag)) { + if("optiongroup".equals(uidl.getStringAttribute("style"))) + return new IOptionGroup(); return new ISelect(); + } if ("panel".equals(tag) || "component".equals(tag)) return new IPanel(); if ("tabsheet".equals(tag)) diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IButton.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IButton.java index d40c55caff..8273a75366 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IButton.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IButton.java @@ -2,12 +2,12 @@ package com.itmill.toolkit.terminal.gwt.client.ui; import com.google.gwt.user.client.ui.ClickListener; import com.google.gwt.user.client.ui.Widget; +import com.google.gwt.user.client.ui.Button; import com.itmill.toolkit.terminal.gwt.client.Client; import com.itmill.toolkit.terminal.gwt.client.Paintable; import com.itmill.toolkit.terminal.gwt.client.UIDL; -public class IButton extends com.google.gwt.user.client.ui.Button implements - Paintable { +public class IButton extends Button implements Paintable { String id; diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IOptionGroup.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IOptionGroup.java new file mode 100644 index 0000000000..b85368ff8f --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IOptionGroup.java @@ -0,0 +1,68 @@ +package com.itmill.toolkit.terminal.gwt.client.ui; + +import java.util.Iterator; + +import com.google.gwt.user.client.ui.CheckBox; +import com.google.gwt.user.client.ui.Panel; +import com.google.gwt.user.client.ui.RadioButton; +import com.google.gwt.user.client.ui.Widget; +import com.itmill.toolkit.terminal.gwt.client.UIDL; + +public class IOptionGroup extends IOptionGroupBase { + + private static final String CLASSNAME = "i-select-optiongroup"; + + private Panel panel; + + public IOptionGroup() { + super(CLASSNAME); + panel = (Panel) optionsContainer; + } + + /* + * Return true if no elements were changed, false otherwise. + */ + protected void buildOptions(UIDL uidl) { + panel.clear(); + for(Iterator it = uidl.getChildIterator(); it.hasNext();) { + UIDL opUidl = (UIDL) it.next(); + CheckBox op; + if(multiselect) { + op = new ICheckBox(); + op.setText(opUidl.getStringAttribute("caption")); + } else { + op = new RadioButton(id, opUidl.getStringAttribute("caption")); + } + op.setStyleName(CLASSNAME_OPTION); + op.setChecked(opUidl.getBooleanAttribute("selected")); + op.setEnabled(!opUidl.getBooleanAttribute("disabled") && !readonly && !disabled); + op.addClickListener(this); + optionsToKeys.put(op, opUidl.getStringAttribute("key")); + panel.add(op); + } + } + + protected Object getSelectedItem() { + if(getSelectedItems().length > 0) + return getSelectedItems()[0]; + else + return null; + } + + protected Object[] getSelectedItems() { + return selectedKeys.toArray(); + } + + public void onClick(Widget sender) { + super.onClick(sender); + if(sender instanceof CheckBox) { + boolean selected = ((CheckBox) sender).isChecked(); + String key = (String) optionsToKeys.get(sender); + if(!multiselect) selectedKeys.clear(); + if(selected) selectedKeys.add(key); + else selectedKeys.remove(key); + client.updateVariable(id, "selected", getSelectedItems(), immediate); + } + } + +} diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IOptionGroupBase.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IOptionGroupBase.java new file mode 100644 index 0000000000..571a803e96 --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IOptionGroupBase.java @@ -0,0 +1,129 @@ +package com.itmill.toolkit.terminal.gwt.client.ui; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import com.google.gwt.user.client.ui.ChangeListener; +import com.google.gwt.user.client.ui.ClickListener; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.Panel; +import com.google.gwt.user.client.ui.Widget; +import com.itmill.toolkit.terminal.gwt.client.Client; +import com.itmill.toolkit.terminal.gwt.client.Paintable; +import com.itmill.toolkit.terminal.gwt.client.UIDL; + +abstract class IOptionGroupBase extends Composite implements Paintable, ClickListener, ChangeListener { + + static final String CLASSNAME_OPTION = "i-select-option"; + + Client client; + + String id; + + protected boolean immediate; + + protected Map optionsToKeys; + + protected Set selectedKeys; + + protected boolean multiselect; + + protected boolean disabled; + + protected boolean readonly; + + /** + * Widget holding the different options + * (e.g. ListBox or Panel for radio buttons) + * (optional, fallbacks to container Panel) + */ + protected Widget optionsContainer; + + /** + * Panel containing the component + */ + private Panel container; + + private ITextField newItemField; + + private IButton newItemButton; + + public IOptionGroupBase(String classname) { + container = new FlowPanel(); + initWidget(container); + optionsContainer = container; + container.setStyleName(classname); + immediate = false; + multiselect = false; + optionsToKeys = new HashMap(); + } + + /* Call this if you wish to specify your own container + * for the option elements (e.g. SELECT) + */ + public IOptionGroupBase(Widget w, String classname) { + this(classname); + optionsContainer = w; + container.add(optionsContainer); + } + + public void updateFromUIDL(UIDL uidl, Client client) { + this.client = client; + this.id = uidl.getId(); + + if(client.updateComponent(this, uidl, true)) + return; + + selectedKeys = uidl.getStringArrayVariableAsSet("selected"); + + readonly = uidl.getBooleanAttribute("readonly"); + disabled = uidl.getBooleanAttribute("disabled"); + multiselect = "multi".equals(uidl.getStringAttribute("selectmode")); + + UIDL ops = uidl.getChildUIDL(0); + + buildOptions(ops); + + if(uidl.getBooleanAttribute("allownewitem")) { + if(newItemField == null) { + newItemButton = new IButton(); + newItemButton.setText("+"); + newItemButton.addClickListener(this); + newItemField = new ITextField(); + } + newItemField.setEnabled(!disabled && !readonly); + newItemButton.setEnabled(!disabled && !readonly); + + if(newItemField != null && newItemField.getParent() == container) + return; + container.add(newItemField); + container.add(newItemButton); + } else if(newItemField != null) { + container.remove(newItemField); + container.remove(newItemButton); + } + + } + + public void onClick(Widget sender) { + if(sender == newItemButton && !newItemField.getText().equals("")) + client.updateVariable(id, "newitem", newItemField.getText(), true); + } + + public void onChange(Widget sender) { + if(multiselect) { + client.updateVariable(id, "selected", getSelectedItems(), immediate); + } else { + client.updateVariable(id, "selected", new String[] { "" + getSelectedItem()}, immediate); + } + } + + protected abstract void buildOptions(UIDL uidl); + + protected abstract Object[] getSelectedItems(); + + protected abstract Object getSelectedItem(); + +} diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ISelect.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ISelect.java index d3000d1c84..18a398dba2 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/ISelect.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/ISelect.java @@ -3,65 +3,35 @@ package com.itmill.toolkit.terminal.gwt.client.ui; import java.util.Iterator; import java.util.Vector; -import com.google.gwt.user.client.ui.ChangeListener; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ListBox; -import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; -import com.itmill.toolkit.terminal.gwt.client.Client; -import com.itmill.toolkit.terminal.gwt.client.Paintable; import com.itmill.toolkit.terminal.gwt.client.UIDL; -public class ISelect extends Composite implements Paintable, ChangeListener { +public class ISelect extends IOptionGroupBase { - Label caption = new Label(); - ListBox select = new ListBox(); - private Client client; - private String id; - private boolean immediate; + private static final String CLASSNAME = "i-select"; + private ListBox select; public ISelect() { - VerticalPanel panel = new VerticalPanel(); - panel.add(caption); - panel.add(select); + super(new ListBox(), CLASSNAME); + select = (ListBox) optionsContainer; select.addChangeListener(this); - initWidget(panel); } - public void updateFromUIDL(UIDL uidl, Client client) { - this.client = client; - this.id = uidl.getStringAttribute("id"); - this.immediate = uidl.getBooleanAttribute("immediate"); - - if (uidl.hasAttribute("caption")) caption.setText(uidl.getStringAttribute("caption")); - - if(uidl.hasAttribute("selectmode")) - select.setMultipleSelect(true); - else - select.setMultipleSelect(false); - - UIDL options = uidl.getChildUIDL(0); - + protected void buildOptions(UIDL uidl) { + select.setMultipleSelect(multiselect); + select.setEnabled(!disabled && !readonly); select.clear(); - for (Iterator i = options.getChildIterator(); i.hasNext();) { + for (Iterator i = uidl.getChildIterator(); i.hasNext();) { UIDL optionUidl = (UIDL)i.next(); select.addItem(optionUidl.getStringAttribute("caption"), optionUidl.getStringAttribute("key")); if(optionUidl.hasAttribute("selected")) select.setItemSelected(select.getItemCount()-1, true); } } - - public void onChange(Widget sender) { - if(select.isMultipleSelect()) { - client.updateVariable(id, "selected", getSelectedKeys(), immediate); - } else { - client.updateVariable(id, "selected", new String[] { "" + select.getValue(select.getSelectedIndex())}, immediate); - } - } - private Object[] getSelectedKeys() { + protected Object[] getSelectedItems() { Vector selectedItemKeys = new Vector(); for(int i = 0; i < select.getItemCount();i++) { if(select.isItemSelected(i)) @@ -69,4 +39,18 @@ public class ISelect extends Composite implements Paintable, ChangeListener { } return selectedItemKeys.toArray(); } + + protected Object getSelectedItem() { + if(getSelectedItems().length > 0) + return getSelectedItems()[0]; + else + return null; + } + + public void onChange(Widget sender) { + if(select.isMultipleSelect()) + client.updateVariable(id, "selected", getSelectedItems(), immediate); + else + client.updateVariable(id, "selected", new String[] { "" + getSelectedItem()}, immediate); + } } diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITextField.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ITextField.java index e7254ce99e..711fb3da06 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITextField.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/ITextField.java @@ -29,9 +29,9 @@ public class ITextField extends TextBoxBase implements */ private static final String CLASSNAME_FOCUS = "i-textfield-focus"; - private String id; + protected String id; - private Client client; + protected Client client; private boolean immediate = false; @@ -64,7 +64,8 @@ public class ITextField extends TextBoxBase implements } public void onChange(Widget sender) { - client.updateVariable(id, "text", getText() , immediate); + if(client != null && id != null) + client.updateVariable(id, "text", getText() , immediate); } public void onFocus(Widget sender) { diff --git a/src/com/itmill/toolkit/terminal/gwt/public/component-themes/collection.css b/src/com/itmill/toolkit/terminal/gwt/public/component-themes/collection.css index 4cdd3d0db2..1b08bcd2dc 100644 --- a/src/com/itmill/toolkit/terminal/gwt/public/component-themes/collection.css +++ b/src/com/itmill/toolkit/terminal/gwt/public/component-themes/collection.css @@ -1,2 +1,3 @@ @import "common/css/common.css"; -@import "textfield/css/textfield.css"; \ No newline at end of file +@import "textfield/css/textfield.css"; +@import "select/css/select.css"; \ No newline at end of file diff --git a/src/com/itmill/toolkit/terminal/gwt/public/component-themes/common/css/common.css b/src/com/itmill/toolkit/terminal/gwt/public/component-themes/common/css/common.css index def46157a5..8f82f870a4 100644 --- a/src/com/itmill/toolkit/terminal/gwt/public/component-themes/common/css/common.css +++ b/src/com/itmill/toolkit/terminal/gwt/public/component-themes/common/css/common.css @@ -4,4 +4,14 @@ body { color: #222; font-size: 62.5%; line-height: 1.4em; +} + +input, select, textarea, button { + font-family: helvetica, verdana, tahoma, arial, sans-serif; + font-size: 1.1em; +} + +select { + padding: 0; + margin: 0; } \ No newline at end of file diff --git a/src/com/itmill/toolkit/terminal/gwt/public/component-themes/select/css/select.css b/src/com/itmill/toolkit/terminal/gwt/public/component-themes/select/css/select.css new file mode 100644 index 0000000000..710bfa1de5 --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/public/component-themes/select/css/select.css @@ -0,0 +1,15 @@ +.i-select { + +} + +.i-select-option { + +} + +.i-select-optiongroup { + +} + +.i-select-optiongroup .i-select-option { + display: block; +} \ No newline at end of file diff --git a/src/com/itmill/toolkit/terminal/gwt/public/component-themes/textfield/css/textfield.css b/src/com/itmill/toolkit/terminal/gwt/public/component-themes/textfield/css/textfield.css index 2e51616487..c1cf6d8334 100644 --- a/src/com/itmill/toolkit/terminal/gwt/public/component-themes/textfield/css/textfield.css +++ b/src/com/itmill/toolkit/terminal/gwt/public/component-themes/textfield/css/textfield.css @@ -1,5 +1,4 @@ .i-textfield{ - font-family: helvetica, verdana, tahoma, arial, sans-serif; /* Copy from common.css */ font-size: 1.2em; color: #444; background: #fff url(../img/bg.png) repeat-x;