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.scene.control; 027 028import java.util.ArrayList; 029import java.util.Collections; 030import java.util.List; 031import javafx.beans.InvalidationListener; 032import javafx.beans.property.IntegerProperty; 033import javafx.beans.property.ObjectProperty; 034import javafx.beans.property.ObjectPropertyBase; 035import javafx.beans.value.ChangeListener; 036import javafx.css.CssMetaData; 037import javafx.css.StyleableIntegerProperty; 038import javafx.css.StyleableObjectProperty; 039import javafx.css.StyleableProperty; 040import javafx.event.ActionEvent; 041import javafx.event.EventHandler; 042import javafx.geometry.Pos; 043import com.sun.javafx.binding.ExpressionHelper; 044import com.sun.javafx.css.converters.EnumConverter; 045import com.sun.javafx.css.converters.SizeConverter; 046import com.sun.javafx.scene.control.skin.TextFieldSkin; 047import javafx.css.Styleable; 048 049 050/** 051 * Text input component that allows a user to enter a single line of 052 * unformatted text. Unlike in previous releases of JavaFX, support for multi-line 053 * input is not available as part of the TextField control, however this is 054 * the sole-purpose of the {@link TextArea} control. Additionally, if you want 055 * a form of rich-text editing, there is also the 056 * {@link javafx.scene.web.HTMLEditor HTMLEditor} control. 057 * 058 * <p>TextField supports the notion of showing {@link #promptTextProperty() prompt text} 059 * to the user when there is no {@link #textProperty() text} already in the 060 * TextField (either via the user, or set programmatically). This is a useful 061 * way of informing the user as to what is expected in the text field, without 062 * having to resort to {@link Tooltip tooltips} or on-screen {@link Label labels}. 063 * 064 * @see TextArea 065 */ 066public class TextField extends TextInputControl { 067 // Text field content 068 private static final class TextFieldContent implements Content { 069 private ExpressionHelper<String> helper = null; 070 private StringBuilder characters = new StringBuilder(); 071 072 @Override public String get(int start, int end) { 073 return characters.substring(start, end); 074 } 075 076 @Override public void insert(int index, String text, boolean notifyListeners) { 077 text = TextInputControl.filterInput(text, true, true); 078 if (!text.isEmpty()) { 079 characters.insert(index, text); 080 if (notifyListeners) { 081 ExpressionHelper.fireValueChangedEvent(helper); 082 } 083 } 084 } 085 086 @Override public void delete(int start, int end, boolean notifyListeners) { 087 if (end > start) { 088 characters.delete(start, end); 089 if (notifyListeners) { 090 ExpressionHelper.fireValueChangedEvent(helper); 091 } 092 } 093 } 094 095 @Override public int length() { 096 return characters.length(); 097 } 098 099 @Override public String get() { 100 return characters.toString(); 101 } 102 103 @Override public void addListener(ChangeListener<? super String> changeListener) { 104 helper = ExpressionHelper.addListener(helper, this, changeListener); 105 } 106 107 @Override public void removeListener(ChangeListener<? super String> changeListener) { 108 helper = ExpressionHelper.removeListener(helper, changeListener); 109 } 110 111 @Override public String getValue() { 112 return get(); 113 } 114 115 @Override public void addListener(InvalidationListener listener) { 116 helper = ExpressionHelper.addListener(helper, this, listener); 117 } 118 119 @Override public void removeListener(InvalidationListener listener) { 120 helper = ExpressionHelper.removeListener(helper, listener); 121 } 122 } 123 124 /** 125 * The default value for {@link #prefColumnCount}. 126 */ 127 public static final int DEFAULT_PREF_COLUMN_COUNT = 12; 128 129 /** 130 * Creates a {@code TextField} with empty text content. 131 */ 132 public TextField() { 133 this(""); 134 } 135 136 /** 137 * Creates a {@code TextField} with initial text content. 138 * 139 * @param text A string for text content. 140 */ 141 public TextField(String text) { 142 super(new TextFieldContent()); 143 getStyleClass().add("text-field"); 144 setText(text); 145 } 146 147 /** 148 * Returns the character sequence backing the text field's content. 149 */ 150 public CharSequence getCharacters() { 151 return ((TextFieldContent)getContent()).characters; 152 } 153 154 155 /*************************************************************************** 156 * * 157 * Properties * 158 * * 159 **************************************************************************/ 160 161 /** 162 * The preferred number of text columns. This is used for 163 * calculating the {@code TextField}'s preferred width. 164 */ 165 private IntegerProperty prefColumnCount = new StyleableIntegerProperty(DEFAULT_PREF_COLUMN_COUNT) { 166 @Override 167 public void set(int value) { 168 if (value < 0) { 169 throw new IllegalArgumentException("value cannot be negative."); 170 } 171 172 super.set(value); 173 } 174 175 @Override public CssMetaData<TextField,Number> getCssMetaData() { 176 return StyleableProperties.PREF_COLUMN_COUNT; 177 } 178 179 @Override 180 public Object getBean() { 181 return TextField.this; 182 } 183 184 @Override 185 public String getName() { 186 return "prefColumnCount"; 187 } 188 }; 189 public final IntegerProperty prefColumnCountProperty() { return prefColumnCount; } 190 public final int getPrefColumnCount() { return prefColumnCount.getValue(); } 191 public final void setPrefColumnCount(int value) { prefColumnCount.setValue(value); } 192 193 194 /** 195 * The action handler associated with this text field, or 196 * <tt>null</tt> if no action handler is assigned. 197 * 198 * The action handler is normally called when the user types the ENTER key. 199 */ 200 private ObjectProperty<EventHandler<ActionEvent>> onAction = new ObjectPropertyBase<EventHandler<ActionEvent>>() { 201 @Override 202 protected void invalidated() { 203 setEventHandler(ActionEvent.ACTION, get()); 204 } 205 206 @Override 207 public Object getBean() { 208 return TextField.this; 209 } 210 211 @Override 212 public String getName() { 213 return "onAction"; 214 } 215 }; 216 public final ObjectProperty<EventHandler<ActionEvent>> onActionProperty() { return onAction; } 217 public final EventHandler<ActionEvent> getOnAction() { return onActionProperty().get(); } 218 public final void setOnAction(EventHandler<ActionEvent> value) { onActionProperty().set(value); } 219 220 /** 221 * Specifies how the text should be aligned when there is empty 222 * space within the TextField. 223 */ 224 public final ObjectProperty<Pos> alignmentProperty() { 225 if (alignment == null) { 226 alignment = new StyleableObjectProperty<Pos>(Pos.CENTER_LEFT) { 227 228 @Override public CssMetaData<TextField,Pos> getCssMetaData() { 229 return StyleableProperties.ALIGNMENT; 230 } 231 232 @Override public Object getBean() { 233 return TextField.this; 234 } 235 236 @Override public String getName() { 237 return "alignment"; 238 } 239 }; 240 } 241 return alignment; 242 } 243 private ObjectProperty<Pos> alignment; 244 public final void setAlignment(Pos value) { alignmentProperty().set(value); } 245 public final Pos getAlignment() { return alignment == null ? Pos.CENTER_LEFT : alignment.get(); } 246 247 /*************************************************************************** 248 * * 249 * Methods * 250 * * 251 **************************************************************************/ 252 253 /** {@inheritDoc} */ 254 @Override protected Skin<?> createDefaultSkin() { 255 return new TextFieldSkin(this); 256 } 257 258 /*************************************************************************** 259 * * 260 * Stylesheet Handling * 261 * * 262 **************************************************************************/ 263 264 /** 265 * @treatAsPrivate implementation detail 266 */ 267 private static class StyleableProperties { 268 private static final CssMetaData<TextField, Pos> ALIGNMENT = 269 new CssMetaData<TextField, Pos>("-fx-alignment", 270 new EnumConverter<Pos>(Pos.class), Pos.CENTER_LEFT ) { 271 272 @Override public boolean isSettable(TextField n) { 273 return (n.alignment == null || !n.alignment.isBound()); 274 } 275 276 @Override public StyleableProperty<Pos> getStyleableProperty(TextField n) { 277 return (StyleableProperty<Pos>)n.alignmentProperty(); 278 } 279 }; 280 281 private static final CssMetaData<TextField,Number> PREF_COLUMN_COUNT = 282 new CssMetaData<TextField,Number>("-fx-pref-column-count", 283 SizeConverter.getInstance(), DEFAULT_PREF_COLUMN_COUNT) { 284 285 @Override 286 public boolean isSettable(TextField n) { 287 return n.prefColumnCount == null || !n.prefColumnCount.isBound(); 288 } 289 290 @Override 291 public StyleableProperty<Number> getStyleableProperty(TextField n) { 292 return (StyleableProperty<Number>)n.prefColumnCountProperty(); 293 } 294 }; 295 296 private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES; 297 static { 298 final List<CssMetaData<? extends Styleable, ?>> styleables = 299 new ArrayList<CssMetaData<? extends Styleable, ?>>(TextInputControl.getClassCssMetaData()); 300 styleables.add(ALIGNMENT); 301 styleables.add(PREF_COLUMN_COUNT); 302 STYLEABLES = Collections.unmodifiableList(styleables); 303 } 304 } 305 306 /** 307 * @return The CssMetaData associated with this class, which may include the 308 * CssMetaData of its super classes. 309 */ 310 public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() { 311 return StyleableProperties.STYLEABLES; 312 } 313 314 /** 315 * {@inheritDoc} 316 */ 317 @Override 318 public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() { 319 return getClassCssMetaData(); 320 } 321}