diff -r 63d458f96141 javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextAreaSkin.java --- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextAreaSkin.java Wed Jan 23 11:39:06 2013 -0500 +++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextAreaSkin.java Wed Jan 23 13:59:12 2013 -0800 @@ -754,7 +754,7 @@ promptNode.setManaged(false); promptNode.getStyleClass().add("text"); promptNode.visibleProperty().bind(usePromptText); - promptNode.fontProperty().bind(font); + promptNode.fontProperty().bind(getSkinnable().fontProperty()); promptNode.textProperty().bind(getSkinnable().promptTextProperty()); promptNode.fillProperty().bind(promptTextFill); } @@ -768,7 +768,7 @@ paragraphNode.getStyleClass().add("text"); paragraphNodes.getChildren().add(i, paragraphNode); - paragraphNode.fontProperty().bind(font); + paragraphNode.fontProperty().bind(textArea.fontProperty()); paragraphNode.fillProperty().bind(textFill); paragraphNode.impl_selectionFillProperty().bind(highlightTextFill); } diff -r 63d458f96141 javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextFieldSkin.java --- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextFieldSkin.java Wed Jan 23 11:39:06 2013 -0500 +++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextFieldSkin.java Wed Jan 23 13:59:12 2013 -0800 @@ -185,7 +185,7 @@ // Add text textNode.setManaged(false); textNode.getStyleClass().add("text"); - textNode.fontProperty().bind(font); + textNode.fontProperty().bind(textField.fontProperty()); textNode.layoutXProperty().bind(textTranslateX); textNode.textProperty().bind(new StringBinding() { @@ -243,7 +243,7 @@ // Be sure to get the control to request layout when the font changes, // since this will affect the pref height and pref width. - font.addListener(new InvalidationListener() { + textField.fontProperty().addListener(new InvalidationListener() { @Override public void invalidated(Observable observable) { // I do both so that any cached values for prefWidth/height are cleared. // The problem is that the skin is unmanaged and so calling request layout @@ -393,7 +393,7 @@ promptNode.setManaged(false); promptNode.getStyleClass().add("text"); promptNode.visibleProperty().bind(usePromptText); - promptNode.fontProperty().bind(font); + promptNode.fontProperty().bind(getSkinnable().fontProperty()); promptNode.textProperty().bind(getSkinnable().promptTextProperty()); promptNode.fillProperty().bind(promptTextFill); diff -r 63d458f96141 javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextInputControlSkin.java --- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextInputControlSkin.java Wed Jan 23 11:39:06 2013 -0500 +++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextInputControlSkin.java Wed Jan 23 13:59:12 2013 -0800 @@ -40,6 +40,10 @@ import javafx.beans.value.ObservableBooleanValue; import javafx.beans.value.ObservableObjectValue; import javafx.collections.ObservableList; +import javafx.css.CssMetaData; +import javafx.css.StyleableBooleanProperty; +import javafx.css.StyleableObjectProperty; +import javafx.css.StyleableProperty; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.NodeOrientation; @@ -70,13 +74,9 @@ import javafx.scene.shape.PathElement; import javafx.scene.shape.Shape; import javafx.scene.shape.VLineTo; -import javafx.scene.text.Font; import javafx.stage.Window; import javafx.util.Duration; import com.sun.javafx.PlatformUtil; -import javafx.css.StyleableBooleanProperty; -import javafx.css.StyleableObjectProperty; -import javafx.css.CssMetaData; import com.sun.javafx.css.converters.BooleanConverter; import com.sun.javafx.css.converters.PaintConverter; import com.sun.javafx.scene.control.behavior.TextInputControlBehavior; @@ -85,42 +85,13 @@ import static com.sun.javafx.PlatformUtil.*; import static com.sun.javafx.scene.control.skin.resources.ControlResources.*; -import javafx.css.FontCssMetaData; -import javafx.css.StyleableProperty; /** * Abstract base class for text input skins. */ public abstract class TextInputControlSkin> extends BehaviorSkinBase { - /** - * The font to use with this control. In 1.3 and prior we had a font property - * on the TextInputControl itself, however now we just do it via CSS - */ - protected final ObjectProperty font = new StyleableObjectProperty(Font.getDefault()) { - - @Override - public Object getBean() { - return TextInputControlSkin.this; - } - - @Override - public String getName() { - return "font"; - } - - @Override - public CssMetaData getCssMetaData() { - return StyleableProperties.FONT; - } - }; - protected final ObservableObjectValue fontMetrics = new ObjectBinding() { - { bind(font); } - @Override protected FontMetrics computeValue() { - invalidateMetrics(); - return Toolkit.getToolkit().getFontLoader().getFontMetrics(font.get()); - } - }; + protected final ObservableObjectValue fontMetrics; /** * The fill to use for the text under normal conditions @@ -292,6 +263,14 @@ public TextInputControlSkin(final T textInput, final B behavior) { super(textInput, behavior); + fontMetrics = new ObjectBinding() { + { bind(textInput.fontProperty()); } + @Override protected FontMetrics computeValue() { + invalidateMetrics(); + return Toolkit.getToolkit().getFontLoader().getFontMetrics(textInput.getFont()); + } + }; + caretTimeline.setCycleCount(Timeline.INDEFINITE); caretTimeline.getKeyFrames().addAll( new KeyFrame(Duration.ZERO, new EventHandler() { @@ -685,22 +664,6 @@ } private static class StyleableProperties { - private static final CssMetaData FONT = - new FontCssMetaData("-fx-font", Font.getDefault()) { - - @Override - public boolean isSettable(TextInputControl n) { - final TextInputControlSkin skin = (TextInputControlSkin) n.getSkin(); - return skin.font == null || !skin.font.isBound(); - } - - @Override - public StyleableProperty getStyleableProperty(TextInputControl n) { - final TextInputControlSkin skin = (TextInputControlSkin) n.getSkin(); - return (StyleableProperty)skin.font; - } - }; - private static final CssMetaData TEXT_FILL = new CssMetaData("-fx-text-fill", PaintConverter.getInstance(), Color.BLACK) { @@ -790,7 +753,6 @@ static { List styleables = new ArrayList(SkinBase.getClassCssMetaData()); Collections.addAll(styleables, - FONT, TEXT_FILL, PROMPT_TEXT_FILL, HIGHLIGHT_FILL, diff -r 63d458f96141 javafx-ui-controls/src/javafx/scene/control/SkinBase.java --- a/javafx-ui-controls/src/javafx/scene/control/SkinBase.java Wed Jan 23 11:39:06 2013 -0500 +++ b/javafx-ui-controls/src/javafx/scene/control/SkinBase.java Wed Jan 23 13:59:12 2013 -0800 @@ -420,7 +420,7 @@ /** @see Node#pseudoClassStateChanged */ public final void pseudoClassStateChanged(PseudoClass pseudoClass, boolean active) { - Control ctl = (Control)getSkinnable(); + Control ctl = getSkinnable(); if (ctl != null) { ctl.pseudoClassStateChanged(pseudoClass, active); } diff -r 63d458f96141 javafx-ui-controls/src/javafx/scene/control/TextField.java --- a/javafx-ui-controls/src/javafx/scene/control/TextField.java Wed Jan 23 11:39:06 2013 -0500 +++ b/javafx-ui-controls/src/javafx/scene/control/TextField.java Wed Jan 23 13:59:12 2013 -0800 @@ -25,27 +25,25 @@ package javafx.scene.control; -import com.sun.javafx.beans.annotations.DuplicateInBuilderProperties; import java.util.ArrayList; import java.util.Collections; import java.util.List; - import javafx.beans.InvalidationListener; import javafx.beans.property.IntegerProperty; import javafx.beans.property.IntegerPropertyBase; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectPropertyBase; import javafx.beans.value.ChangeListener; +import javafx.css.CssMetaData; +import javafx.css.StyleableObjectProperty; +import javafx.css.StyleableProperty; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Pos; - +import com.sun.javafx.beans.annotations.DuplicateInBuilderProperties; import com.sun.javafx.binding.ExpressionHelper; import com.sun.javafx.css.converters.EnumConverter; import com.sun.javafx.scene.control.skin.TextFieldSkin; -import javafx.css.CssMetaData; -import javafx.css.StyleableObjectProperty; -import javafx.css.StyleableProperty; /** @@ -279,7 +277,7 @@ private static final List STYLEABLES; static { final List styleables = - new ArrayList(Control.getClassCssMetaData()); + new ArrayList(TextInputControl.getClassCssMetaData()); Collections.addAll(styleables, ALIGNMENT ); diff -r 63d458f96141 javafx-ui-controls/src/javafx/scene/control/TextInputControl.java --- a/javafx-ui-controls/src/javafx/scene/control/TextInputControl.java Wed Jan 23 11:39:06 2013 -0500 +++ b/javafx-ui-controls/src/javafx/scene/control/TextInputControl.java Wed Jan 23 13:59:12 2013 -0800 @@ -26,13 +26,16 @@ package javafx.scene.control; import java.text.BreakIterator; -import java.util.Set; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import javafx.beans.DefaultProperty; import javafx.beans.InvalidationListener; import javafx.beans.Observable; import javafx.beans.binding.IntegerBinding; import javafx.beans.binding.StringBinding; import javafx.beans.property.BooleanProperty; +import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyIntegerProperty; import javafx.beans.property.ReadOnlyIntegerWrapper; import javafx.beans.property.ReadOnlyObjectProperty; @@ -45,11 +48,17 @@ import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableStringValue; import javafx.beans.value.ObservableValue; +import javafx.css.CssMetaData; +import javafx.css.FontCssMetaData; +import javafx.css.PseudoClass; +import javafx.css.StyleOrigin; +import javafx.css.StyleableObjectProperty; +import javafx.css.StyleableProperty; import javafx.scene.input.Clipboard; import javafx.scene.input.ClipboardContent; +import javafx.scene.text.Font; import com.sun.javafx.Utils; import com.sun.javafx.binding.ExpressionHelper; -import javafx.css.PseudoClass; /** * Abstract base class for text input controls. @@ -154,6 +163,59 @@ **************************************************************************/ /** + * The default font to use for text in the TextInputControl. If the TextInputControl's text is + * rich text then this font may or may not be used depending on the font + * information embedded in the rich text, but in any case where a default + * font is required, this font will be used. + */ + public final ObjectProperty fontProperty() { + if (font == null) { + font = new StyleableObjectProperty(Font.getDefault()) { + + @Override + public void set(Font value) { + final Font oldValue = get(); + if (value == null ? oldValue == null : value.equals(oldValue)) { + return; + } + super.set(value); + } + + @Override + protected void invalidated() { + // RT-20727 - if font is changed by calling setFont, then + // css might need to be reapplied since font size affects + // calculated values for styles with relative values + StyleOrigin origin = ((StyleableProperty)font).getStyleOrigin(); + if (origin == null || origin == StyleOrigin.USER) { + TextInputControl.this.impl_reapplyCSS(); + } + } + + @Override + public CssMetaData getCssMetaData() { + return StyleableProperties.FONT; + } + + @Override + public Object getBean() { + return TextInputControl.this; + } + + @Override + public String getName() { + return "font"; + } + }; + } + return font; + } + + private ObjectProperty font; + public final void setFont(Font value) { fontProperty().setValue(value); } + public final Font getFont() { return font == null ? Font.getDefault() : font.getValue(); } + + /** * The prompt text to display in the {@code TextInputControl}, or * null if no prompt text is displayed. * @since 2.2 @@ -1036,7 +1098,6 @@ } - /*************************************************************************** * * * Stylesheet Handling * @@ -1047,4 +1108,50 @@ private static final PseudoClass PSEUDO_CLASS_READONLY = PseudoClass.getPseudoClass("readonly"); + /** + * @treatAsPrivate implementation detail + */ + private static class StyleableProperties { + private static final FontCssMetaData FONT = + new FontCssMetaData("-fx-font", Font.getDefault()) { + + @Override + public boolean isSettable(TextInputControl n) { + return n.font == null || !n.font.isBound(); + } + + @Override + public StyleableProperty getStyleableProperty(TextInputControl n) { + return (StyleableProperty)n.fontProperty(); + } + }; + + private static final List STYLEABLES; + static { + final List styleables = + new ArrayList(Control.getClassCssMetaData()); + Collections.addAll( + styleables, + FONT + ); + STYLEABLES = Collections.unmodifiableList(styleables); + } + } + + /** + * @return The CssMetaData associated with this class, which may include the + * CssMetaData of its super classes. + */ + public static List getClassCssMetaData() { + return StyleableProperties.STYLEABLES; + } + + /** + * {@inheritDoc} + */ + @Override + public List getControlCssMetaData() { + return getClassCssMetaData(); + } + }