changeset 6074:e35db0874061

RT-35233: [TreeTableView, TreeTableColumn] Fix incomplete API documentation and TODOs
author jgiles
date Mon, 13 Jan 2014 13:56:03 +1300
parents 6216d402dc1b
children dace65c4c5d7
files modules/controls/src/main/java/javafx/scene/control/TableView.java modules/controls/src/main/java/javafx/scene/control/TreeTableColumn.java modules/controls/src/main/java/javafx/scene/control/TreeTableView.java modules/controls/src/main/java/javafx/scene/control/cell/TreeItemPropertyValueFactory.java
diffstat 4 files changed, 100 insertions(+), 98 deletions(-) [+]
line wrap: on
line diff
--- a/modules/controls/src/main/java/javafx/scene/control/TableView.java	Mon Jan 13 09:34:30 2014 +1300
+++ b/modules/controls/src/main/java/javafx/scene/control/TableView.java	Mon Jan 13 13:56:03 2014 +1300
@@ -87,8 +87,9 @@
  *   <li>Support for {@link TableColumn#cellFactoryProperty() cell factories} to
  *      easily customize {@link Cell cell} contents in both rendering and editing
  *      states.
- *   <li>Specification of {@link #minWidthProperty() minWidth}/
- *      {@link #prefWidthProperty() prefWidth}/{@link #maxWidthProperty() maxWidth},
+ *   <li>Specification of {@link TableColumn#minWidthProperty() minWidth}/
+ *      {@link TableColumn#prefWidthProperty() prefWidth}/
+ *      {@link TableColumn#maxWidthProperty() maxWidth},
  *      and also {@link TableColumn#resizableProperty() fixed width columns}.
  *   <li>Width resizing by the user at runtime.
  *   <li>Column reordering by the user at runtime.
@@ -2175,7 +2176,7 @@
             // fire off a single add/remove/replace notification (rather than
             // individual remove and add notifications) - see RT-33324
             int changeIndex = selectedCellsSeq.indexOf(new TablePosition(getTableView(), row, column));
-            ListChangeListener.Change change = new NonIterableChange.GenericAddRemoveChange<>(
+            ListChangeListener.Change change = new NonIterableChange.GenericAddRemoveChange<TablePosition<S,?>>(
                     changeIndex, changeIndex+1, previousSelection, selectedCellsSeq);
             handleSelectedCellsListChangeEvent(change);
         }
--- a/modules/controls/src/main/java/javafx/scene/control/TreeTableColumn.java	Mon Jan 13 09:34:30 2014 +1300
+++ b/modules/controls/src/main/java/javafx/scene/control/TreeTableColumn.java	Mon Jan 13 13:56:03 2014 +1300
@@ -51,12 +51,14 @@
 import com.sun.javafx.scene.control.skin.TableViewSkinBase;
 /**
  * A {@link TreeTableView} is made up of a number of TreeTableColumn instances. Each
- * TreeTableColumn in a tree table is responsible for displaying (and editing) the contents
- * of that column. As well as being responsible for displaying and editing data 
- * for a single column, a TableColumn also contains the necessary properties to:
+ * TreeTableColumn in a {@link TreeTableView} is responsible for displaying
+ * (and editing) the contents of that column. As well as being responsible for
+ * displaying and editing data for a single column, a TreeTableColumn also
+ * contains the necessary properties to:
  * <ul>
- *    <li>Be resized (using {@link #minWidthProperty() minWidth}/{@link #prefWidthProperty() prefWidth}/{@link #maxWidthProperty() maxWidth}
- *      and {@link #widthProperty() width} properties)
+ *    <li>Be resized (using {@link #minWidthProperty() minWidth}/
+ *    {@link #prefWidthProperty() prefWidth}/
+ *    {@link #maxWidthProperty() maxWidth} and {@link #widthProperty() width} properties)
  *    <li>Have its {@link #visibleProperty() visibility} toggled
  *    <li>Display {@link #textProperty() header text}
  *    <li>Display any {@link #getColumns() nested columns} it may contain
@@ -74,48 +76,43 @@
  * (which is used to populate individual cells in the column). This can be 
  * achieved using some variation on the following code:
  * 
- * <p>// TODO update example for TreeTableColumn
- * 
- * <pre>
- * {@code 
- * ObservableList<Person> data = ...
- * TableView<Person> tableView = new TableView<Person>(data);
- * 
- * TableColumn<Person,String> firstNameCol = new TableColumn<Person,String>("First Name");
+ * <pre>{@code
  * firstNameCol.setCellValueFactory(new Callback<CellDataFeatures<Person, String>, ObservableValue<String>>() {
  *     public ObservableValue<String> call(CellDataFeatures<Person, String> p) {
- *         // p.getValue() returns the Person instance for a particular TableView row
- *         return p.getValue().firstNameProperty();
+ *         // p.getValue() returns the TreeItem<Person> instance for a particular TreeTableView row,
+ *         // p.getValue().getValue() returns the Person instance inside the TreeItem<Person>
+ *         return p.getValue().getValue().firstNameProperty();
  *     }
  *  });
- * }
- * tableView.getColumns().add(firstNameCol);}</pre>
+ * }}</pre>
  * 
- * This approach assumes that the object returned from <code>p.getValue()</code>
+ * This approach assumes that the object returned from <code>p.getValue().getValue()</code>
  * has a JavaFX {@link ObservableValue} that can simply be returned. The benefit of this
  * is that the TableView will internally create bindings to ensure that,
  * should the returned {@link ObservableValue} change, the cell contents will be
  * automatically refreshed. 
  * 
  * <p>In situations where a TableColumn must interact with classes created before
- * JavaFX, or that generally do not wish to use JavaFX apis for properties, it is
+ * JavaFX, or that generally do not wish to use JavaFX APIs for properties, it is
  * possible to wrap the returned value in a {@link ReadOnlyObjectWrapper} instance. For
  * example:
  * 
- * <pre>
- * {@code 
+ *<pre>{@code
  * firstNameCol.setCellValueFactory(new Callback<CellDataFeatures<Person, String>, ObservableValue<String>>() {
  *     public ObservableValue<String> call(CellDataFeatures<Person, String> p) {
- *         return new ReadOnlyObjectWrapper(p.getValue().getFirstName());
+ *         // p.getValue() returns the TreeItem<Person> instance for a particular TreeTableView row,
+ *         // p.getValue().getValue() returns the Person instance inside the TreeItem<Person>
+ *         return new ReadOnlyObjectWrapper(p.getValue().getValue().getFirstName());
  *     }
- *  });}</pre>
+ *  });
+ * }}</pre>
  * 
  * It is hoped that over time there will be convenience cell value factories 
  * developed and made available to developers. As of the JavaFX 2.0 release, 
  * there is one such convenience class: {@link javafx.scene.control.cell.TreeItemPropertyValueFactory}.
  * This class removes the need to write the code above, instead relying on reflection to
  * look up a given property from a String. Refer to the 
- * <code>PropertyValueFactory</code> class documentation for more information
+ * <code>TreeItemPropertyValueFactory</code> class documentation for more information
  * on how to use this with a TableColumn.
  * 
  * Finally, for more detail on how to use TableColumn, there is further documentation in
@@ -126,6 +123,7 @@
  * @see TableView
  * @see TableCell
  * @see TablePosition
+ * @see javafx.scene.control.cell.TreeItemPropertyValueFactory
  * @since JavaFX 8.0
  */
 public class TreeTableColumn<S,T> extends TableColumnBase<TreeItem<S>,T> implements EventTarget {
@@ -357,28 +355,26 @@
      * will be observed internally to allow for updates to the value to be 
      * immediately reflected on screen.
      * 
-     * <p> // TODO update example
+     * <p>An example of how to set a cell value factory is:
      * 
-     * An example of how to set a cell value factory is:
-     * 
-     * <pre><code>
-     * lastNameCol.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) {
-     *         // p.getValue() returns the Person instance for a particular TableView row
-     *         return p.getValue().lastNameProperty();
+     * <pre>{@code
+     * firstNameCol.setCellValueFactory(new Callback<CellDataFeatures<Person, String>, ObservableValue<String>>() {
+     *     public ObservableValue<String> call(CellDataFeatures<Person, String> p) {
+     *         // p.getValue() returns the TreeItem<Person> instance for a particular TreeTableView row,
+     *         // p.getValue().getValue() returns the Person instance inside the TreeItem<Person>
+     *         return p.getValue().getValue().firstNameProperty();
      *     }
      *  });
-     * }
-     * </code></pre>
+     * }}</pre>
      * 
      * A common approach is to want to populate cells in a TreeTableColumn using
      * a single value from a Java bean. To support this common scenario, there
      * is the {@link javafx.scene.control.cell.TreeItemPropertyValueFactory} class.
      * Refer to this class for more information on how to use it, but briefly
-     * here is how the above use case could be simplified using the PropertyValueFactory class:
+     * here is how the above use case could be simplified using the TreeItemPropertyValueFactory class:
      * 
      * <pre><code>
-     * lastNameCol.setCellValueFactory(new PropertyValueFactory&lt;Person,String&gt;("lastName"));
+     * firstNameCol.setCellValueFactory(new TreeItemPropertyValueFactory&lt;Person,String&gt;("firstName"));
      * </code></pre>
      * 
      * @see javafx.scene.control.cell.TreeItemPropertyValueFactory
--- a/modules/controls/src/main/java/javafx/scene/control/TreeTableView.java	Mon Jan 13 09:34:30 2014 +1300
+++ b/modules/controls/src/main/java/javafx/scene/control/TreeTableView.java	Mon Jan 13 13:56:03 2014 +1300
@@ -82,20 +82,31 @@
 
 /**
  * The TreeTableView control is designed to visualize an unlimited number of rows
- * of data, broken out into columns. A TreeTableView is therefore very similar to the
- * {@link ListView} and {@link TableView} controls. For an
- * example on how to create a TreeTableView, refer to the 'Creating a TreeTableView'
- * control section below.
+ * of data, broken out into columns. The TreeTableView control is conceptually
+ * very similar to the {@link TreeView} and {@link TableView} controls,
+ * and as you read on you'll come to see the APIs are largely the same.
+ * However, to give a high-level overview, you'll note that the TreeTableView
+ * uses the same {@link TreeItem} API as {@link TreeView},
+ * and that you therefore are required to simply set the
+ * {@link #rootProperty() root node} in the TreeTableView. Similarly, the
+ * TreeTableView control makes use of the same TableColumn-based approach that
+ * the {@link TableView} control uses, except instead of using the
+ * TableView-specific {@link TableColumn} class, you should instead use the
+ * TreeTableView-specific {@link TreeTableColumn} class instead. For an
+ * example on how to create a TreeTableView instance, refer to the 'Creating a
+ * TreeTableView' control section below.
  *
- * <p>The TreeTableView control has a number of features, including:
+ * <p>As with the {@link TableView} control, the TreeTableView control has a
+ * number of features, including:
  * <ul>
  * <li>Powerful {@link TreeTableColumn} API:
  *   <ul>
  *   <li>Support for {@link TreeTableColumn#cellFactoryProperty() cell factories} to
  *      easily customize {@link Cell cell} contents in both rendering and editing
  *      states.
- *   <li>Specification of {@link #minWidthProperty() minWidth}/
- *      {@link #prefWidthProperty() prefWidth}/{@link #maxWidthProperty() maxWidth},
+ *   <li>Specification of {@link TreeTableColumn#minWidthProperty() minWidth}/
+ *      {@link TreeTableColumn#prefWidthProperty() prefWidth}/
+ *      {@link TreeTableColumn#maxWidthProperty() maxWidth},
  *      and also {@link TreeTableColumn#resizableProperty() fixed width columns}.
  *   <li>Width resizing by the user at runtime.
  *   <li>Column reordering by the user at runtime.
@@ -109,22 +120,14 @@
  * </ul>
  * </p>
  *
- * <p>Note that TreeTableView is intended to be used to visualize data - it is not
- * intended to be used for laying out your user interface. If you want to lay
- * your user interface out in a grid-like fashion, consider the 
- * {@link GridPane} layout.</p>
- *
  * <h2>Creating a TreeTableView</h2>
  * 
- * TODO update to a relevant example
- *
  * <p>Creating a TreeTableView is a multi-step process, and also depends on the
  * underlying data model needing to be represented. For this example we'll use
  * the TreeTableView to visualise a file system, and will therefore make use
  * of an imaginary (and vastly simplified) File class as defined below:
  * 
- * <pre>
- * {@code
+ * <pre>{@code
  * public class File {
  *     private StringProperty name;
  *     public void setName(String value) { nameProperty().set(value); }
@@ -134,28 +137,26 @@
  *         return name; 
  *     }
  * 
- *     private DoubleProperty lastModified;
- *     public void setLastModified(Double value) { lastModifiedProperty().set(value); }
- *     public DoubleProperty getLastModified() { return lastModifiedProperty().get(); }
- *     public DoubleProperty lastModifiedProperty() { 
- *         if (lastModified == null) lastModified = new SimpleDoubleProperty(this, "lastModified");
+ *     private LongProperty lastModified;
+ *     public void setLastModified(long value) { lastModifiedProperty().set(value); }
+ *     public long getLastModified() { return lastModifiedProperty().get(); }
+ *     public LongProperty lastModifiedProperty() {
+ *         if (lastModified == null) lastModified = new SimpleLongProperty(this, "lastModified");
  *         return lastModified; 
  *     } 
  * }}</pre>
  * 
  * <p>Firstly, a TreeTableView instance needs to be defined, as such:
  * 
- * <pre>
- * {@code
- * TreeTableView<File> treeTable = new TreeTableView<File>();}</pre>
+ * <pre>{@code
+ * TreeTableView<File> treeTable = new TreeTableView<>();}</pre>
  *
- * <p>With the basic tree table defined, we next focus on the data model. As mentioned,
- * for this example, we'll be representing a file system using File instances. To
- * do this, we need to define the root node of the tree table, as such:
+ * <p>With the basic TreeTableView instantiated, we next focus on the data model.
+ * As mentioned, for this example, we'll be representing a file system using File
+ * instances. To do this, we need to define the root node of the tree table, as such:
  *
- * <pre>
- * {@code
- * TreeItem<File> root = new TreeItem<File>(new File("/"));
+ * <pre>{@code
+ * TreeItem<File> root = new TreeItem<>(new File("/"));
  * treeTable.setRoot(root);}</pre>
  * 
  * <p>With the root set as such, the TreeTableView will automatically update whenever
@@ -168,44 +169,48 @@
  * create a two-column TreeTableView to show the file name and last modified 
  * properties, we extend the code shown above as follows:
  * 
- * <pre>
- * {@code
- * TreeItem<File> root = new TreeItem<File>(new File("/"));
- * treeTable.setRoot(root);
+ * <pre>{@code
+ * TreeTableColumns<File,String> fileNameCol = new TreeTableColumn<>("Filename");
+ * TreeTableColumns<File,Long> lastModifiedCol = new TreeTableColumn<>("Size");
+ *
+ * table.getColumns().setAll(fileNameCol, lastModifiedCol);}</pre>
  * 
- * // TODO this is not valid TreeTableView code
- * TreeTableColumns<Person,String> firstNameCol = new TreeTableColumns<Person,String>("First Name");
- * firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName"));
- * TreeTableColumns<Person,String> lastNameCol = new TreeTableColumns<Person,String>("Last Name");
- * lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName"));
- * 
- * table.getColumns().setAll(firstNameCol, lastNameCol);}</pre>
- * 
- * <p>With the code shown above we have fully defined the minimum properties
- * required to create a TreeTableView instance. Running this code (assuming the
- * file system structure is probably built up in memory) will result in a TreeTableView being
- * shown with two columns for name and lastModified. Any other properties of the
- * File class will not be shown, as no TreeTableColumns are defined for them.
+ * <p>With the code shown above we have nearly fully defined the minimum properties
+ * required to create a TreeTableView instance. The only thing missing is the
+ * {@link javafx.scene.control.TreeTableColumn#cellValueFactoryProperty() cell value factories}
+ * for the two columns - it is these that are responsible for determining the value
+ * of a cell in a given row. Commonly these can be specified using the
+ * {@link javafx.scene.control.cell.TreeItemPropertyValueFactory} class, but
+ * failing that you can also create an anonymous inner class and do whatever is
+ * necessary. For example, using {@link javafx.scene.control.cell.TreeItemPropertyValueFactory}
+ * you would do the following:
+ *
+ * <pre>{@code
+ * fileNameCol.setCellValueFactory(new TreeItemPropertyValueFactory("name"));
+ * lastModifiedCol.setCellValueFactory(new TreeItemPropertyValueFactory("lastModified"));}</pre>
+ *
+ * Running this code (assuming the file system structure is probably built up in
+ * memory) will result in a TreeTableView being shown with two columns for name
+ * and lastModified. Any other properties of the File class will not be shown, as
+ * no TreeTableColumns are defined for them.
  * 
  * <h3>TreeTableView support for classes that don't contain properties</h3>
  *
- * // TODO update - this is not correct for TreeTableView
- * 
  * <p>The code shown above is the shortest possible code for creating a TreeTableView
  * when the domain objects are designed with JavaFX properties in mind 
- * (additionally, {@link javafx.scene.control.cell.PropertyValueFactory} supports
+ * (additionally, {@link javafx.scene.control.cell.TreeItemPropertyValueFactory} supports
  * normal JavaBean properties too, although there is a caveat to this, so refer 
  * to the class documentation for more information). When this is not the case, 
  * it is necessary to provide a custom cell value factory. More information
  * about cell value factories can be found in the {@link TreeTableColumn} API
  * documentation, but briefly, here is how a TreeTableColumns could be specified:
  * 
- * <pre>
- * {@code
+ * <pre>{@code
  * firstNameCol.setCellValueFactory(new Callback<CellDataFeatures<Person, String>, ObservableValue<String>>() {
  *     public ObservableValue<String> call(CellDataFeatures<Person, String> p) {
- *         // p.getValue() returns the Person instance for a particular TreeTableView row
- *         return p.getValue().firstNameProperty();
+ *         // p.getValue() returns the TreeItem<Person> instance for a particular TreeTableView row,
+ *         // p.getValue().getValue() returns the Person instance inside the TreeItem<Person>
+ *         return p.getValue().getValue().firstNameProperty();
  *     }
  *  });
  * }}</pre>
@@ -215,7 +220,7 @@
  * {@link SelectionModel} and {@link FocusModel} classes. A TreeTableView has at most
  * one instance of each of these classes, available from 
  * {@link #selectionModelProperty() selectionModel} and 
- * {@link #focusModelProperty() focusModel} properties respectively.
+ * {@link #focusModelProperty() focusModel} properties, respectively.
  * Whilst it is possible to use this API to set a new selection model, in
  * most circumstances this is not necessary - the default selection and focus
  * models should work in most circumstances.
@@ -2367,7 +2372,7 @@
             // fire off a single add/remove/replace notification (rather than
             // individual remove and add notifications) - see RT-33324
             int changeIndex = selectedCellsSeq.indexOf(new TreeTablePosition<>(getTreeTableView(), row, (TreeTableColumn<S,?>)column));
-            ListChangeListener.Change change = new NonIterableChange.GenericAddRemoveChange<>(
+            ListChangeListener.Change change = new NonIterableChange.GenericAddRemoveChange<TreeTablePosition<S,?>>(
                     changeIndex, changeIndex+1, previousSelection, selectedCellsSeq);
             handleSelectedCellsListChangeEvent(change);
         }
--- a/modules/controls/src/main/java/javafx/scene/control/cell/TreeItemPropertyValueFactory.java	Mon Jan 13 09:34:30 2014 +1300
+++ b/modules/controls/src/main/java/javafx/scene/control/cell/TreeItemPropertyValueFactory.java	Mon Jan 13 13:56:03 2014 +1300
@@ -54,7 +54,7 @@
  * <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 TreeTableCell} is populated with this ObservableValue<T>.
+ * is found, then the {@link javafx.scene.control.TreeTableCell} is populated with this 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.
@@ -86,8 +86,8 @@
  * </code></pre>
  *
  * @see TreeTableColumn
- * @see TreeTableView
- * @see TreeTableCell
+ * @see javafx.scene.control.TreeTableView
+ * @see javafx.scene.control.TreeTableCell
  * @see PropertyValueFactory
  * @see MapValueFactory
  * @since JavaFX 8.0