Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2010, 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.beans.binding; 027 028import javafx.beans.InvalidationListener; 029import javafx.beans.Observable; 030import javafx.beans.value.ChangeListener; 031import javafx.collections.FXCollections; 032import javafx.collections.ObservableList; 033import com.sun.javafx.collections.annotations.ReturnsUnmodifiableCollection; 034 035import com.sun.javafx.binding.BindingHelperObserver; 036import com.sun.javafx.binding.ExpressionHelper; 037 038/** 039 * Base class that provides most of the functionality needed to implement a 040 * {@link Binding} of a {@code float} value. 041 * <p> 042 * {@code FloatBinding} provides a simple invalidation-scheme. An extending 043 * class can register dependencies by calling {@link #bind(Observable...)}. 044 * If One of the registered dependencies becomes invalid, this 045 * {@code FloatBinding} is marked as invalid. With 046 * {@link #unbind(Observable...)} listening to dependencies can be stopped. 047 * <p> 048 * To provide a concrete implementation of this class, the method 049 * {@link #computeValue()} has to be implemented to calculate the value of this 050 * binding based on the current state of the dependencies. It is called when 051 * {@link #get()} is called for an invalid binding. 052 * <p> 053 * See {@link DoubleBinding} for an example how this base class can be extended. 054 * 055 * @see Binding 056 * @see NumberBinding 057 * @see javafx.beans.binding.FloatExpression 058 * 059 * 060 */ 061public abstract class FloatBinding extends FloatExpression implements 062 NumberBinding { 063 064 private float value; 065 private boolean valid; 066 private BindingHelperObserver observer; 067 private ExpressionHelper<Number> helper = null; 068 069 @Override 070 public void addListener(InvalidationListener listener) { 071 helper = ExpressionHelper.addListener(helper, this, listener); 072 } 073 074 @Override 075 public void removeListener(InvalidationListener listener) { 076 helper = ExpressionHelper.removeListener(helper, listener); 077 } 078 079 @Override 080 public void addListener(ChangeListener<? super Number> listener) { 081 helper = ExpressionHelper.addListener(helper, this, listener); 082 } 083 084 @Override 085 public void removeListener(ChangeListener<? super Number> listener) { 086 helper = ExpressionHelper.removeListener(helper, listener); 087 } 088 089 /** 090 * Start observing the dependencies for changes. If the value of one of the 091 * dependencies changes, the binding is marked as invalid. 092 * 093 * @param dependencies 094 * the dependencies to observe 095 */ 096 protected final void bind(Observable... dependencies) { 097 if ((dependencies != null) && (dependencies.length > 0)) { 098 if (observer == null) { 099 observer = new BindingHelperObserver(this); 100 } 101 for (final Observable dep : dependencies) { 102 dep.addListener(observer); 103 } 104 } 105 } 106 107 /** 108 * Stop observing the dependencies for changes. 109 * 110 * @param dependencies 111 * the dependencies to stop observing 112 */ 113 protected final void unbind(Observable... dependencies) { 114 if (observer != null) { 115 for (final Observable dep : dependencies) { 116 dep.removeListener(observer); 117 } 118 observer = null; 119 } 120 } 121 122 /** 123 * A default implementation of {@code dispose()} that is empty. 124 */ 125 @Override 126 public void dispose() { 127 } 128 129 /** 130 * A default implementation of {@code getDependencies()} that returns an 131 * empty {@link javafx.collections.ObservableList}. 132 * 133 * @return an empty {@code ObservableList} 134 */ 135 @Override 136 @ReturnsUnmodifiableCollection 137 public ObservableList<?> getDependencies() { 138 return FXCollections.emptyObservableList(); 139 } 140 141 /** 142 * Returns the result of {@link #computeValue()}. The method 143 * {@code computeValue()} is only called if the binding is invalid. The 144 * result is cached and returned if the binding did not become invalid since 145 * the last call of {@code getValue}. 146 */ 147 @Override 148 public final float get() { 149 if (!valid) { 150 value = computeValue(); 151 valid = true; 152 } 153 return value; 154 } 155 156 /** 157 * The method onInvalidating() can be overridden by extending classes to 158 * react, if this binding becomes invalid. The default implementation is 159 * empty. 160 */ 161 protected void onInvalidating() { 162 } 163 164 @Override 165 public final void invalidate() { 166 if (valid) { 167 valid = false; 168 onInvalidating(); 169 ExpressionHelper.fireValueChangedEvent(helper); 170 } 171 } 172 173 @Override 174 public final boolean isValid() { 175 return valid; 176 } 177 178 /** 179 * Calculates the current value of this binding. 180 * <p> 181 * Classes extending {@code FloatBinding} have to provide an implementation 182 * of {@code computeValue}. 183 * 184 * @return the current value 185 */ 186 protected abstract float computeValue(); 187 188 /** 189 * Returns a string representation of this {@code FloatBinding} object. 190 * @return a string representation of this {@code FloatBinding} object. 191 */ 192 @Override 193 public String toString() { 194 return valid ? "FloatBinding [value: " + get() + "]" 195 : "FloatBinding [invalid]"; 196 } 197}