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 boolean} value. 041 * <p> 042 * {@code BooleanBinding} 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 BooleanBinding} 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 javafx.beans.binding.BooleanExpression 057 * 058 */ 059public abstract class BooleanBinding extends BooleanExpression implements 060 Binding<Boolean> { 061 062 private boolean value; 063 private boolean valid = false; 064 private BindingHelperObserver observer; 065 private ExpressionHelper<Boolean> helper = null; 066 067 @Override 068 public void addListener(InvalidationListener listener) { 069 helper = ExpressionHelper.addListener(helper, this, listener); 070 } 071 072 @Override 073 public void removeListener(InvalidationListener listener) { 074 helper = ExpressionHelper.removeListener(helper, listener); 075 } 076 077 @Override 078 public void addListener(ChangeListener<? super Boolean> listener) { 079 helper = ExpressionHelper.addListener(helper, this, listener); 080 } 081 082 @Override 083 public void removeListener(ChangeListener<? super Boolean> listener) { 084 helper = ExpressionHelper.removeListener(helper, listener); 085 } 086 087 /** 088 * Start observing the dependencies for changes. If the value of one of the 089 * dependencies changes, the binding is marked as invalid. 090 * 091 * @param dependencies 092 * the dependencies to observe 093 */ 094 protected final void bind(Observable... dependencies) { 095 if ((dependencies != null) && (dependencies.length > 0)) { 096 if (observer == null) { 097 observer = new BindingHelperObserver(this); 098 } 099 for (final Observable dep : dependencies) { 100 dep.addListener(observer); 101 } 102 } 103 } 104 105 /** 106 * Stop observing the dependencies for changes. 107 * 108 * @param dependencies 109 * the dependencies to stop observing 110 */ 111 protected final void unbind(Observable... dependencies) { 112 if (observer != null) { 113 for (final Observable dep : dependencies) { 114 dep.removeListener(observer); 115 } 116 observer = null; 117 } 118 } 119 120 /** 121 * A default implementation of {@code dispose()} that is empty. 122 */ 123 @Override 124 public void dispose() { 125 } 126 127 /** 128 * A default implementation of {@code getDependencies()} that returns an 129 * empty {@link javafx.collections.ObservableList}. 130 * 131 * @return an empty {@code ObservableList} 132 */ 133 @Override 134 @ReturnsUnmodifiableCollection 135 public ObservableList<?> getDependencies() { 136 return FXCollections.emptyObservableList(); 137 } 138 139 /** 140 * Returns the result of {@link #computeValue()}. The method 141 * {@code computeValue()} is only called if the binding is invalid. The 142 * result is cached and returned if the binding did not become invalid since 143 * the last call of {@code get()}. 144 * 145 * @return the current value 146 */ 147 @Override 148 public final boolean 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 BooleanBinding} have to provide an 182 * implementation of {@code computeValue}. 183 * 184 * @return the current value 185 */ 186 protected abstract boolean computeValue(); 187 188 /** 189 * Returns a string representation of this {@code BooleanBinding} object. 190 * @return a string representation of this {@code BooleanBinding} object. 191 */ 192 @Override 193 public String toString() { 194 return valid ? "BooleanBinding [value: " + get() + "]" 195 : "BooleanBinding [invalid]"; 196 } 197 198}