< prev index next >

modules/javafx.controls/src/main/java/javafx/scene/control/cell/TreeItemPropertyValueFactory.java

Print this page
rev 10441 : imported patch fix-8177566-trampoline
rev 10443 : [mq]: doc-8177566-trampoline

*** 28,39 **** --- 28,41 ---- import javafx.beans.NamedArg; import javafx.beans.property.Property; import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.value.ObservableValue; import javafx.scene.control.TreeItem; + import javafx.scene.control.TreeTableCell; import javafx.scene.control.TreeTableColumn; import javafx.scene.control.TreeTableColumn.CellDataFeatures; + import javafx.scene.control.TreeTableView; import javafx.util.Callback; import com.sun.javafx.property.PropertyReference; import com.sun.javafx.scene.control.Logging; import sun.util.logging.PlatformLogger; import sun.util.logging.PlatformLogger.Level;
*** 48,79 **** * <pre><code> * TreeTableColumn&lt;Person,String&gt; firstNameCol = new TreeTableColumn&lt;Person,String&gt;("First Name"); * firstNameCol.setCellValueFactory(new TreeItemPropertyValueFactory&lt;Person,String&gt;("firstName")); * </code></pre> * ! * In this example, the "firstName" string is used as a reference to an assumed ! * <code>firstNameProperty()</code> method in the <code>Person</code> class type ! * (which is the class type of the TreeTableView). Additionally, this method must ! * return a {@link Property} instance. If a method meeting these requirements ! * is found, then the {@link javafx.scene.control.TreeTableCell} is populated ! * with this {@literal ObservableValue<T>}. ! * In addition, the TreeTableView will automatically add an observer to the ! * returned value, such that any changes fired will be observed by the TreeTableView, ! * resulting in the cell immediately updating. ! * ! * <p>If no method matching this pattern exists, there is fall-through support ! * for attempting to call get&lt;property&gt;() or is&lt;property&gt;() (that is, ! * <code>getFirstName()</code> or <code>isFirstName()</code> in the example ! * above). If a method matching this pattern exists, the value returned from this method ! * is wrapped in a {@link ReadOnlyObjectWrapper} and returned to the TreeTableCell. ! * However, in this situation, this means that the TreeTableCell will not be able ! * to observe the ObservableValue for changes (as is the case in the first ! * approach above). * * <p>For reference (and as noted in the TreeTableColumn * {@link TreeTableColumn#cellValueFactory cell value factory} documentation), the * long form of the code above would be the following: * * <pre><code> * TreeTableColumn&lt;Person,String&gt; firstNameCol = new TreeTableColumn&lt;Person,String&gt;("First Name"); * {@literal * firstNameCol.setCellValueFactory(new Callback<CellDataFeatures<Person, String>, ObservableValue<String>>() { --- 50,100 ---- * <pre><code> * TreeTableColumn&lt;Person,String&gt; firstNameCol = new TreeTableColumn&lt;Person,String&gt;("First Name"); * firstNameCol.setCellValueFactory(new TreeItemPropertyValueFactory&lt;Person,String&gt;("firstName")); * </code></pre> * ! * ! * <p> ! * In this example, {@code Person} is the class type of the {@link TreeItem} ! * instances used in the {@link TreeTableView}. ! * {@code TreeItemPropertyValueFactory} uses the constructor argument, ! * {@code "firstName"}, to assume that {@code Person} has a method ! * {@code firstNameProperty} with no formal parameters and a return type of ! * {@code ObservableValue<String>}. ! * </p> ! * <p> ! * If such a method exists, then it is invoked, and additionally assumed ! * to return an instance of {@code Property<String>}. The return value is used ! * to populate the {@link TreeTableCell}. In addition, the {@code TreeTableView} ! * adds an observer to the return value, such that any changes fired will be ! * observed by the {@code TreeTableView}, resulting in the cell immediately ! * updating. ! * </p> ! * <p> ! * If no such method exists, then {@code TreeItemPropertyValueFactory} ! * assumes that {@code Person} has a method {@code getFirstName} or ! * {@code isFirstName} with no formal parameters and a return type of ! * {@code String}. If such a method exists, then it is invoked, and its return ! * value is wrapped in a {@link ReadOnlyObjectWrapper} ! * and returned to the {@code TreeTableCell}. In this situation, ! * the {@code TreeTableCell} will not be able to observe changes to the property, ! * unlike in the first approach above. ! * </p> ! * <p> ! * The class {@code Person} must be declared public. If that class is in a named ! * module, then the module must {@link Module#isOpen(String,Module) open} ! * the containing package to at least the {@code javafx.base} module ! * (or {@link Module#isExported(String) export} the containing package ! * unconditionally). ! * Otherwise the {@link #call call(TreeTableColumn.CellDataFeatures)} method ! * will log a warning and return {@code null}. ! * </p> * * <p>For reference (and as noted in the TreeTableColumn * {@link TreeTableColumn#cellValueFactory cell value factory} documentation), the * long form of the code above would be the following: + * </p> * * <pre><code> * TreeTableColumn&lt;Person,String&gt; firstNameCol = new TreeTableColumn&lt;Person,String&gt;("First Name"); * {@literal * firstNameCol.setCellValueFactory(new Callback<CellDataFeatures<Person, String>, ObservableValue<String>>() {
*** 87,98 **** * } * } * </code></pre> * * @see TreeTableColumn ! * @see javafx.scene.control.TreeTableView ! * @see javafx.scene.control.TreeTableCell * @see PropertyValueFactory * @see MapValueFactory * @since JavaFX 8.0 */ public class TreeItemPropertyValueFactory<S,T> implements Callback<TreeTableColumn.CellDataFeatures<S,T>, ObservableValue<T>> { --- 108,119 ---- * } * } * </code></pre> * * @see TreeTableColumn ! * @see TreeTableView ! * @see TreeTableCell * @see PropertyValueFactory * @see MapValueFactory * @since JavaFX 8.0 */ public class TreeItemPropertyValueFactory<S,T> implements Callback<TreeTableColumn.CellDataFeatures<S,T>, ObservableValue<T>> {
*** 141,167 **** this.columnClass = rowData.getClass(); this.previousProperty = getProperty(); this.propertyRef = new PropertyReference<T>(rowData.getClass(), getProperty()); } return propertyRef.getProperty(rowData); ! } catch (IllegalStateException e) { try { // attempt to just get the value T value = propertyRef.get(rowData); return new ReadOnlyObjectWrapper<T>(value); ! } catch (IllegalStateException e2) { // fall through to logged exception below } // log the warning and move on final PlatformLogger logger = Logging.getControlsLogger(); if (logger.isLoggable(Level.WARNING)) { ! logger.finest("Can not retrieve property '" + getProperty() + "' in TreeItemPropertyValueFactory: " + this + " with provided class type: " + rowData.getClass(), e); } } return null; } } --- 162,191 ---- this.columnClass = rowData.getClass(); this.previousProperty = getProperty(); this.propertyRef = new PropertyReference<T>(rowData.getClass(), getProperty()); } + if (propertyRef != null) { return propertyRef.getProperty(rowData); ! } ! } catch (RuntimeException e) { try { // attempt to just get the value T value = propertyRef.get(rowData); return new ReadOnlyObjectWrapper<T>(value); ! } catch (RuntimeException e2) { // fall through to logged exception below } // log the warning and move on final PlatformLogger logger = Logging.getControlsLogger(); if (logger.isLoggable(Level.WARNING)) { ! logger.warning("Can not retrieve property '" + getProperty() + "' in TreeItemPropertyValueFactory: " + this + " with provided class type: " + rowData.getClass(), e); } + propertyRef = null; } return null; } }
< prev index next >