Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package javafx.scene.control.cell; 027 028import javafx.beans.property.BooleanProperty; 029import javafx.beans.property.ObjectProperty; 030import javafx.beans.property.SimpleObjectProperty; 031import javafx.beans.value.ObservableValue; 032import javafx.geometry.Pos; 033import javafx.scene.control.CheckBox; 034import javafx.scene.control.ContentDisplay; 035import javafx.scene.control.ListCell; 036import javafx.scene.control.ListView; 037import javafx.scene.control.TreeItem; 038import javafx.util.Callback; 039import javafx.util.StringConverter; 040 041/** 042 * A class containing a {@link ListCell} implementation that draws a 043 * {@link CheckBox} node inside the cell, optionally with a label to indicate 044 * what the checkbox represents. 045 * 046 * <p>The CheckBoxListCell is rendered with a CheckBox on the left-hand side of 047 * the {@link ListView}, and the text related to the list item taking up all 048 * remaining horizontal space. 049 * 050 * <p>To construct an instance of this class, it is necessary to provide a 051 * {@link Callback} that, given an object of type T, will return a 052 * {@code ObservableValue<Boolean>} that represents whether the given item is 053 * selected or not. This ObservableValue will be bound bidirectionally (meaning 054 * that the CheckBox in the cell will set/unset this property based on user 055 * interactions, and the CheckBox will reflect the state of the 056 * ObservableValue<Boolean>, if it changes externally). 057 * 058 * @see CheckBox 059 * @see ListCell 060 * @param <T> The type of the elements contained within the ListView. 061 * @since 2.2 062 */ 063public class CheckBoxListCell<T> extends ListCell<T> { 064 065 /*************************************************************************** 066 * * 067 * Static cell factories * 068 * * 069 **************************************************************************/ 070 071 /** 072 * Creates a cell factory for use in ListView controls. When used in a 073 * ListView, the {@link CheckBoxListCell} is rendered with a CheckBox on the 074 * left-hand side of the ListView, with the text related to the list item 075 * taking up all remaining horizontal space. 076 * 077 * @param <T> The type of the elements contained within the ListView. 078 * @param getSelectedProperty A {@link Callback} that, given an object of 079 * type T (which is a value taken out of the 080 * {@code ListView<T>.items} list), 081 * will return an {@code ObservableValue<Boolean>} that represents 082 * whether the given item is selected or not. This ObservableValue will 083 * be bound bidirectionally (meaning that the CheckBox in the cell will 084 * set/unset this property based on user interactions, and the CheckBox 085 * will reflect the state of the ObservableValue, if it changes 086 * externally). 087 * @return A {@link Callback} that will return a ListCell that is able to 088 * work on the type of element contained within the ListView items list. 089 */ 090 public static <T> Callback<ListView<T>, ListCell<T>> forListView( 091 final Callback<T, ObservableValue<Boolean>> getSelectedProperty) { 092 return forListView(getSelectedProperty, CellUtils.<T>defaultStringConverter()); 093 } 094 095 /** 096 * Creates a cell factory for use in ListView controls. When used in a 097 * ListView, the {@link CheckBoxListCell} is rendered with a CheckBox on the 098 * left-hand side of the ListView, with the text related to the list item 099 * taking up all remaining horizontal space. 100 * 101 * @param <T> The type of the elements contained within the ListView. 102 * @param getSelectedProperty A {@link Callback} that, given an object 103 * of type T (which is a value taken out of the 104 * {@code ListView<T>.items} list), 105 * will return an {@code ObservableValue<Boolean>} that represents 106 * whether the given item is selected or not. This ObservableValue will 107 * be bound bidirectionally (meaning that the CheckBox in the cell will 108 * set/unset this property based on user interactions, and the CheckBox 109 * will reflect the state of the ObservableValue, if it changes 110 * externally). 111 * @param converter A StringConverter that, give an object of type T, will 112 * return a String that can be used to represent the object visually. 113 * @return A {@link Callback} that will return a ListCell that is able to 114 * work on the type of element contained within the ListView. 115 */ 116 public static <T> Callback<ListView<T>, ListCell<T>> forListView( 117 final Callback<T, ObservableValue<Boolean>> getSelectedProperty, 118 final StringConverter<T> converter) { 119 return new Callback<ListView<T>, ListCell<T>>() { 120 @Override public ListCell<T> call(ListView<T> list) { 121 return new CheckBoxListCell<T>(getSelectedProperty, converter); 122 } 123 }; 124 } 125 126 /*************************************************************************** 127 * * 128 * Fields * 129 * * 130 **************************************************************************/ 131 132 private final CheckBox checkBox; 133 134 private ObservableValue<Boolean> booleanProperty; 135 136 137 138 /*************************************************************************** 139 * * 140 * Constructors * 141 * * 142 **************************************************************************/ 143 144 /** 145 * Creates a default CheckBoxListCell. 146 */ 147 public CheckBoxListCell() { 148 this(null); 149 } 150 151 /** 152 * Creates a default CheckBoxListCell. 153 * 154 * @param getSelectedProperty A {@link Callback} that will return an 155 * {@code ObservableValue<Boolean>} given an item from the ListView. 156 */ 157 public CheckBoxListCell( 158 final Callback<T, ObservableValue<Boolean>> getSelectedProperty) { 159 this(getSelectedProperty, CellUtils.<T>defaultStringConverter()); 160 } 161 162 /** 163 * Creates a CheckBoxListCell with a custom string converter. 164 * 165 * @param getSelectedProperty A {@link Callback} that will return an 166 * {@code ObservableValue<Boolean>} given an item from the ListView. 167 * @param converter A StringConverter that, given an object of type T, will 168 * return a String that can be used to represent the object visually. 169 */ 170 public CheckBoxListCell( 171 final Callback<T, ObservableValue<Boolean>> getSelectedProperty, 172 final StringConverter<T> converter) { 173 this.getStyleClass().add("check-box-list-cell"); 174 setSelectedStateCallback(getSelectedProperty); 175 setConverter(converter); 176 177 this.checkBox = new CheckBox(); 178 179 setAlignment(Pos.CENTER_LEFT); 180 setContentDisplay(ContentDisplay.LEFT); 181 setGraphic(checkBox); 182 } 183 184 185 /*************************************************************************** 186 * * 187 * Properties * 188 * * 189 **************************************************************************/ 190 191 // --- converter 192 private ObjectProperty<StringConverter<T>> converter = 193 new SimpleObjectProperty<StringConverter<T>>(this, "converter"); 194 195 /** 196 * The {@link StringConverter} property. 197 */ 198 public final ObjectProperty<StringConverter<T>> converterProperty() { 199 return converter; 200 } 201 202 /** 203 * Sets the {@link StringConverter} to be used in this cell. 204 */ 205 public final void setConverter(StringConverter<T> value) { 206 converterProperty().set(value); 207 } 208 209 /** 210 * Returns the {@link StringConverter} used in this cell. 211 */ 212 public final StringConverter<T> getConverter() { 213 return converterProperty().get(); 214 } 215 216 217 // --- selected state callback property 218 private ObjectProperty<Callback<T, ObservableValue<Boolean>>> 219 selectedStateCallback = 220 new SimpleObjectProperty<Callback<T, ObservableValue<Boolean>>>( 221 this, "selectedStateCallback"); 222 223 /** 224 * Property representing the {@link Callback} that is bound to by the 225 * CheckBox shown on screen. 226 */ 227 public final ObjectProperty<Callback<T, ObservableValue<Boolean>>> selectedStateCallbackProperty() { 228 return selectedStateCallback; 229 } 230 231 /** 232 * Sets the {@link Callback} that is bound to by the CheckBox shown on screen. 233 */ 234 public final void setSelectedStateCallback(Callback<T, ObservableValue<Boolean>> value) { 235 selectedStateCallbackProperty().set(value); 236 } 237 238 /** 239 * Returns the {@link Callback} that is bound to by the CheckBox shown on screen. 240 */ 241 public final Callback<T, ObservableValue<Boolean>> getSelectedStateCallback() { 242 return selectedStateCallbackProperty().get(); 243 } 244 245 246 247 /*************************************************************************** 248 * * 249 * Public API * 250 * * 251 **************************************************************************/ 252 253 /** {@inheritDoc} */ 254 @Override public void updateItem(T item, boolean empty) { 255 super.updateItem(item, empty); 256 257 if (! empty) { 258 StringConverter c = getConverter(); 259 Callback<T, ObservableValue<Boolean>> callback = getSelectedStateCallback(); 260 if (callback == null) { 261 throw new NullPointerException( 262 "The CheckBoxListCell selectedStateCallbackProperty can not be null"); 263 } 264 265 setGraphic(checkBox); 266 setText(c != null ? c.toString(item) : (item == null ? "" : item.toString())); 267 268 if (booleanProperty != null) { 269 checkBox.selectedProperty().unbindBidirectional((BooleanProperty)booleanProperty); 270 } 271 booleanProperty = callback.call(item); 272 if (booleanProperty != null) { 273 checkBox.selectedProperty().bindBidirectional((BooleanProperty)booleanProperty); 274 } 275 } else { 276 setGraphic(null); 277 setText(null); 278 } 279 } 280}