Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package javafx.scene.control.cell; 027 028import static javafx.scene.control.cell.CellUtils.createComboBox; 029import javafx.beans.property.BooleanProperty; 030import javafx.beans.property.ObjectProperty; 031import javafx.beans.property.SimpleBooleanProperty; 032import javafx.beans.property.SimpleObjectProperty; 033import javafx.collections.FXCollections; 034import javafx.collections.ObservableList; 035import javafx.scene.control.*; 036import javafx.util.Callback; 037import javafx.util.StringConverter; 038 039/** 040 * A class containing a {@link ListCell} implementation that draws a 041 * {@link ComboBox} node inside the cell. 042 * 043 * <p>By default, the ComboBoxListCell is rendered as a {@link Label} when not 044 * being edited, and as a ComboBox when in editing mode. The ComboBox will, by 045 * default, stretch to fill the entire list cell. 046 * 047 * <p>To create a ComboBoxListCell, it is necessary to provide zero or more 048 * items that will be shown to the user when the {@link ComboBox} menu is 049 * showing. These items must be of the same type as the ListView items sequence, 050 * such that upon selection, they replace the existing value in the 051 * {@link ListView#itemsProperty() items} list. 052 * 053 * @param <T> The type of the elements contained within the ListView. 054 * @since 2.2 055 */ 056public class ComboBoxListCell<T> extends ListCell<T> { 057 058 /*************************************************************************** 059 * * 060 * Static cell factories * 061 * * 062 **************************************************************************/ 063 064 /** 065 * Creates a ComboBox cell factory for use in {@link ListView} controls. By 066 * default, the ComboBoxCell is rendered as a {@link Label} when not being 067 * edited, and as a ComboBox when in editing mode. The ComboBox will, by 068 * default, stretch to fill the entire list cell. 069 * 070 * @param <T> The type of the elements contained within the ListView. 071 * @param items Zero or more items that will be shown to the user when the 072 * {@link ComboBox} menu is showing. These items must be of the same 073 * type as the ListView items list, such that upon selection, they 074 * replace the existing value in the 075 * {@link ListView#itemsProperty() items} list. 076 * @return A {@link Callback} that will return a ListCell that is able to 077 * work on the type of element contained within the ListView. 078 */ 079 public static <T> Callback<ListView<T>, ListCell<T>> forListView(final T... items) { 080 return forListView(FXCollections.observableArrayList(items)); 081 } 082 083 /** 084 * Creates a ComboBox cell factory for use in {@link ListView} controls. By 085 * default, the ComboBoxCell is rendered as a {@link Label} when not being 086 * edited, and as a ComboBox when in editing mode. The ComboBox will, by 087 * default, stretch to fill the entire list cell. 088 * 089 * @param <T> The type of the elements contained within the ListView. 090 * @param converter A {@link StringConverter} to convert the given item (of 091 * type T) to a String for displaying to the user. 092 * @param items Zero or more items that will be shown to the user when the 093 * {@link ComboBox} menu is showing. These items must be of the same 094 * type as the ListView items list, such that 095 * upon selection, they replace the existing value in the 096 * {@link ListView#itemsProperty() items} list. 097 * @return A {@link Callback} that will return a ListCell that is able to 098 * work on the type of element contained within the ListView. 099 */ 100 public static <T> Callback<ListView<T>, ListCell<T>> forListView( 101 final StringConverter<T> converter, 102 final T... items) { 103 return forListView(converter, FXCollections.observableArrayList(items)); 104 } 105 106 /** 107 * Creates a ComboBox cell factory for use in {@link ListView} controls. By 108 * default, the ComboBoxCell is rendered as a {@link Label} when not being 109 * edited, and as a ComboBox when in editing mode. The ComboBox will, by 110 * default, stretch to fill the entire list cell. 111 * 112 * @param <T> The type of the elements contained within the ListView. 113 * @param items An {@link ObservableList} containing zero or more items that 114 * will be shown to the user when the {@link ComboBox} menu is showing. 115 * These items must be of the same type as the ListView items sequence, 116 * such that upon selection, they replace the existing value in the 117 * {@link ListView#itemsProperty() items} list. 118 * @return A {@link Callback} that will return a ListCell that is able to 119 * work on the type of element contained within the ListView. 120 */ 121 public static <T> Callback<ListView<T>, ListCell<T>> forListView( 122 final ObservableList<T> items) { 123 return forListView(null, items); 124 } 125 126 /** 127 * Creates a ComboBox cell factory for use in {@link ListView} controls. By 128 * default, the ComboBoxCell is rendered as a {@link Label} when not being 129 * edited, and as a ComboBox when in editing mode. The ComboBox will, by 130 * default, stretch to fill the entire list cell. 131 * 132 * @param <T> The type of the elements contained within the ListView. 133 * @param converter A {@link StringConverter} to convert the given item (of 134 * type T) to a String for displaying to the user. 135 * @param items An {@link ObservableList} containing zero or more items that 136 * will be shown to the user when the {@link ComboBox} menu is showing. 137 * These items must be of the same type as the ListView items sequence, 138 * such that upon selection, they replace the existing value in the 139 * {@link ListView#itemsProperty() items} list. 140 * @return A {@link Callback} that will return a ListCell that is able to 141 * work on the type of element contained within the ListView. 142 */ 143 public static <T> Callback<ListView<T>, ListCell<T>> forListView( 144 final StringConverter<T> converter, 145 final ObservableList<T> items) { 146 return new Callback<ListView<T>, ListCell<T>>() { 147 @Override public ListCell<T> call(ListView<T> list) { 148 return new ComboBoxListCell<T>(converter, items); 149 } 150 }; 151 } 152 153 154 155 /*************************************************************************** 156 * * 157 * Fields * 158 * * 159 **************************************************************************/ 160 161 private final ObservableList<T> items; 162 163 private ComboBox<T> comboBox; 164 165 166 167 /*************************************************************************** 168 * * 169 * Constructors * 170 * * 171 **************************************************************************/ 172 173 /** 174 * Creates a default ComboBoxListCell with an empty items list. 175 */ 176 public ComboBoxListCell() { 177 this(FXCollections.<T>observableArrayList()); 178 } 179 180 /** 181 * Creates a default {@link ComboBoxListCell} instance with the given items 182 * being used to populate the {@link ComboBox} when it is shown. 183 * 184 * @param items The items to show in the ComboBox popup menu when selected 185 * by the user. 186 */ 187 public ComboBoxListCell(T... items) { 188 this(FXCollections.observableArrayList(items)); 189 } 190 191 /** 192 * Creates a {@link ComboBoxListCell} instance with the given items 193 * being used to populate the {@link ComboBox} when it is shown, and the 194 * {@link StringConverter} being used to convert the item in to a 195 * user-readable form. 196 * 197 * @param converter A {@link StringConverter} that can convert an item of 198 * type T into a user-readable string so that it may then be shown in 199 * the ComboBox popup menu. 200 * @param items The items to show in the ComboBox popup menu when selected 201 * by the user. 202 */ 203 public ComboBoxListCell(StringConverter<T> converter, T... items) { 204 this(converter, FXCollections.observableArrayList(items)); 205 } 206 207 /** 208 * Creates a default {@link ComboBoxListCell} instance with the given items 209 * being used to populate the {@link ComboBox} when it is shown. 210 * 211 * @param items The items to show in the ComboBox popup menu when selected 212 * by the user. 213 */ 214 public ComboBoxListCell(ObservableList<T> items) { 215 this(null, items); 216 } 217 218 /** 219 * Creates a {@link ComboBoxListCell} instance with the given items 220 * being used to populate the {@link ComboBox} when it is shown, and the 221 * {@link StringConverter} being used to convert the item in to a 222 * user-readable form. 223 * 224 * @param converter A {@link StringConverter} that can convert an item of 225 * type T into a user-readable string so that it may then be shown in 226 * the ComboBox popup menu. 227 * @param items The items to show in the ComboBox popup menu when selected 228 * by the user. 229 */ 230 public ComboBoxListCell(StringConverter<T> converter, ObservableList<T> items) { 231 this.getStyleClass().add("combo-box-list-cell"); 232 this.items = items; 233 setConverter(converter != null ? converter : CellUtils.<T>defaultStringConverter()); 234 } 235 236 237 238 /*************************************************************************** 239 * * 240 * Properties * 241 * * 242 **************************************************************************/ 243 244 // --- converter 245 private ObjectProperty<StringConverter<T>> converter = 246 new SimpleObjectProperty<StringConverter<T>>(this, "converter"); 247 248 /** 249 * The {@link StringConverter} property. 250 */ 251 public final ObjectProperty<StringConverter<T>> converterProperty() { 252 return converter; 253 } 254 255 /** 256 * Sets the {@link StringConverter} to be used in this cell. 257 */ 258 public final void setConverter(StringConverter<T> value) { 259 converterProperty().set(value); 260 } 261 262 /** 263 * Returns the {@link StringConverter} used in this cell. 264 */ 265 public final StringConverter<T> getConverter() { 266 return converterProperty().get(); 267 } 268 269 270 // --- comboBox editable 271 private BooleanProperty comboBoxEditable = 272 new SimpleBooleanProperty(this, "comboBoxEditable"); 273 274 /** 275 * A property representing whether the ComboBox, when shown to the user, 276 * is editable or not. 277 */ 278 public final BooleanProperty comboBoxEditableProperty() { 279 return comboBoxEditable; 280 } 281 282 /** 283 * Configures the ComboBox to be editable (to allow user input outside of the 284 * options provide in the dropdown list). 285 */ 286 public final void setComboBoxEditable(boolean value) { 287 comboBoxEditableProperty().set(value); 288 } 289 290 /** 291 * Returns true if the ComboBox is editable. 292 */ 293 public final boolean isComboBoxEditable() { 294 return comboBoxEditableProperty().get(); 295 } 296 297 298 299 /*************************************************************************** 300 * * 301 * Public API * 302 * * 303 **************************************************************************/ 304 305 /** 306 * Returns the items to be displayed in the ChoiceBox when it is showing. 307 */ 308 public ObservableList<T> getItems() { 309 return items; 310 } 311 312 /** {@inheritDoc} */ 313 @Override public void startEdit() { 314 if (! isEditable() || ! getListView().isEditable()) { 315 return; 316 } 317 318 if (comboBox == null) { 319 comboBox = createComboBox(this, items, getConverter()); 320 comboBox.editableProperty().bind(comboBoxEditableProperty()); 321 } 322 323 comboBox.getSelectionModel().select(getItem()); 324 325 super.startEdit(); 326 setText(null); 327 setGraphic(comboBox); 328 } 329 330 /** {@inheritDoc} */ 331 @Override public void cancelEdit() { 332 super.cancelEdit(); 333 334 setText(getConverter().toString(getItem())); 335 setGraphic(null); 336 } 337 338 /** {@inheritDoc} */ 339 @Override public void updateItem(T item, boolean empty) { 340 super.updateItem(item, empty); 341 CellUtils.updateItem(this, getConverter(), null, null, comboBox); 342 } 343}