You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

VListSelect.java 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * Copyright 2000-2018 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.v7.client.ui;
  17. import java.util.ArrayList;
  18. import java.util.HashSet;
  19. import java.util.List;
  20. import java.util.Set;
  21. import com.google.gwt.event.dom.client.ChangeEvent;
  22. import com.google.gwt.user.client.ui.ListBox;
  23. import com.vaadin.client.UIDL;
  24. import com.vaadin.shared.util.SharedUtil;
  25. public class VListSelect extends VOptionGroupBase {
  26. public static final String CLASSNAME = "v-select";
  27. private static final int VISIBLE_COUNT = 10;
  28. protected ListBox select;
  29. private int lastSelectedIndex = -1;
  30. public VListSelect() {
  31. super(new ListBox(true), CLASSNAME);
  32. select = getOptionsContainer();
  33. select.addChangeHandler(this);
  34. select.addClickHandler(this);
  35. select.setVisibleItemCount(VISIBLE_COUNT);
  36. setStyleName(CLASSNAME);
  37. updateEnabledState();
  38. }
  39. @Override
  40. public void setStyleName(String style) {
  41. super.setStyleName(style);
  42. updateStyleNames();
  43. }
  44. @Override
  45. public void setStylePrimaryName(String style) {
  46. super.setStylePrimaryName(style);
  47. updateStyleNames();
  48. }
  49. protected void updateStyleNames() {
  50. container.setStyleName(getStylePrimaryName());
  51. select.setStyleName(getStylePrimaryName() + "-select");
  52. }
  53. protected ListBox getOptionsContainer() {
  54. return (ListBox) optionsContainer;
  55. }
  56. @Override
  57. public void buildOptions(UIDL uidl) {
  58. select.setMultipleSelect(isMultiselect());
  59. Set<String> previousKeys = new HashSet<String>();
  60. for (int i = 0; i < select.getItemCount(); i++) {
  61. previousKeys.add(select.getValue(i));
  62. }
  63. int nextIndex = 0;
  64. if (!isMultiselect() && isNullSelectionAllowed()
  65. && !isNullSelectionItemAvailable()) {
  66. // can't unselect last item in singleselect mode
  67. updateOrCreateItem("", "null", nextIndex++, previousKeys);
  68. select.addItem("", (String) null);
  69. // Null select item can't be selected programmatically, but will
  70. // remain selected if it was selected by the user. There's no
  71. // need to deselect when something else is selected since it's only
  72. // used in single select mode.
  73. }
  74. for (final Object child : uidl) {
  75. final UIDL optionUidl = (UIDL) child;
  76. updateOrCreateItem(optionUidl.getStringAttribute("caption"),
  77. optionUidl.getStringAttribute("key"), nextIndex,
  78. previousKeys);
  79. if (optionUidl.hasAttribute("selected")) {
  80. select.setItemSelected(nextIndex, true);
  81. lastSelectedIndex = nextIndex;
  82. } else {
  83. select.setItemSelected(nextIndex, false);
  84. }
  85. nextIndex++;
  86. }
  87. // Remove any trailing items not in the UIDL
  88. while (select.getItemCount() > nextIndex) {
  89. select.removeItem(nextIndex);
  90. }
  91. if (getRows() > 0) {
  92. select.setVisibleItemCount(getRows());
  93. }
  94. }
  95. private void updateOrCreateItem(String caption, String key, int index,
  96. Set<String> previousKeys) {
  97. if (previousKeys.remove(key)) {
  98. while (select.getItemCount() >= index) {
  99. String keyAtIndex = select.getValue(index);
  100. if (SharedUtil.equals(key, keyAtIndex)) {
  101. select.setItemText(index, caption);
  102. return;
  103. } else {
  104. // Assume the item we're looking at has simply been removed
  105. // and that the next item will match our key
  106. select.removeItem(index);
  107. previousKeys.remove(keyAtIndex);
  108. }
  109. }
  110. }
  111. // We end up here for new items or if we removed all following items
  112. // while looking for a match
  113. select.insertItem(caption, key, index);
  114. }
  115. @Override
  116. protected String[] getSelectedItems() {
  117. final List<String> selectedItemKeys = new ArrayList<String>();
  118. for (int i = 0; i < select.getItemCount(); i++) {
  119. if (select.isItemSelected(i)) {
  120. selectedItemKeys.add(select.getValue(i));
  121. }
  122. }
  123. return selectedItemKeys.toArray(new String[selectedItemKeys.size()]);
  124. }
  125. @Override
  126. public void onChange(ChangeEvent event) {
  127. final int si = select.getSelectedIndex();
  128. if (si == -1 && !isNullSelectionAllowed()) {
  129. select.setSelectedIndex(lastSelectedIndex);
  130. } else {
  131. lastSelectedIndex = si;
  132. if (isMultiselect()) {
  133. client.updateVariable(paintableId, "selected",
  134. getSelectedItems(), isImmediate());
  135. } else {
  136. client.updateVariable(paintableId, "selected",
  137. new String[] { "" + getSelectedItem() }, isImmediate());
  138. }
  139. }
  140. }
  141. @Override
  142. public void setHeight(String height) {
  143. select.setHeight(height);
  144. super.setHeight(height);
  145. }
  146. @Override
  147. public void setWidth(String width) {
  148. select.setWidth(width);
  149. super.setWidth(width);
  150. }
  151. @Override
  152. public void setTabIndex(int tabIndex) {
  153. getOptionsContainer().setTabIndex(tabIndex);
  154. }
  155. @Override
  156. protected void updateEnabledState() {
  157. select.setEnabled(isEnabled() && !isReadonly());
  158. }
  159. @Override
  160. public void focus() {
  161. select.setFocus(true);
  162. }
  163. }