< prev index next >

modules/javafx.controls/src/main/java/javafx/scene/control/Cell.java

Print this page




 122  *
 123  *     public MoneyFormatCell() {    }
 124  *
 125  *     @Override protected void updateItem(Number item, boolean empty) {
 126  *         // calling super here is very important - don't skip this!
 127  *         super.updateItem(item, empty);
 128  *
 129  *         // format the number as if it were a monetary value using the
 130  *         // formatting relevant to the current locale. This would format
 131  *         // 43.68 as "$43.68", and -23.67 as "-$23.67"
 132  *         setText(item == null ? "" : NumberFormat.getCurrencyInstance().format(item));
 133  *
 134  *         // change the text fill based on whether it is positive (green)
 135  *         // or negative (red). If the cell is selected, the text will
 136  *         // always be white (so that it can be read against the blue
 137  *         // background), and if the value is zero, we'll make it black.
 138  *         if (item != null) {
 139  *             double value = item.doubleValue();
 140  *             setTextFill(isSelected() ? Color.WHITE :
 141  *                 value == 0 ? Color.BLACK :
 142  *                 value < 0 ? Color.RED : Color.GREEN);
 143  *         }
 144  *     }
 145  * }</pre>
 146  *
 147  * This class could then be used inside a ListView as such:
 148  *
 149  * <pre>
 150  * ObservableList&lt;Number&gt; money = ...;
 151  * final ListView&lt;Number&gt; listView = new ListView&lt;Number&gt;(money);
 152  * listView.setCellFactory(new Callback&lt;ListView&lt;Number&gt;, ListCell&lt;Number&gt;&gt;() {
 153  *     @Override public ListCell&lt;Number&gt; call(ListView&lt;Number&gt; list) {
 154  *         return new MoneyFormatCell();
 155  *     }
 156  * });</pre>
 157  *
 158  * In this example an anonymous inner class is created, that simply returns
 159  * instances of MoneyFormatCell whenever it is called. The MoneyFormatCell class
 160  * extends {@link ListCell}, overriding the
 161  * {@link #updateItem(java.lang.Object, boolean) updateItem} method. This method
 162  * is called whenever the item in the cell changes, for example when the user


 376 
 377 
 378 
 379     /***************************************************************************
 380      *                                                                         *
 381      * Properties                                                              *
 382      *                                                                         *
 383      **************************************************************************/
 384 
 385     // --- item
 386     private ObjectProperty<T> item = new SimpleObjectProperty<T>(this, "item");
 387 
 388     /**
 389      * The data value associated with this Cell. This value is set by the
 390      * virtualized Control when the Cell is created or updated. This represents
 391      * the raw data value.
 392     *
 393     * <p>This value should only be set in subclasses of Cell by the virtualised
 394     * user interface controls that know how to properly work with the Cell
 395     * class.

 396      */
 397     public final ObjectProperty<T> itemProperty() { return item; }
 398 
 399     /**
 400      * Sets the item to the given value - should not be called directly as the
 401      * item is managed by the virtualized control.

 402      */
 403     public final void setItem(T value) { item.set(value); }
 404 
 405     /**
 406      * Returns the data value associated with this Cell.

 407      */
 408     public final T getItem() { return item.get(); }
 409 
 410 
 411 
 412     // --- empty
 413     private ReadOnlyBooleanWrapper empty = new ReadOnlyBooleanWrapper(true) {
 414         @Override protected void invalidated() {
 415             final boolean active = get();
 416             pseudoClassStateChanged(PSEUDO_CLASS_EMPTY,   active);
 417             pseudoClassStateChanged(PSEUDO_CLASS_FILLED, !active);
 418         }
 419 
 420         @Override
 421         public Object getBean() {
 422             return Cell.this;
 423         }
 424 
 425         @Override
 426         public String getName() {
 427             return "empty";
 428         }
 429     };
 430 
 431     /**
 432      * A property used to represent whether the cell has any contents.
 433      * If true, then the Cell contains no data and is not associated with any
 434      * data item in the virtualized Control.
 435      *
 436      * <p>When a cell is empty, it can be styled differently via the 'empty'
 437      * CSS pseudo class state. For example, it may not receive any
 438      * alternate row highlighting, or it may not receive hover background
 439      * fill when hovered.

 440      */
 441     public final ReadOnlyBooleanProperty emptyProperty() { return empty.getReadOnlyProperty(); }
 442 
 443     private void setEmpty(boolean value) { empty.set(value); }
 444 
 445     /**
 446      * Returns a boolean representing whether the cell is considered to be empty
 447      * or not.

 448      */
 449     public final boolean isEmpty() { return empty.get(); }
 450 
 451 
 452 
 453     // --- selected
 454     private ReadOnlyBooleanWrapper selected = new ReadOnlyBooleanWrapper() {
 455         @Override protected void invalidated() {
 456             pseudoClassStateChanged(PSEUDO_CLASS_SELECTED, get());
 457         }
 458 
 459         @Override
 460         public Object getBean() {
 461             return Cell.this;
 462         }
 463 
 464         @Override
 465         public String getName() {
 466             return "selected";
 467         }
 468     };
 469 
 470     /**
 471      * Indicates whether or not this cell has been selected. For example, a
 472      * ListView defines zero or more cells as being the "selected" cells.

 473      */
 474     public final ReadOnlyBooleanProperty selectedProperty() { return selected.getReadOnlyProperty(); }
 475 
 476     void setSelected(boolean value) { selected.set(value); }
 477 
 478     /**
 479      * Returns whether this cell is currently selected or not.
 480      * @return True if the cell is selected, false otherwise.
 481      */
 482     public final boolean isSelected() { return selected.get(); }
 483 
 484 
 485 
 486     // --- Editing
 487     private ReadOnlyBooleanWrapper editing;
 488 
 489     private void setEditing(boolean value) {
 490         editingPropertyImpl().set(value);
 491     }
 492 
 493     /**
 494      * Represents whether the cell is currently in its editing state or not.


 495      */
 496     public final boolean isEditing() {
 497         return editing == null ? false : editing.get();
 498     }
 499 
 500     /**
 501      * Property representing whether this cell is currently in its editing state.


 502      */
 503     public final ReadOnlyBooleanProperty editingProperty() {
 504         return editingPropertyImpl().getReadOnlyProperty();
 505     }
 506 
 507     private ReadOnlyBooleanWrapper editingPropertyImpl() {
 508         if (editing == null) {
 509             editing = new ReadOnlyBooleanWrapper(this, "editing");
 510         }
 511         return editing;
 512     }
 513 
 514 
 515 
 516     // --- Editable
 517     private BooleanProperty editable;
 518 
 519     /**
 520      * Allows for certain cells to not be able to be edited. This is useful in
 521      * cases where, say, a List has 'header rows' - it does not make sense for
 522      * the header rows to be editable, so they should have editable set to
 523      * false.
 524      *
 525      * @param value A boolean representing whether the cell is editable or not.
 526      *      If true, the cell is editable, and if it is false, the cell can not
 527      *      be edited.
 528      */
 529     public final void setEditable(boolean value) {
 530         editableProperty().set(value);
 531     }
 532 
 533     /**
 534      * Returns whether this cell is allowed to be put into an editing state.


 535      */
 536     public final boolean isEditable() {
 537         return editable == null ? true : editable.get();
 538     }
 539 
 540     /**
 541      * A property representing whether this cell is allowed to be put into an
 542      * editing state. By default editable is set to true in Cells (although for
 543      * a subclass of Cell to be allowed to enter its editing state, it may have
 544      * to satisfy additional criteria. For example, ListCell requires that the
 545      * ListView {@link ListView#editableProperty() editable} property is also
 546      * true.


 547      */
 548     public final BooleanProperty editableProperty() {
 549         if (editable == null) {
 550             editable = new SimpleBooleanProperty(this, "editable", true);
 551         }
 552         return editable;
 553     }
 554 
 555 
 556 
 557     /***************************************************************************
 558      *                                                                         *
 559      * Public API                                                              *
 560      *                                                                         *
 561      **************************************************************************/
 562 
 563     /**
 564      * Call this function to transition from a non-editing state into an editing
 565      * state, if the cell is editable. If this cell is already in an editing
 566      * state, it will stay in it.


 656      *         setText(item.toString());
 657      *     }
 658      * }
 659      * </pre>
 660      *
 661      * <p>Note in this code sample two important points:
 662      * <ol>
 663      *     <li>We call the super.updateItem(T, boolean) method. If this is not
 664      *     done, the item and empty properties are not correctly set, and you are
 665      *     likely to end up with graphical issues.</li>
 666      *     <li>We test for the <code>empty</code> condition, and if true, we
 667      *     set the text and graphic properties to null. If we do not do this,
 668      *     it is almost guaranteed that end users will see graphical artifacts
 669      *     in cells unexpectedly.</li>
 670      * </ol>
 671      *
 672      * @param item The new item for the cell.
 673      * @param empty whether or not this cell represents data from the list. If it
 674      *        is empty, then it does not represent any domain data, but is a cell
 675      *        being used to render an "empty" row.
 676      * @expert
 677      */
 678     protected void updateItem(T item, boolean empty) {
 679         setItem(item);
 680         setEmpty(empty);
 681         if (empty && isSelected()) {
 682             updateSelected(false);
 683         }
 684     }
 685 
 686     /**
 687      * Updates whether this cell is in a selected state or not.
 688      * @expert
 689      * @param selected whether or not to select this cell.
 690      */
 691     public void updateSelected(boolean selected) {
 692         if (selected && isEmpty()) return;
 693         boolean wasSelected = isSelected();
 694         setSelected(selected);
 695 
 696         if (wasSelected != selected) {
 697             markCellDirty();
 698         }
 699     }
 700 
 701     /**
 702      * This method is called by Cell subclasses so that certain CPU-intensive
 703      * actions (specifically, calling {@link #updateItem(Object, boolean)}) are
 704      * only performed when necessary (that is, they are only performed
 705      * when the currently set {@link #itemProperty() item} is considered to be
 706      * different than the proposed new item that could be set).
 707      *
 708      * <p>The default implementation of this method tests against equality, but




 122  *
 123  *     public MoneyFormatCell() {    }
 124  *
 125  *     @Override protected void updateItem(Number item, boolean empty) {
 126  *         // calling super here is very important - don't skip this!
 127  *         super.updateItem(item, empty);
 128  *
 129  *         // format the number as if it were a monetary value using the
 130  *         // formatting relevant to the current locale. This would format
 131  *         // 43.68 as "$43.68", and -23.67 as "-$23.67"
 132  *         setText(item == null ? "" : NumberFormat.getCurrencyInstance().format(item));
 133  *
 134  *         // change the text fill based on whether it is positive (green)
 135  *         // or negative (red). If the cell is selected, the text will
 136  *         // always be white (so that it can be read against the blue
 137  *         // background), and if the value is zero, we'll make it black.
 138  *         if (item != null) {
 139  *             double value = item.doubleValue();
 140  *             setTextFill(isSelected() ? Color.WHITE :
 141  *                 value == 0 ? Color.BLACK :
 142  *                 value &lt; 0 ? Color.RED : Color.GREEN);
 143  *         }
 144  *     }
 145  * }</pre>
 146  *
 147  * This class could then be used inside a ListView as such:
 148  *
 149  * <pre>
 150  * ObservableList&lt;Number&gt; money = ...;
 151  * final ListView&lt;Number&gt; listView = new ListView&lt;Number&gt;(money);
 152  * listView.setCellFactory(new Callback&lt;ListView&lt;Number&gt;, ListCell&lt;Number&gt;&gt;() {
 153  *     @Override public ListCell&lt;Number&gt; call(ListView&lt;Number&gt; list) {
 154  *         return new MoneyFormatCell();
 155  *     }
 156  * });</pre>
 157  *
 158  * In this example an anonymous inner class is created, that simply returns
 159  * instances of MoneyFormatCell whenever it is called. The MoneyFormatCell class
 160  * extends {@link ListCell}, overriding the
 161  * {@link #updateItem(java.lang.Object, boolean) updateItem} method. This method
 162  * is called whenever the item in the cell changes, for example when the user


 376 
 377 
 378 
 379     /***************************************************************************
 380      *                                                                         *
 381      * Properties                                                              *
 382      *                                                                         *
 383      **************************************************************************/
 384 
 385     // --- item
 386     private ObjectProperty<T> item = new SimpleObjectProperty<T>(this, "item");
 387 
 388     /**
 389      * The data value associated with this Cell. This value is set by the
 390      * virtualized Control when the Cell is created or updated. This represents
 391      * the raw data value.
 392     *
 393     * <p>This value should only be set in subclasses of Cell by the virtualised
 394     * user interface controls that know how to properly work with the Cell
 395     * class.
 396      * @return the data value associated with this cell
 397      */
 398     public final ObjectProperty<T> itemProperty() { return item; }
 399 
 400     /**
 401      * Sets the item to the given value - should not be called directly as the
 402      * item is managed by the virtualized control.
 403      * @param value the data value to this item
 404      */
 405     public final void setItem(T value) { item.set(value); }
 406 
 407     /**
 408      * Returns the data value associated with this Cell.
 409      * @return the data value associated with this cell
 410      */
 411     public final T getItem() { return item.get(); }
 412 
 413 
 414 
 415     // --- empty
 416     private ReadOnlyBooleanWrapper empty = new ReadOnlyBooleanWrapper(true) {
 417         @Override protected void invalidated() {
 418             final boolean active = get();
 419             pseudoClassStateChanged(PSEUDO_CLASS_EMPTY,   active);
 420             pseudoClassStateChanged(PSEUDO_CLASS_FILLED, !active);
 421         }
 422 
 423         @Override
 424         public Object getBean() {
 425             return Cell.this;
 426         }
 427 
 428         @Override
 429         public String getName() {
 430             return "empty";
 431         }
 432     };
 433 
 434     /**
 435      * A property used to represent whether the cell has any contents.
 436      * If true, then the Cell contains no data and is not associated with any
 437      * data item in the virtualized Control.
 438      *
 439      * <p>When a cell is empty, it can be styled differently via the 'empty'
 440      * CSS pseudo class state. For example, it may not receive any
 441      * alternate row highlighting, or it may not receive hover background
 442      * fill when hovered.
 443      * @return the representation of whether this cell has any contents
 444      */
 445     public final ReadOnlyBooleanProperty emptyProperty() { return empty.getReadOnlyProperty(); }
 446 
 447     private void setEmpty(boolean value) { empty.set(value); }
 448 
 449     /**
 450      * Returns a boolean representing whether the cell is considered to be empty
 451      * or not.
 452      * @return true if cell is empty, otherwise false
 453      */
 454     public final boolean isEmpty() { return empty.get(); }
 455 
 456 
 457 
 458     // --- selected
 459     private ReadOnlyBooleanWrapper selected = new ReadOnlyBooleanWrapper() {
 460         @Override protected void invalidated() {
 461             pseudoClassStateChanged(PSEUDO_CLASS_SELECTED, get());
 462         }
 463 
 464         @Override
 465         public Object getBean() {
 466             return Cell.this;
 467         }
 468 
 469         @Override
 470         public String getName() {
 471             return "selected";
 472         }
 473     };
 474 
 475     /**
 476      * Indicates whether or not this cell has been selected. For example, a
 477      * ListView defines zero or more cells as being the "selected" cells.
 478      * @return the representation of whether this cell has been selected
 479      */
 480     public final ReadOnlyBooleanProperty selectedProperty() { return selected.getReadOnlyProperty(); }
 481 
 482     void setSelected(boolean value) { selected.set(value); }
 483 
 484     /**
 485      * Returns whether this cell is currently selected or not.
 486      * @return True if the cell is selected, false otherwise.
 487      */
 488     public final boolean isSelected() { return selected.get(); }
 489 
 490 
 491 
 492     // --- Editing
 493     private ReadOnlyBooleanWrapper editing;
 494 
 495     private void setEditing(boolean value) {
 496         editingPropertyImpl().set(value);
 497     }
 498 
 499     /**
 500      * Represents whether the cell is currently in its editing state or not.
 501      * @return true if this cell is currently in its editing state, otherwise
 502      * false
 503      */
 504     public final boolean isEditing() {
 505         return editing == null ? false : editing.get();
 506     }
 507 
 508     /**
 509      * Property representing whether this cell is currently in its editing state.
 510      * @return the representation of whether this cell is currently in its
 511      * editing state
 512      */
 513     public final ReadOnlyBooleanProperty editingProperty() {
 514         return editingPropertyImpl().getReadOnlyProperty();
 515     }
 516 
 517     private ReadOnlyBooleanWrapper editingPropertyImpl() {
 518         if (editing == null) {
 519             editing = new ReadOnlyBooleanWrapper(this, "editing");
 520         }
 521         return editing;
 522     }
 523 
 524 
 525 
 526     // --- Editable
 527     private BooleanProperty editable;
 528 
 529     /**
 530      * Allows for certain cells to not be able to be edited. This is useful in
 531      * cases where, say, a List has 'header rows' - it does not make sense for
 532      * the header rows to be editable, so they should have editable set to
 533      * false.
 534      *
 535      * @param value A boolean representing whether the cell is editable or not.
 536      *      If true, the cell is editable, and if it is false, the cell can not
 537      *      be edited.
 538      */
 539     public final void setEditable(boolean value) {
 540         editableProperty().set(value);
 541     }
 542 
 543     /**
 544      * Returns whether this cell is allowed to be put into an editing state.
 545      * @return true if this cell is allowed to be put into an editing state,
 546      * otherwise false
 547      */
 548     public final boolean isEditable() {
 549         return editable == null ? true : editable.get();
 550     }
 551 
 552     /**
 553      * A property representing whether this cell is allowed to be put into an
 554      * editing state. By default editable is set to true in Cells (although for
 555      * a subclass of Cell to be allowed to enter its editing state, it may have
 556      * to satisfy additional criteria. For example, ListCell requires that the
 557      * ListView {@link ListView#editableProperty() editable} property is also
 558      * true.
 559      * @return the representation of whether this cell is allowed to be put into
 560      * an editing state
 561      */
 562     public final BooleanProperty editableProperty() {
 563         if (editable == null) {
 564             editable = new SimpleBooleanProperty(this, "editable", true);
 565         }
 566         return editable;
 567     }
 568 
 569 
 570 
 571     /***************************************************************************
 572      *                                                                         *
 573      * Public API                                                              *
 574      *                                                                         *
 575      **************************************************************************/
 576 
 577     /**
 578      * Call this function to transition from a non-editing state into an editing
 579      * state, if the cell is editable. If this cell is already in an editing
 580      * state, it will stay in it.


 670      *         setText(item.toString());
 671      *     }
 672      * }
 673      * </pre>
 674      *
 675      * <p>Note in this code sample two important points:
 676      * <ol>
 677      *     <li>We call the super.updateItem(T, boolean) method. If this is not
 678      *     done, the item and empty properties are not correctly set, and you are
 679      *     likely to end up with graphical issues.</li>
 680      *     <li>We test for the <code>empty</code> condition, and if true, we
 681      *     set the text and graphic properties to null. If we do not do this,
 682      *     it is almost guaranteed that end users will see graphical artifacts
 683      *     in cells unexpectedly.</li>
 684      * </ol>
 685      *
 686      * @param item The new item for the cell.
 687      * @param empty whether or not this cell represents data from the list. If it
 688      *        is empty, then it does not represent any domain data, but is a cell
 689      *        being used to render an "empty" row.

 690      */
 691     protected void updateItem(T item, boolean empty) {
 692         setItem(item);
 693         setEmpty(empty);
 694         if (empty && isSelected()) {
 695             updateSelected(false);
 696         }
 697     }
 698 
 699     /**
 700      * Updates whether this cell is in a selected state or not.

 701      * @param selected whether or not to select this cell.
 702      */
 703     public void updateSelected(boolean selected) {
 704         if (selected && isEmpty()) return;
 705         boolean wasSelected = isSelected();
 706         setSelected(selected);
 707 
 708         if (wasSelected != selected) {
 709             markCellDirty();
 710         }
 711     }
 712 
 713     /**
 714      * This method is called by Cell subclasses so that certain CPU-intensive
 715      * actions (specifically, calling {@link #updateItem(Object, boolean)}) are
 716      * only performed when necessary (that is, they are only performed
 717      * when the currently set {@link #itemProperty() item} is considered to be
 718      * different than the proposed new item that could be set).
 719      *
 720      * <p>The default implementation of this method tests against equality, but


< prev index next >