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 an {@code int} value. 041 * <p> 042 * {@code IntegerBinding} 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 IntegerBinding} 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.IntegerExpression 058 * 059 * 060 */ 061public abstract class IntegerBinding extends IntegerExpression implements 062 NumberBinding { 063 064 private int value; 065 private boolean valid = false; 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 get()}. 146 * 147 * @return the current value 148 */ 149 @Override 150 public final int get() { 151 if (!valid) { 152 value = computeValue(); 153 valid = true; 154 } 155 return value; 156 } 157 158 /** 159 * The method onInvalidating() can be overridden by extending classes to 160 * react, if this binding becomes invalid. The default implementation is 161 * empty. 162 */ 163 protected void onInvalidating() { 164 } 165 166 @Override 167 public final void invalidate() { 168 if (valid) { 169 valid = false; 170 onInvalidating(); 171 ExpressionHelper.fireValueChangedEvent(helper); 172 } 173 } 174 175 @Override 176 public final boolean isValid() { 177 return valid; 178 } 179 180 /** 181 * Calculates the current value of this binding. 182 * <p> 183 * Classes extending {@code IntegerBinding} have to provide an 184 * implementation of {@code computeValue}. 185 * 186 * @return the current value 187 */ 188 protected abstract int computeValue(); 189 190 /** 191 * Returns a string representation of this {@code IntegerBinding} object. 192 * @return a string representation of this {@code IntegerBinding} object. 193 */ 194 @Override 195 public String toString() { 196 return valid ? "IntegerBinding [value: " + get() + "]" 197 : "IntegerBinding [invalid]"; 198 } 199}