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 java.util.Map; 029 030import javafx.beans.property.ReadOnlyBooleanWrapper; 031import javafx.beans.property.ReadOnlyDoubleWrapper; 032import javafx.beans.property.ReadOnlyFloatWrapper; 033import javafx.beans.property.ReadOnlyIntegerWrapper; 034import javafx.beans.property.ReadOnlyLongWrapper; 035import javafx.beans.property.ReadOnlyObjectWrapper; 036import javafx.beans.property.ReadOnlyStringWrapper; 037import javafx.beans.value.ObservableValue; 038import javafx.scene.control.TableCell; 039import javafx.scene.control.TableColumn; 040import javafx.scene.control.TableColumn.CellDataFeatures; 041import javafx.scene.control.TableView; 042import javafx.util.Callback; 043 044/** 045 * A convenience implementation of the Callback interface, designed specifically 046 * for use within the {@link TableColumn} 047 * {@link TableColumn#cellValueFactoryProperty() cell value factory}. An example 048 * of how to use this class is: 049 * 050 * <pre><code> 051 * ObservableList<Map> personsMapList = ... 052 * 053 * TableColumn<Map, String> firstNameColumn = new TableColumn<Map, String>("First Name"); 054 * firstNameColumn.setCellValueFactory(new MapValueFactory<String>("firstName")); 055 * 056 * TableView<Map> table = new TableView<Map>(personMapList); 057 * tableView.getColumns().setAll(firstNameColumn); 058 * </code></pre> 059 * 060 * <p>In this example, there is a list of Map instances, where each Map instance 061 * representsa single row in the TableView. The "firstName" string is used as a 062 * key into this map, and the value corresponding to this key is returned, if 063 * one exists. If the value is an {@link ObservableValue}, then this is returned 064 * directly, otherwise the value is wrapped in a {@link ReadOnlyObjectWrapper}. 065 * 066 * @see TableColumn 067 * @see TableView 068 * @see TableCell 069 * @see PropertyValueFactory 070 * @param <T> The type of the class contained within the TableColumn cells. 071 * @since 2.2 072 */ 073public class MapValueFactory<T> implements Callback<CellDataFeatures<Map,T>, ObservableValue<T>> { 074 075 private final Object key; 076 077 /** 078 * Creates a default MapValueFactory, which will use the provided key to 079 * lookup the value for cells in the {@link TableColumn} in which this 080 * MapValueFactory is installed (via the 081 * {@link TableColumn#cellValueFactoryProperty() cell value factory} property. 082 * 083 * @param key The key to use to lookup the value in the {@code Map}. 084 */ 085 public MapValueFactory(final Object key) { 086 this.key = key; 087 } 088 089 @Override public ObservableValue<T> call(CellDataFeatures<Map, T> cdf) { 090 Map map = cdf.getValue(); 091 Object value = map.get(key); 092 093 // ideally the map will contain observable values directly, and in which 094 // case we can just return this observable value. 095 if (value instanceof ObservableValue) { 096 return (ObservableValue)value; 097 } 098 099 // TODO 100 // If we are here, the value in the map for the given key is not observable, 101 // but perhaps the Map is an ObservableMap. If this is the case, we 102 // can add a listener to the map for the given key, and possibly observe 103 // it for changes and return these 104// if (map instanceof ObservableMap) { 105// ObservableMap oMap = (ObservableMap) map; 106// // .... 107// } 108 109 // Often time there is special case code to deal with specific observable 110 // value types, so we try to wrap in the most specific type. 111 if (value instanceof Boolean) { 112 return (ObservableValue<T>) new ReadOnlyBooleanWrapper((Boolean)value); 113 } else if (value instanceof Integer) { 114 return (ObservableValue<T>) new ReadOnlyIntegerWrapper((Integer)value); 115 } else if (value instanceof Float) { 116 return (ObservableValue<T>) new ReadOnlyFloatWrapper((Float)value); 117 } else if (value instanceof Long) { 118 return (ObservableValue<T>) new ReadOnlyLongWrapper((Long)value); 119 } else if (value instanceof Double) { 120 return (ObservableValue<T>) new ReadOnlyDoubleWrapper((Double)value); 121 } else if (value instanceof String) { 122 return (ObservableValue<T>) new ReadOnlyStringWrapper((String)value); 123 } 124 125 // fall back to an object wrapper 126 return new ReadOnlyObjectWrapper<T>((T)value); 127 } 128}