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.value.ChangeListener; 031import javafx.beans.value.ObservableValue; 032 033import com.sun.javafx.binding.ExpressionHelper; 034 035/** 036 * The class {@code StringPropertyBase} is the base class for a property 037 * wrapping a {@code String} value. 038 * 039 * It provides all the functionality required for a property except for the 040 * {@link #getBean()} and {@link #getName()} methods, which must be implemented 041 * by extending classes. 042 * 043 * @see StringProperty 044 * 045 * 046 */ 047public abstract class StringPropertyBase extends StringProperty { 048 049 private String value; 050 private ObservableValue<? extends String> observable = null; 051 private InvalidationListener listener = null; 052 private boolean valid = true; 053 private ExpressionHelper<String> helper = null; 054 055 /** 056 * The constructor of the {@code StringPropertyBase}. 057 */ 058 public StringPropertyBase() { 059 } 060 061 /** 062 * The constructor of the {@code StringPropertyBase}. 063 * 064 * @param initialValue 065 * the initial value of the wrapped {@code String} 066 */ 067 public StringPropertyBase(String 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 String> listener) { 083 helper = ExpressionHelper.addListener(helper, this, listener); 084 } 085 086 @Override 087 public void removeListener(ChangeListener<? super String> 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} 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 String get() { 127 valid = true; 128 return observable == null ? value : observable.getValue(); 129 } 130 131 /** 132 * {@inheritDoc} 133 */ 134 @Override 135 public void set(String newValue) { 136 if (isBound()) { 137 throw new java.lang.RuntimeException("A bound value cannot be set."); 138 } 139 if ((value == null)? newValue != null : !value.equals(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(ObservableValue<? extends String> newObservable) { 158 if (newObservable == null) { 159 throw new NullPointerException("Cannot bind to null"); 160 } 161 if (!newObservable.equals(observable)) { 162 unbind(); 163 observable = newObservable; 164 if (listener == null) { 165 listener = new Listener(); 166 } 167 observable.addListener(listener); 168 markInvalid(); 169 } 170 } 171 172 /** 173 * {@inheritDoc} 174 */ 175 @Override 176 public void unbind() { 177 if (observable != null) { 178 value = observable.getValue(); 179 observable.removeListener(listener); 180 observable = null; 181 } 182 } 183 184 /** 185 * Returns a string representation of this {@code StringPropertyBase} object. 186 * @return a string representation of this {@code StringPropertyBase} object. 187 */ 188 @Override 189 public String toString() { 190 final Object bean = getBean(); 191 final String name = getName(); 192 final StringBuilder result = new StringBuilder("StringProperty ["); 193 if (bean != null) { 194 result.append("bean: ").append(bean).append(", "); 195 } 196 if ((name != null) && (!name.equals(""))) { 197 result.append("name: ").append(name).append(", "); 198 } 199 if (isBound()) { 200 result.append("bound, "); 201 if (valid) { 202 result.append("value: ").append(get()); 203 } else { 204 result.append("invalid"); 205 } 206 } else { 207 result.append("value: ").append(get()); 208 } 209 result.append("]"); 210 return result.toString(); 211 } 212 213 private class Listener implements InvalidationListener { 214 @Override 215 public void invalidated(Observable valueModel) { 216 markInvalid(); 217 } 218 } 219}