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.event.EventHandler; 036import javafx.scene.control.ComboBox; 037import javafx.scene.control.Label; 038import javafx.scene.control.TreeTableCell; 039import javafx.scene.control.TreeTableColumn; 040import javafx.util.Callback; 041import javafx.util.StringConverter; 042 043/** 044 * A class containing a {@link TreeTableCell} implementation that draws a 045 * {@link ComboBox} node inside the cell. 046 * 047 * <p>By default, the ComboBoxTreeTableCell is rendered as a {@link Label} when not 048 * being edited, and as a ComboBox when in editing mode. The ComboBox will, by 049 * default, stretch to fill the entire table cell. 050 * 051 * <p>To create a ComboBoxTreeTableCell, it is necessary to provide zero or more 052 * items that will be shown to the user when the {@link ComboBox} menu is 053 * showing. These items must be of the same type as the TreeTableColumn. 054 * 055 * @param <T> The type of the elements contained within the TreeTableColumn. 056 * @since 8.0 057 */ 058public class ComboBoxTreeTableCell<S,T> extends TreeTableCell<S,T> { 059 060 /*************************************************************************** 061 * * 062 * Static cell factories * 063 * * 064 **************************************************************************/ 065 066 /** 067 * Creates a ComboBox cell factory for use in {@link TreeTableColumn} controls. 068 * By default, the ComboBoxCell is rendered as a {@link Label} when not 069 * being edited, and as a ComboBox when in editing mode. The ComboBox will, 070 * by default, stretch to fill the entire list cell. 071 * 072 * @param <T> The type of the elements contained within the TreeTableColumn. 073 * @param items Zero or more items that will be shown to the user when the 074 * {@link ComboBox} menu is showing. These items must be of the same 075 * type as the TreeTableColumn. Note that it is up to the developer to set 076 * {@link EventHandler event handlers} to listen to edit events in the 077 * TreeTableColumn, and react accordingly. Methods of interest include 078 * {@link TreeTableColumn#setOnEditStart(javafx.event.EventHandler) setOnEditStart}, 079 * {@link TreeTableColumn#setOnEditCommit(javafx.event.EventHandler) setOnEditCommit}, 080 * and {@link TreeTableColumn#setOnEditCancel(javafx.event.EventHandler) setOnEditCancel}. 081 * @return A {@link Callback} that will return a TreeTableCell that is able to 082 * work on the type of element contained within the TreeTableColumn. 083 */ 084 public static <S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> forTreeTableColumn( 085 final T... items) { 086 return forTreeTableColumn(null, items); 087 } 088 089 /** 090 * Creates a ComboBox cell factory for use in {@link TreeTableColumn} controls. 091 * By default, the ComboBoxCell is rendered as a {@link Label} when not 092 * being edited, and as a ComboBox when in editing mode. The ComboBox will, 093 * by default, stretch to fill the entire list cell. 094 * 095 * @param <T> The type of the elements contained within the TreeTableColumn. 096 * @param converter A {@link StringConverter} to convert the given item (of 097 * type T) to a String for displaying to the user. 098 * @param items Zero or more items that will be shown to the user when the 099 * {@link ComboBox} menu is showing. These items must be of the same 100 * type as the TreeTableColumn. Note that it is up to the developer to set 101 * {@link EventHandler event handlers} to listen to edit events in the 102 * TreeTableColumn, and react accordingly. Methods of interest include 103 * {@link TreeTableColumn#setOnEditStart(javafx.event.EventHandler) setOnEditStart}, 104 * {@link TreeTableColumn#setOnEditCommit(javafx.event.EventHandler) setOnEditCommit}, 105 * and {@link TreeTableColumn#setOnEditCancel(javafx.event.EventHandler) setOnEditCancel}. 106 * @return A {@link Callback} that will return a TreeTableCell that is able to 107 * work on the type of element contained within the TreeTableColumn. 108 */ 109 public static <S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> forTreeTableColumn( 110 final StringConverter<T> converter, 111 final T... items) { 112 return forTreeTableColumn(converter, FXCollections.observableArrayList(items)); 113 } 114 115 /** 116 * Creates a ComboBox cell factory for use in {@link TreeTableColumn} controls. 117 * By default, the ComboBoxCell is rendered as a {@link Label} when not 118 * being edited, and as a ComboBox when in editing mode. The ComboBox will, 119 * by default, stretch to fill the entire list cell. 120 * 121 * @param <T> The type of the elements contained within the TreeTableColumn. 122 * @param items Zero or more items that will be shown to the user when the 123 * {@link ComboBox} menu is showing. These items must be of the same 124 * type as the TreeTableColumn. Note that it is up to the developer to set 125 * {@link EventHandler event handlers} to listen to edit events in the 126 * TreeTableColumn, and react accordingly. Methods of interest include 127 * {@link TreeTableColumn#setOnEditStart(javafx.event.EventHandler) setOnEditStart}, 128 * {@link TreeTableColumn#setOnEditCommit(javafx.event.EventHandler) setOnEditCommit}, 129 * and {@link TreeTableColumn#setOnEditCancel(javafx.event.EventHandler) setOnEditCancel}. 130 * @return A {@link Callback} that will return a TreeTableCell that is able to 131 * work on the type of element contained within the TreeTableColumn. 132 */ 133 public static <S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> forTreeTableColumn( 134 final ObservableList<T> items) { 135 return forTreeTableColumn(null, items); 136 } 137 138 /** 139 * Creates a ComboBox cell factory for use in {@link TreeTableColumn} controls. 140 * By default, the ComboBoxCell is rendered as a {@link Label} when not 141 * being edited, and as a ComboBox when in editing mode. The ComboBox will, 142 * by default, stretch to fill the entire list cell. 143 * 144 * @param <T> The type of the elements contained within the TreeTableColumn. 145 * @param converter A {@link StringConverter} to convert the given item (of 146 * type T) to a String for displaying to the user. 147 * @param items Zero or more items that will be shown to the user when the 148 * {@link ComboBox} menu is showing. These items must be of the same 149 * type as the TreeTableColumn. Note that it is up to the developer to set 150 * {@link EventHandler event handlers} to listen to edit events in the 151 * TreeTableColumn, and react accordingly. Methods of interest include 152 * {@link TreeTableColumn#setOnEditStart(javafx.event.EventHandler) setOnEditStart}, 153 * {@link TreeTableColumn#setOnEditCommit(javafx.event.EventHandler) setOnEditCommit}, 154 * and {@link TreeTableColumn#setOnEditCancel(javafx.event.EventHandler) setOnEditCancel}. 155 * @return A {@link Callback} that will return a TreeTableCell that is able to 156 * work on the type of element contained within the TreeTableColumn. 157 */ 158 public static <S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> forTreeTableColumn( 159 final StringConverter<T> converter, 160 final ObservableList<T> items) { 161 return new Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>>() { 162 @Override public TreeTableCell<S,T> call(TreeTableColumn<S,T> list) { 163 return new ComboBoxTreeTableCell<S,T>(converter, items); 164 } 165 }; 166 } 167 168 169 170 /*************************************************************************** 171 * * 172 * Fields * 173 * * 174 **************************************************************************/ 175 176 private final ObservableList<T> items; 177 178 private ComboBox<T> comboBox; 179 180 181 182 /*************************************************************************** 183 * * 184 * Constructors * 185 * * 186 **************************************************************************/ 187 188 /** 189 * Creates a default ComboBoxTreeTableCell with an empty items list. 190 */ 191 public ComboBoxTreeTableCell() { 192 this(FXCollections.<T>observableArrayList()); 193 } 194 195 /** 196 * Creates a default {@link ComboBoxTreeTableCell} instance with the given items 197 * being used to populate the {@link ComboBox} when it is shown. 198 * 199 * @param items The items to show in the ComboBox popup menu when selected 200 * by the user. 201 */ 202 public ComboBoxTreeTableCell(T... items) { 203 this(FXCollections.observableArrayList(items)); 204 } 205 206 /** 207 * Creates a {@link ComboBoxTreeTableCell} instance with the given items 208 * being used to populate the {@link ComboBox} when it is shown, and the 209 * {@link StringConverter} being used to convert the item in to a 210 * user-readable form. 211 * 212 * @param converter A {@link StringConverter} that can convert an item of type T 213 * into a user-readable string so that it may then be shown in the 214 * ComboBox popup menu. 215 * @param items The items to show in the ComboBox popup menu when selected 216 * by the user. 217 */ 218 public ComboBoxTreeTableCell(StringConverter<T> converter, T... items) { 219 this(converter, FXCollections.observableArrayList(items)); 220 } 221 222 /** 223 * Creates a default {@link ComboBoxTreeTableCell} instance with the given items 224 * being used to populate the {@link ComboBox} when it is shown. 225 * 226 * @param items The items to show in the ComboBox popup menu when selected 227 * by the user. 228 */ 229 public ComboBoxTreeTableCell(ObservableList<T> items) { 230 this(null, items); 231 } 232 233 /** 234 * Creates a {@link ComboBoxTreeTableCell} instance with the given items 235 * being used to populate the {@link ComboBox} when it is shown, and the 236 * {@link StringConverter} being used to convert the item in to a 237 * user-readable form. 238 * 239 * @param converter A {@link StringConverter} that can convert an item of type T 240 * into a user-readable string so that it may then be shown in the 241 * ComboBox popup menu. 242 * @param items The items to show in the ComboBox popup menu when selected 243 * by the user. 244 */ 245 public ComboBoxTreeTableCell(StringConverter<T> converter, ObservableList<T> items) { 246 this.getStyleClass().add("combo-box-tree-table-cell"); 247 this.items = items; 248 setConverter(converter != null ? converter : CellUtils.<T>defaultStringConverter()); 249 } 250 251 252 253 /*************************************************************************** 254 * * 255 * Properties * 256 * * 257 **************************************************************************/ 258 259 // --- converter 260 private ObjectProperty<StringConverter<T>> converter = 261 new SimpleObjectProperty<StringConverter<T>>(this, "converter"); 262 263 /** 264 * The {@link StringConverter} property. 265 */ 266 public final ObjectProperty<StringConverter<T>> converterProperty() { 267 return converter; 268 } 269 270 /** 271 * Sets the {@link StringConverter} to be used in this cell. 272 */ 273 public final void setConverter(StringConverter<T> value) { 274 converterProperty().set(value); 275 } 276 277 /** 278 * Returns the {@link StringConverter} used in this cell. 279 */ 280 public final StringConverter<T> getConverter() { 281 return converterProperty().get(); 282 } 283 284 285 // --- comboBox editable 286 private BooleanProperty comboBoxEditable = 287 new SimpleBooleanProperty(this, "comboBoxEditable"); 288 289 /** 290 * A property representing whether the ComboBox, when shown to the user, 291 * is editable or not. 292 */ 293 public final BooleanProperty comboBoxEditableProperty() { 294 return comboBoxEditable; 295 } 296 297 /** 298 * Configures the ComboBox to be editable (to allow user input outside of the 299 * options provide in the dropdown list). 300 */ 301 public final void setComboBoxEditable(boolean value) { 302 comboBoxEditableProperty().set(value); 303 } 304 305 /** 306 * Returns true if the ComboBox is editable. 307 */ 308 public final boolean isComboBoxEditable() { 309 return comboBoxEditableProperty().get(); 310 } 311 312 313 314 /*************************************************************************** 315 * * 316 * Public API * 317 * * 318 **************************************************************************/ 319 320 /** 321 * Returns the items to be displayed in the ChoiceBox when it is showing. 322 */ 323 public ObservableList<T> getItems() { 324 return items; 325 } 326 327 /** {@inheritDoc} */ 328 @Override public void startEdit() { 329 if (! isEditable() || ! getTreeTableView().isEditable() || ! getTableColumn().isEditable()) { 330 return; 331 } 332 333 if (comboBox == null) { 334 comboBox = createComboBox(this, items, getConverter()); 335 comboBox.editableProperty().bind(comboBoxEditableProperty()); 336 } 337 338 comboBox.getSelectionModel().select(getItem()); 339 340 super.startEdit(); 341 setText(null); 342 setGraphic(comboBox); 343 } 344 345 /** {@inheritDoc} */ 346 @Override public void cancelEdit() { 347 super.cancelEdit(); 348 349 setText(getConverter().toString(getItem())); 350 setGraphic(null); 351 } 352 353 /** {@inheritDoc} */ 354 @Override public void updateItem(T item, boolean empty) { 355 super.updateItem(item, empty); 356 CellUtils.updateItem(this, getConverter(), null, null, comboBox); 357 } 358}