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