changeset 880:e91d38c52914

RT-21023: ComboBox : allow different Cell rendering for Open and Closed state.
author jgiles
date Fri, 27 Apr 2012 07:45:12 +1200
parents edd9ab755798
children 339fc9553446 14596f886092
files javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ComboBoxListViewSkin.java javafx-ui-controls/src/javafx/scene/control/ComboBox.java
diffstat 2 files changed, 35 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ComboBoxListViewSkin.java	Thu Apr 26 19:53:42 2012 +1200
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ComboBoxListViewSkin.java	Fri Apr 27 07:45:12 2012 +1200
@@ -59,7 +59,8 @@
     
     private final ComboBox<T> comboBox;
     
-    private ListCell<T> listCellLabel;
+    private ListCell<T> buttonCell;
+    private Callback<ListView<T>, ListCell<T>> cellFactory;
     private TextField textField;
     
     private final ListView<T> listView;
@@ -70,7 +71,11 @@
         super(comboBox, new ComboBoxListViewBehavior<T>(comboBox));
         this.comboBox = comboBox;
         this.listView = createListView();
-        this.listCellLabel = getListCellLabel();
+        
+        updateListViewItems();
+        updateCellFactory();
+        
+        updateButtonCell();
         
         // move focus in to the textfield if the comboBox is editable
         comboBox.focusedProperty().addListener(new ChangeListener<Boolean>() {
@@ -131,15 +136,13 @@
             }
         });
         
-        updateListViewItems();
-        updateCellFactory();
-        
         registerChangeListener(comboBox.itemsProperty(), "ITEMS");
         registerChangeListener(comboBox.promptTextProperty(), "PROMPT_TEXT");
         registerChangeListener(comboBox.cellFactoryProperty(), "CELL_FACTORY");
         registerChangeListener(comboBox.visibleRowCountProperty(), "VISIBLE_ROW_COUNT");
         registerChangeListener(comboBox.converterProperty(), "CONVERTER");
         registerChangeListener(comboBox.editorProperty(), "EDITOR");
+        registerChangeListener(comboBox.buttonCellProperty(), "BUTTON_CELL");
     }
     
     public void updateListViewItems() {
@@ -186,6 +189,8 @@
             updateListViewItems();
         } else if ("EDITOR".equals(p)) {
             getEditableInputNode();
+        } else if ("BUTTON_CELL".equals(p)) {
+            updateButtonCell();
         }
     }
     
@@ -197,7 +202,7 @@
             }
             displayNode = textField;
         } else {
-            displayNode = listCellLabel;
+            displayNode = buttonCell;
         }
         
         updateDisplayNode();
@@ -239,18 +244,18 @@
             }
         } else {
             int index = getSelectedIndex();
-            listCellLabel.updateListView(listView);
-            listCellLabel.updateIndex(index);
+            buttonCell.updateListView(listView);
+            buttonCell.updateIndex(index);
         }
     }
     
     private void updateDisplayText(ListCell<T> cell, T item, boolean empty) {
         if (empty) {
-            if (listCellLabel == null) return;
+            if (buttonCell == null) return;
             cell.setGraphic(null);
             cell.setText(comboBox.getPromptText() == null ? null : comboBox.getPromptText());
         } else if (item instanceof Node) {
-            Node currentNode = listCellLabel.getGraphic();
+            Node currentNode = buttonCell.getGraphic();
             Node newNode = (Node) item;
             if (currentNode == null || ! currentNode.equals(newNode)) {
                 cell.setText(null);
@@ -271,15 +276,10 @@
         return index;
     }
     
-    private ListCell<T> getListCellLabel() {
-        if (listCellLabel != null) return listCellLabel;
-        
-        Callback<ListView<T>, ListCell<T>> cellFactory = comboBox.getCellFactory();
-        listCellLabel = cellFactory != null ? 
-                cellFactory.call(listView) : getDefaultCellFactory().call(listView);
-        listCellLabel.setMouseTransparent(true);
-        
-        return listCellLabel;
+    private void updateButtonCell() {
+        buttonCell = comboBox.getButtonCell() != null ? 
+                comboBox.getButtonCell() : getDefaultCellFactory().call(listView);
+        buttonCell.setMouseTransparent(true);
     }
 
     @Override public Node getPopupContent() {
@@ -288,7 +288,8 @@
     
     private void updateCellFactory() {
         Callback<ListView<T>, ListCell<T>> cf = comboBox.getCellFactory();
-        listView.setCellFactory(cf != null ? cf : getDefaultCellFactory());
+        cellFactory = cf != null ? cf : getDefaultCellFactory();
+        listView.setCellFactory(cellFactory);
     }
     
     private Callback<ListView<T>, ListCell<T>> getDefaultCellFactory() {
--- a/javafx-ui-controls/src/javafx/scene/control/ComboBox.java	Thu Apr 26 19:53:42 2012 +1200
+++ b/javafx-ui-controls/src/javafx/scene/control/ComboBox.java	Fri Apr 27 07:45:12 2012 +1200
@@ -39,7 +39,6 @@
 import javafx.collections.ListChangeListener;
 import javafx.collections.ListChangeListener.Change;
 import javafx.collections.ObservableList;
-import javafx.event.EventDispatchChain;
 import javafx.scene.Node;
 import javafx.util.Callback;
 import javafx.util.StringConverter;
@@ -294,6 +293,20 @@
     public ObjectProperty<Callback<ListView<T>, ListCell<T>>> cellFactoryProperty() { return cellFactory; }
     
     
+    // --- button cell
+    /**
+     * The button cell is used to render what is shown in the ComboBox 'button'
+     * area. If a cell is set here, it does not change the rendering of the
+     * ComboBox popup list - that rendering is controlled via the 
+     * {@link #cellFactoryProperty() cell factory} API.
+     */
+    public ObjectProperty<ListCell<T>> buttonCellProperty() { return buttonCell; }
+    private ObjectProperty<ListCell<T>> buttonCell = 
+            new SimpleObjectProperty<ListCell<T>>(this, "buttonCell");
+    public final void setButtonCell(ListCell<T> value) { buttonCellProperty().set(value); }
+    public final ListCell<T> getButtonCell() {return buttonCellProperty().get(); }
+    
+    
     // --- Selection Model
     /**
      * The selection model for the ComboBox. A ComboBox only supports