35 import javafx.event.EventHandler;
36 import javafx.scene.control.ComboBox;
37 import javafx.scene.control.Label;
38 import javafx.scene.control.TreeTableCell;
39 import javafx.scene.control.TreeTableColumn;
40 import javafx.util.Callback;
41 import javafx.util.StringConverter;
42
43 /**
44 * A class containing a {@link TreeTableCell} implementation that draws a
45 * {@link ComboBox} node inside the cell.
46 *
47 * <p>By default, the ComboBoxTreeTableCell is rendered as a {@link Label} when not
48 * being edited, and as a ComboBox when in editing mode. The ComboBox will, by
49 * default, stretch to fill the entire table cell.
50 *
51 * <p>To create a ComboBoxTreeTableCell, it is necessary to provide zero or more
52 * items that will be shown to the user when the {@link ComboBox} menu is
53 * showing. These items must be of the same type as the TreeTableColumn.
54 *
55 * @param <T> The type of the elements contained within the TreeTableColumn.
56 * @since JavaFX 8.0
57 */
58 public class ComboBoxTreeTableCell<S,T> extends TreeTableCell<S,T> {
59
60 /***************************************************************************
61 * *
62 * Static cell factories *
63 * *
64 **************************************************************************/
65
66 /**
67 * Creates a ComboBox cell factory for use in {@link TreeTableColumn} controls.
68 * By default, the ComboBoxCell is rendered as a {@link Label} when not
69 * being edited, and as a ComboBox when in editing mode. The ComboBox will,
70 * by default, stretch to fill the entire list cell.
71 *
72 * @param <T> The type of the elements contained within the TreeTableColumn.
73 * @param items Zero or more items that will be shown to the user when the
74 * {@link ComboBox} menu is showing. These items must be of the same
75 * type as the TreeTableColumn. Note that it is up to the developer to set
76 * {@link EventHandler event handlers} to listen to edit events in the
77 * TreeTableColumn, and react accordingly. Methods of interest include
78 * {@link TreeTableColumn#setOnEditStart(javafx.event.EventHandler) setOnEditStart},
79 * {@link TreeTableColumn#setOnEditCommit(javafx.event.EventHandler) setOnEditCommit},
80 * and {@link TreeTableColumn#setOnEditCancel(javafx.event.EventHandler) setOnEditCancel}.
81 * @return A {@link Callback} that will return a TreeTableCell that is able to
82 * work on the type of element contained within the TreeTableColumn.
83 */
84 @SafeVarargs
85 public static <S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> forTreeTableColumn(
86 final T... items) {
87 return forTreeTableColumn(null, items);
88 }
89
90 /**
91 * Creates a ComboBox cell factory for use in {@link TreeTableColumn} controls.
92 * By default, the ComboBoxCell is rendered as a {@link Label} when not
93 * being edited, and as a ComboBox when in editing mode. The ComboBox will,
94 * by default, stretch to fill the entire list cell.
95 *
96 * @param <T> The type of the elements contained within the TreeTableColumn.
97 * @param converter A {@link StringConverter} to convert the given item (of
98 * type T) to a String for displaying to the user.
99 * @param items Zero or more items that will be shown to the user when the
100 * {@link ComboBox} menu is showing. These items must be of the same
101 * type as the TreeTableColumn. Note that it is up to the developer to set
102 * {@link EventHandler event handlers} to listen to edit events in the
103 * TreeTableColumn, and react accordingly. Methods of interest include
104 * {@link TreeTableColumn#setOnEditStart(javafx.event.EventHandler) setOnEditStart},
105 * {@link TreeTableColumn#setOnEditCommit(javafx.event.EventHandler) setOnEditCommit},
106 * and {@link TreeTableColumn#setOnEditCancel(javafx.event.EventHandler) setOnEditCancel}.
107 * @return A {@link Callback} that will return a TreeTableCell that is able to
108 * work on the type of element contained within the TreeTableColumn.
109 */
110 @SafeVarargs
111 public static <S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> forTreeTableColumn(
112 final StringConverter<T> converter,
113 final T... items) {
114 return forTreeTableColumn(converter, FXCollections.observableArrayList(items));
115 }
116
117 /**
118 * Creates a ComboBox cell factory for use in {@link TreeTableColumn} controls.
119 * By default, the ComboBoxCell is rendered as a {@link Label} when not
120 * being edited, and as a ComboBox when in editing mode. The ComboBox will,
121 * by default, stretch to fill the entire list cell.
122 *
123 * @param <T> The type of the elements contained within the TreeTableColumn.
124 * @param items Zero or more items that will be shown to the user when the
125 * {@link ComboBox} menu is showing. These items must be of the same
126 * type as the TreeTableColumn. Note that it is up to the developer to set
127 * {@link EventHandler event handlers} to listen to edit events in the
128 * TreeTableColumn, and react accordingly. Methods of interest include
129 * {@link TreeTableColumn#setOnEditStart(javafx.event.EventHandler) setOnEditStart},
130 * {@link TreeTableColumn#setOnEditCommit(javafx.event.EventHandler) setOnEditCommit},
131 * and {@link TreeTableColumn#setOnEditCancel(javafx.event.EventHandler) setOnEditCancel}.
132 * @return A {@link Callback} that will return a TreeTableCell that is able to
133 * work on the type of element contained within the TreeTableColumn.
134 */
135 public static <S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> forTreeTableColumn(
136 final ObservableList<T> items) {
137 return forTreeTableColumn(null, items);
138 }
139
140 /**
141 * Creates a ComboBox cell factory for use in {@link TreeTableColumn} controls.
142 * By default, the ComboBoxCell is rendered as a {@link Label} when not
143 * being edited, and as a ComboBox when in editing mode. The ComboBox will,
144 * by default, stretch to fill the entire list cell.
145 *
146 * @param <T> The type of the elements contained within the TreeTableColumn.
147 * @param converter A {@link StringConverter} to convert the given item (of
148 * type T) to a String for displaying to the user.
149 * @param items Zero or more items that will be shown to the user when the
150 * {@link ComboBox} menu is showing. These items must be of the same
151 * type as the TreeTableColumn. Note that it is up to the developer to set
152 * {@link EventHandler event handlers} to listen to edit events in the
153 * TreeTableColumn, and react accordingly. Methods of interest include
154 * {@link TreeTableColumn#setOnEditStart(javafx.event.EventHandler) setOnEditStart},
155 * {@link TreeTableColumn#setOnEditCommit(javafx.event.EventHandler) setOnEditCommit},
156 * and {@link TreeTableColumn#setOnEditCancel(javafx.event.EventHandler) setOnEditCancel}.
157 * @return A {@link Callback} that will return a TreeTableCell that is able to
158 * work on the type of element contained within the TreeTableColumn.
159 */
160 public static <S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> forTreeTableColumn(
161 final StringConverter<T> converter,
162 final ObservableList<T> items) {
163 return list -> new ComboBoxTreeTableCell<S,T>(converter, items);
164 }
165
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, converterProperty());
335 comboBox.editableProperty().bind(comboBoxEditableProperty());
336 }
337
338 comboBox.getSelectionModel().select(getItem());
339
340 super.startEdit();
341 setText(null);
|
35 import javafx.event.EventHandler;
36 import javafx.scene.control.ComboBox;
37 import javafx.scene.control.Label;
38 import javafx.scene.control.TreeTableCell;
39 import javafx.scene.control.TreeTableColumn;
40 import javafx.util.Callback;
41 import javafx.util.StringConverter;
42
43 /**
44 * A class containing a {@link TreeTableCell} implementation that draws a
45 * {@link ComboBox} node inside the cell.
46 *
47 * <p>By default, the ComboBoxTreeTableCell is rendered as a {@link Label} when not
48 * being edited, and as a ComboBox when in editing mode. The ComboBox will, by
49 * default, stretch to fill the entire table cell.
50 *
51 * <p>To create a ComboBoxTreeTableCell, it is necessary to provide zero or more
52 * items that will be shown to the user when the {@link ComboBox} menu is
53 * showing. These items must be of the same type as the TreeTableColumn.
54 *
55 * @param <S> The type of the TableView generic type
56 * @param <T> The type of the elements contained within the TreeTableColumn.
57 * @since JavaFX 8.0
58 */
59 public class ComboBoxTreeTableCell<S,T> extends TreeTableCell<S,T> {
60
61 /***************************************************************************
62 * *
63 * Static cell factories *
64 * *
65 **************************************************************************/
66
67 /**
68 * Creates a ComboBox cell factory for use in {@link TreeTableColumn} controls.
69 * By default, the ComboBoxCell is rendered as a {@link Label} when not
70 * being edited, and as a ComboBox when in editing mode. The ComboBox will,
71 * by default, stretch to fill the entire list cell.
72 *
73 * @param <S> The type of the TableView generic type
74 * @param <T> The type of the elements contained within the TreeTableColumn.
75 * @param items Zero or more items that will be shown to the user when the
76 * {@link ComboBox} menu is showing. These items must be of the same
77 * type as the TreeTableColumn. Note that it is up to the developer to set
78 * {@link EventHandler event handlers} to listen to edit events in the
79 * TreeTableColumn, and react accordingly. Methods of interest include
80 * {@link TreeTableColumn#setOnEditStart(javafx.event.EventHandler) setOnEditStart},
81 * {@link TreeTableColumn#setOnEditCommit(javafx.event.EventHandler) setOnEditCommit},
82 * and {@link TreeTableColumn#setOnEditCancel(javafx.event.EventHandler) setOnEditCancel}.
83 * @return A {@link Callback} that will return a TreeTableCell that is able to
84 * work on the type of element contained within the TreeTableColumn.
85 */
86 @SafeVarargs
87 public static <S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> forTreeTableColumn(
88 final T... items) {
89 return forTreeTableColumn(null, items);
90 }
91
92 /**
93 * Creates a ComboBox cell factory for use in {@link TreeTableColumn} controls.
94 * By default, the ComboBoxCell is rendered as a {@link Label} when not
95 * being edited, and as a ComboBox when in editing mode. The ComboBox will,
96 * by default, stretch to fill the entire list cell.
97 *
98 * @param <S> The type of the TableView generic type
99 * @param <T> The type of the elements contained within the TreeTableColumn.
100 * @param converter A {@link StringConverter} to convert the given item (of
101 * type T) to a String for displaying to the user.
102 * @param items Zero or more items that will be shown to the user when the
103 * {@link ComboBox} menu is showing. These items must be of the same
104 * type as the TreeTableColumn. Note that it is up to the developer to set
105 * {@link EventHandler event handlers} to listen to edit events in the
106 * TreeTableColumn, and react accordingly. Methods of interest include
107 * {@link TreeTableColumn#setOnEditStart(javafx.event.EventHandler) setOnEditStart},
108 * {@link TreeTableColumn#setOnEditCommit(javafx.event.EventHandler) setOnEditCommit},
109 * and {@link TreeTableColumn#setOnEditCancel(javafx.event.EventHandler) setOnEditCancel}.
110 * @return A {@link Callback} that will return a TreeTableCell that is able to
111 * work on the type of element contained within the TreeTableColumn.
112 */
113 @SafeVarargs
114 public static <S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> forTreeTableColumn(
115 final StringConverter<T> converter,
116 final T... items) {
117 return forTreeTableColumn(converter, FXCollections.observableArrayList(items));
118 }
119
120 /**
121 * Creates a ComboBox cell factory for use in {@link TreeTableColumn} controls.
122 * By default, the ComboBoxCell is rendered as a {@link Label} when not
123 * being edited, and as a ComboBox when in editing mode. The ComboBox will,
124 * by default, stretch to fill the entire list cell.
125 *
126 * @param <S> The type of the TableView generic type
127 * @param <T> The type of the elements contained within the TreeTableColumn.
128 * @param items Zero or more items that will be shown to the user when the
129 * {@link ComboBox} menu is showing. These items must be of the same
130 * type as the TreeTableColumn. Note that it is up to the developer to set
131 * {@link EventHandler event handlers} to listen to edit events in the
132 * TreeTableColumn, and react accordingly. Methods of interest include
133 * {@link TreeTableColumn#setOnEditStart(javafx.event.EventHandler) setOnEditStart},
134 * {@link TreeTableColumn#setOnEditCommit(javafx.event.EventHandler) setOnEditCommit},
135 * and {@link TreeTableColumn#setOnEditCancel(javafx.event.EventHandler) setOnEditCancel}.
136 * @return A {@link Callback} that will return a TreeTableCell that is able to
137 * work on the type of element contained within the TreeTableColumn.
138 */
139 public static <S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> forTreeTableColumn(
140 final ObservableList<T> items) {
141 return forTreeTableColumn(null, items);
142 }
143
144 /**
145 * Creates a ComboBox cell factory for use in {@link TreeTableColumn} controls.
146 * By default, the ComboBoxCell is rendered as a {@link Label} when not
147 * being edited, and as a ComboBox when in editing mode. The ComboBox will,
148 * by default, stretch to fill the entire list cell.
149 *
150 * @param <S> The type of the TableView generic type
151 * @param <T> The type of the elements contained within the TreeTableColumn.
152 * @param converter A {@link StringConverter} to convert the given item (of
153 * type T) to a String for displaying to the user.
154 * @param items Zero or more items that will be shown to the user when the
155 * {@link ComboBox} menu is showing. These items must be of the same
156 * type as the TreeTableColumn. Note that it is up to the developer to set
157 * {@link EventHandler event handlers} to listen to edit events in the
158 * TreeTableColumn, and react accordingly. Methods of interest include
159 * {@link TreeTableColumn#setOnEditStart(javafx.event.EventHandler) setOnEditStart},
160 * {@link TreeTableColumn#setOnEditCommit(javafx.event.EventHandler) setOnEditCommit},
161 * and {@link TreeTableColumn#setOnEditCancel(javafx.event.EventHandler) setOnEditCancel}.
162 * @return A {@link Callback} that will return a TreeTableCell that is able to
163 * work on the type of element contained within the TreeTableColumn.
164 */
165 public static <S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> forTreeTableColumn(
166 final StringConverter<T> converter,
167 final ObservableList<T> items) {
168 return list -> new ComboBoxTreeTableCell<S,T>(converter, items);
169 }
170
250 public ComboBoxTreeTableCell(StringConverter<T> converter, ObservableList<T> items) {
251 this.getStyleClass().add("combo-box-tree-table-cell");
252 this.items = items;
253 setConverter(converter != null ? converter : CellUtils.<T>defaultStringConverter());
254 }
255
256
257
258 /***************************************************************************
259 * *
260 * Properties *
261 * *
262 **************************************************************************/
263
264 // --- converter
265 private ObjectProperty<StringConverter<T>> converter =
266 new SimpleObjectProperty<StringConverter<T>>(this, "converter");
267
268 /**
269 * The {@link StringConverter} property.
270 * @return the string converter property
271 */
272 public final ObjectProperty<StringConverter<T>> converterProperty() {
273 return converter;
274 }
275
276 /**
277 * Sets the {@link StringConverter} to be used in this cell.
278 * @param value the string converter
279 */
280 public final void setConverter(StringConverter<T> value) {
281 converterProperty().set(value);
282 }
283
284 /**
285 * Returns the {@link StringConverter} used in this cell.
286 * @return the string converter
287 */
288 public final StringConverter<T> getConverter() {
289 return converterProperty().get();
290 }
291
292
293 // --- comboBox editable
294 private BooleanProperty comboBoxEditable =
295 new SimpleBooleanProperty(this, "comboBoxEditable");
296
297 /**
298 * A property representing whether the ComboBox, when shown to the user,
299 * is editable or not.
300 * @return the property representing whether the ComboBox, when shown to the
301 * user, is editable or not
302 */
303 public final BooleanProperty comboBoxEditableProperty() {
304 return comboBoxEditable;
305 }
306
307 /**
308 * Configures the ComboBox to be editable (to allow user input outside of the
309 * options provide in the dropdown list).
310 * @param value the editable value to be set for this ComboBox
311 */
312 public final void setComboBoxEditable(boolean value) {
313 comboBoxEditableProperty().set(value);
314 }
315
316 /**
317 * Returns true if the ComboBox is editable.
318 * @return true if the ComboBox is editable
319 */
320 public final boolean isComboBoxEditable() {
321 return comboBoxEditableProperty().get();
322 }
323
324
325
326 /***************************************************************************
327 * *
328 * Public API *
329 * *
330 **************************************************************************/
331
332 /**
333 * Returns the items to be displayed in the ComboBox when it is showing.
334 * @return the items to be displayed in this ComboBox when it is showing
335 */
336 public ObservableList<T> getItems() {
337 return items;
338 }
339
340 /** {@inheritDoc} */
341 @Override public void startEdit() {
342 if (! isEditable() || ! getTreeTableView().isEditable() || ! getTableColumn().isEditable()) {
343 return;
344 }
345
346 if (comboBox == null) {
347 comboBox = createComboBox(this, items, converterProperty());
348 comboBox.editableProperty().bind(comboBoxEditableProperty());
349 }
350
351 comboBox.getSelectionModel().select(getItem());
352
353 super.startEdit();
354 setText(null);
|