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