1 /* 2 * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javafx.scene.control.cell; 27 28 import javafx.beans.property.ObjectProperty; 29 import javafx.beans.property.SimpleObjectProperty; 30 import javafx.scene.control.TextField; 31 import javafx.scene.control.TreeTableCell; 32 import javafx.scene.control.TreeTableColumn; 33 import javafx.util.Callback; 34 import javafx.util.StringConverter; 35 import javafx.util.converter.DefaultStringConverter; 36 37 /** 38 * A class containing a {@link javafx.scene.control.TableCell} implementation that draws a 39 * {@link TextField} node inside the cell. 40 * 41 * <p>By default, the TextFieldTableCell is rendered as a {@link javafx.scene.control.Label} when not 42 * being edited, and as a TextField when in editing mode. The TextField will, by 43 * default, stretch to fill the entire table cell. 44 * 45 * @param <S> The type of the TreeTableView generic type 46 * @param <T> The type of the elements contained within the TreeTableColumn. 47 * @since JavaFX 8.0 48 */ 49 public class TextFieldTreeTableCell<S,T> extends TreeTableCell<S,T> { 50 51 /*************************************************************************** 52 * * 53 * Static cell factories * 54 * * 55 **************************************************************************/ 56 57 /** 58 * Provides a {@link TextField} that allows editing of the cell content when 59 * the cell is double-clicked, or when 60 * {@link javafx.scene.control.TreeTableView#edit(int, javafx.scene.control.TreeTableColumn)} is called. 61 * This method will only work on {@link TreeTableColumn} instances which are of 62 * type String. 63 * 64 * @param <S> The type of the TreeTableView generic type 65 * @return A {@link Callback} that can be inserted into the 66 * {@link TreeTableColumn#cellFactoryProperty() cell factory property} of a 67 * TreeTableColumn, that enables textual editing of the content. 68 */ 69 public static <S> Callback<TreeTableColumn<S,String>, TreeTableCell<S,String>> forTreeTableColumn() { 70 return forTreeTableColumn(new DefaultStringConverter()); 71 } 72 73 /** 74 * Provides a {@link TextField} that allows editing of the cell content when 75 * the cell is double-clicked, or when 76 * {@link javafx.scene.control.TreeTableView#edit(int, javafx.scene.control.TreeTableColumn) } is called. 77 * This method will work on any {@link TreeTableColumn} instance, regardless of 78 * its generic type. However, to enable this, a {@link StringConverter} must 79 * be provided that will convert the given String (from what the user typed 80 * in) into an instance of type T. This item will then be passed along to the 81 * {@link TreeTableColumn#onEditCommitProperty()} callback. 82 * 83 * @param <S> The type of the TreeTableView generic type 84 * @param <T> The type of the elements contained within the TreeTableColumn 85 * @param converter A {@link StringConverter} that can convert the given String 86 * (from what the user typed in) into an instance of type T. 87 * @return A {@link Callback} that can be inserted into the 88 * {@link TreeTableColumn#cellFactoryProperty() cell factory property} of a 89 * TreeTableColumn, that enables textual editing of the content. 90 */ 91 public static <S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> forTreeTableColumn( 92 final StringConverter<T> converter) { 93 return list -> new TextFieldTreeTableCell<S,T>(converter); 94 } 95 96 97 /*************************************************************************** 98 * * 99 * Fields * 100 * * 101 **************************************************************************/ 102 103 private TextField textField; 104 105 106 107 /*************************************************************************** 108 * * 109 * Constructors * 110 * * 111 **************************************************************************/ 112 113 /** 114 * Creates a default TextFieldTreeTableCell with a null converter. Without a 115 * {@link StringConverter} specified, this cell will not be able to accept 116 * input from the TextField (as it will not know how to convert this back 117 * to the domain object). It is therefore strongly encouraged to not use 118 * this constructor unless you intend to set the converter separately. 119 */ 120 public TextFieldTreeTableCell() { 121 this(null); 122 } 123 124 /** 125 * Creates a TextFieldTreeTableCell that provides a {@link TextField} when put 126 * into editing mode that allows editing of the cell content. This method 127 * will work on any TreeTableColumn instance, regardless of its generic type. 128 * However, to enable this, a {@link StringConverter} must be provided that 129 * will convert the given String (from what the user typed in) into an 130 * instance of type T. This item will then be passed along to the 131 * {@link TreeTableColumn#onEditCommitProperty()} callback. 132 * 133 * @param converter A {@link StringConverter converter} that can convert 134 * the given String (from what the user typed in) into an instance of 135 * type T. 136 */ 137 public TextFieldTreeTableCell(StringConverter<T> converter) { 138 this.getStyleClass().add("text-field-tree-table-cell"); 139 setConverter(converter); 140 } 141 142 143 144 /*************************************************************************** 145 * * 146 * Properties * 147 * * 148 **************************************************************************/ 149 150 // --- converter 151 private ObjectProperty<StringConverter<T>> converter = 152 new SimpleObjectProperty<StringConverter<T>>(this, "converter"); 153 154 /** 155 * The {@link StringConverter} property. 156 * @return the {@link StringConverter} property 157 */ 158 public final ObjectProperty<StringConverter<T>> converterProperty() { 159 return converter; 160 } 161 162 /** 163 * Sets the {@link StringConverter} to be used in this cell. 164 * @param value the {@link StringConverter} to be used in this cell 165 */ 166 public final void setConverter(StringConverter<T> value) { 167 converterProperty().set(value); 168 } 169 170 /** 171 * Returns the {@link StringConverter} used in this cell. 172 * @return the {@link StringConverter} used in this cell 173 */ 174 public final StringConverter<T> getConverter() { 175 return converterProperty().get(); 176 } 177 178 179 180 /*************************************************************************** 181 * * 182 * Public API * 183 * * 184 **************************************************************************/ 185 186 /** {@inheritDoc} */ 187 @Override public void startEdit() { 188 if (! isEditable() 189 || ! getTreeTableView().isEditable() 190 || ! getTableColumn().isEditable()) { 191 return; 192 } 193 super.startEdit(); 194 195 if (isEditing()) { 196 if (textField == null) { 197 textField = CellUtils.createTextField(this, getConverter()); 198 } 199 200 CellUtils.startEdit(this, getConverter(), null, null, textField); 201 } 202 } 203 204 /** {@inheritDoc} */ 205 @Override public void cancelEdit() { 206 super.cancelEdit(); 207 CellUtils.cancelEdit(this, getConverter(), null); 208 } 209 210 /** {@inheritDoc} */ 211 @Override public void updateItem(T item, boolean empty) { 212 super.updateItem(item, empty); 213 CellUtils.updateItem(this, getConverter(), null, null, textField); 214 } 215 }