Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2011, 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.property; 027 028import javafx.beans.InvalidationListener; 029import javafx.beans.Observable; 030import javafx.beans.binding.BooleanBinding; 031import javafx.beans.value.ChangeListener; 032import javafx.beans.value.ObservableBooleanValue; 033import javafx.beans.value.ObservableValue; 034 035import com.sun.javafx.binding.ExpressionHelper; 036 037/** 038 * The class {@code BooleanPropertyBase} is the base class for a property 039 * wrapping a {@code boolean} value. 040 * 041 * It provides all the functionality required for a property except for the 042 * {@link #getBean()} and {@link #getName()} methods, which must be implemented 043 * by extending classes. 044 * 045 * @see BooleanProperty 046 */ 047public abstract class BooleanPropertyBase extends BooleanProperty { 048 049 private boolean value; 050 private ObservableBooleanValue observable = null; 051 private InvalidationListener listener = null; 052 private boolean valid = true; 053 private ExpressionHelper<Boolean> helper = null; 054 055 /** 056 * The constructor of the {@code BooleanPropertyBase}. 057 */ 058 public BooleanPropertyBase() { 059 } 060 061 /** 062 * The constructor of the {@code BooleanPropertyBase}. 063 * 064 * @param initialValue 065 * the initial value of the wrapped value 066 */ 067 public BooleanPropertyBase(boolean initialValue) { 068 this.value = initialValue; 069 } 070 071 @Override 072 public void addListener(InvalidationListener listener) { 073 helper = ExpressionHelper.addListener(helper, this, listener); 074 } 075 076 @Override 077 public void removeListener(InvalidationListener listener) { 078 helper = ExpressionHelper.removeListener(helper, listener); 079 } 080 081 @Override 082 public void addListener(ChangeListener<? super Boolean> listener) { 083 helper = ExpressionHelper.addListener(helper, this, listener); 084 } 085 086 @Override 087 public void removeListener(ChangeListener<? super Boolean> listener) { 088 helper = ExpressionHelper.removeListener(helper, listener); 089 } 090 091 /** 092 * Sends notifications to all attached 093 * {@link javafx.beans.InvalidationListener InvalidationListeners} and 094 * {@link javafx.beans.value.ChangeListener ChangeListeners}. 095 * 096 * This method is called when the value is changed, either manually by 097 * calling {@link #set(boolean)} or in case of a bound property, if the 098 * binding becomes invalid. 099 */ 100 protected void fireValueChangedEvent() { 101 ExpressionHelper.fireValueChangedEvent(helper); 102 } 103 104 private void markInvalid() { 105 if (valid) { 106 valid = false; 107 invalidated(); 108 fireValueChangedEvent(); 109 } 110 } 111 112 /** 113 * The method {@code invalidated()} can be overridden to receive 114 * invalidation notifications. This is the preferred option in 115 * {@code Objects} defining the property, because it requires less memory. 116 * 117 * The default implementation is empty. 118 */ 119 protected void invalidated() { 120 } 121 122 /** 123 * {@inheritDoc} 124 */ 125 @Override 126 public boolean get() { 127 valid = true; 128 return observable == null ? value : observable.get(); 129 } 130 131 /** 132 * {@inheritDoc} 133 */ 134 @Override 135 public void set(boolean newValue) { 136 if (isBound()) { 137 throw new java.lang.RuntimeException("A bound value cannot be set."); 138 } 139 if (value != newValue) { 140 value = newValue; 141 markInvalid(); 142 } 143 } 144 145 /** 146 * {@inheritDoc} 147 */ 148 @Override 149 public boolean isBound() { 150 return observable != null; 151 } 152 153 /** 154 * {@inheritDoc} 155 */ 156 @Override 157 public void bind(final ObservableValue<? extends Boolean> rawObservable) { 158 if (rawObservable == null) { 159 throw new NullPointerException("Cannot bind to null"); 160 } 161 162 final ObservableBooleanValue newObservable = (rawObservable instanceof ObservableBooleanValue) ? (ObservableBooleanValue) rawObservable 163 : new BooleanBinding() { 164 { 165 super.bind(rawObservable); 166 } 167 168 @Override 169 protected boolean computeValue() { 170 final Boolean value = rawObservable.getValue(); 171 return (value == null)? false : value; 172 } 173 }; 174 175 if (!newObservable.equals(observable)) { 176 unbind(); 177 observable = newObservable; 178 if (listener == null) { 179 listener = new Listener(); 180 } 181 observable.addListener(listener); 182 markInvalid(); 183 } 184 } 185 186 /** 187 * {@inheritDoc} 188 */ 189 @Override 190 public void unbind() { 191 if (observable != null) { 192 value = observable.get(); 193 observable.removeListener(listener); 194 observable = null; 195 } 196 } 197 198 /** 199 * Returns a string representation of this {@code BooleanPropertyBase} object. 200 * @return a string representation of this {@code BooleanPropertyBase} object. 201 */ 202 @Override 203 public String toString() { 204 final Object bean = getBean(); 205 final String name = getName(); 206 final StringBuilder result = new StringBuilder("BooleanProperty ["); 207 if (bean != null) { 208 result.append("bean: ").append(bean).append(", "); 209 } 210 if ((name != null) && (!name.equals(""))) { 211 result.append("name: ").append(name).append(", "); 212 } 213 if (isBound()) { 214 result.append("bound, "); 215 if (valid) { 216 result.append("value: ").append(get()); 217 } else { 218 result.append("invalid"); 219 } 220 } else { 221 result.append("value: ").append(get()); 222 } 223 result.append("]"); 224 return result.toString(); 225 } 226 227 private class Listener implements InvalidationListener { 228 @Override 229 public void invalidated(Observable valueModel) { 230 markInvalid(); 231 } 232 } 233 234}