< prev index next >

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

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

*** 50,82 **** * <pre><code> * TableColumn&lt;Person,String&gt; firstNameCol = new TableColumn&lt;Person,String&gt;("First Name"); * firstNameCol.setCellValueFactory(new PropertyValueFactory&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 TableView ! * {@link TableView#itemsProperty() items} list). Additionally, this method must ! * return a {@link Property} instance. If a method meeting these requirements ! * is found, then the {@link TableCell} is populated with this ! * {@literal ObservableValue<T>}. ! * In addition, the TableView will automatically add an observer to the ! * returned value, such that any changes fired will be observed by the TableView, ! * 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 TableCell. ! * However, in this situation, this means that the TableCell 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 TableColumn * {@link TableColumn#cellValueFactory cell value factory} documentation), the * long form of the code above would be the following: * * <pre><code> * TableColumn&lt;Person,String&gt; firstNameCol = new TableColumn&lt;Person,String&gt;("First Name"); * firstNameCol.setCellValueFactory(new Callback&lt;CellDataFeatures&lt;Person, String&gt;, ObservableValue&lt;String&gt;&gt;() { * public ObservableValue&lt;String&gt; call(CellDataFeatures&lt;Person, String&gt; p) { --- 50,90 ---- * <pre><code> * TableColumn&lt;Person,String&gt; firstNameCol = new TableColumn&lt;Person,String&gt;("First Name"); * firstNameCol.setCellValueFactory(new PropertyValueFactory&lt;Person,String&gt;("firstName")); * </code></pre> * ! * <p> ! * In this example, {@code Person} is the class type of the {@code TableView} ! * {@link TableView#itemsProperty() items} list. ! * The class {@code Person} must be declared public. ! * {@code PropertyValueFactory} uses the constructor argument, ! * {@code "firstName"}, to assume that {@code Person} has a public 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 TableCell}. In addition, the {@code TableView} adds ! * an observer to the return value, such that any changes fired will be observed ! * by the {@code TableView}, resulting in the cell immediately updating. ! * </p> ! * <p> ! * If no such method exists, then {@code PropertyValueFactory} ! * assumes that {@code Person} has a public 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 TableCell}. In this situation, ! * the {@code TableCell} will not be able to observe changes to the property, ! * unlike in the first approach above. ! * </p> * * <p>For reference (and as noted in the TableColumn * {@link TableColumn#cellValueFactory cell value factory} documentation), the * long form of the code above would be the following: + * </p> * * <pre><code> * TableColumn&lt;Person,String&gt; firstNameCol = new TableColumn&lt;Person,String&gt;("First Name"); * firstNameCol.setCellValueFactory(new Callback&lt;CellDataFeatures&lt;Person, String&gt;, ObservableValue&lt;String&gt;&gt;() { * public ObservableValue&lt;String&gt; call(CellDataFeatures&lt;Person, String&gt; p) {
*** 85,94 **** --- 93,128 ---- * } * }); * } * </code></pre> * + * <p><b>Deploying an Application as a Module</b></p> + * <p> + * If the referenced class is in a named module, then it must be reflectively + * accessible to the {@code javafx.base} module. + * A class is reflectively accessible if the module + * {@link Module#isOpen(String,Module) opens} the containing package to at + * least the {@code javafx.base} module. + * Otherwise the {@link #call call(TableColumn.CellDataFeatures)} method + * will log a warning and return {@code null}. + * </p> + * <p> + * For example, if the {@code Person} class is in the {@code com.foo} package + * in the {@code foo.app} module, the {@code module-info.java} might + * look like this: + * </p> + * + <pre>{@code module foo.app { + opens com.foo to javafx.base; + }}</pre> + * + * <p> + * Alternatively, a class is reflectively accessible if the module + * {@link Module#isExported(String) exports} the containing package + * unconditionally. + * </p> + * * @see TableColumn * @see TableView * @see TableCell * @see TreeItemPropertyValueFactory * @see MapValueFactory
*** 141,164 **** this.columnClass = rowData.getClass(); this.previousProperty = getProperty(); this.propertyRef = new PropertyReference<T>(rowData.getClass(), getProperty()); } if (propertyRef.hasProperty()) { return propertyRef.getProperty(rowData); } else { T value = propertyRef.get(rowData); return new ReadOnlyObjectWrapper<T>(value); } ! } catch (IllegalStateException e) { // log the warning and move on final PlatformLogger logger = Logging.getControlsLogger(); if (logger.isLoggable(Level.WARNING)) { ! logger.finest("Can not retrieve property '" + getProperty() + "' in PropertyValueFactory: " + this + " with provided class type: " + rowData.getClass(), e); } } return null; } } --- 175,201 ---- this.columnClass = rowData.getClass(); this.previousProperty = getProperty(); this.propertyRef = new PropertyReference<T>(rowData.getClass(), getProperty()); } + if (propertyRef != null) { if (propertyRef.hasProperty()) { return propertyRef.getProperty(rowData); } else { T value = propertyRef.get(rowData); return new ReadOnlyObjectWrapper<T>(value); } ! } ! } catch (RuntimeException e) { // log the warning and move on final PlatformLogger logger = Logging.getControlsLogger(); if (logger.isLoggable(Level.WARNING)) { ! logger.warning("Can not retrieve property '" + getProperty() + "' in PropertyValueFactory: " + this + " with provided class type: " + rowData.getClass(), e); } + propertyRef = null; } return null; } }
< prev index next >