< prev index next > modules/javafx.graphics/src/main/java/javafx/scene/text/Text.java
Print this page
import javafx.css.CssMetaData;
import javafx.css.FontCssMetaData;
import javafx.css.Styleable;
import javafx.css.StyleableBooleanProperty;
import javafx.css.StyleableDoubleProperty;
+ import javafx.css.StyleableIntegerProperty;
import javafx.css.StyleableObjectProperty;
import javafx.css.StyleableProperty;
import javafx.geometry.BoundingBox;
import javafx.geometry.Bounds;
import javafx.geometry.NodeOrientation;
if (getEffectiveNodeOrientation() == NodeOrientation.RIGHT_TO_LEFT) {
layout.setDirection(TextLayout.DIRECTION_RTL);
} else {
layout.setDirection(TextLayout.DIRECTION_LTR);
}
+ layout.setTabSize(getTabSize());
}
return layout;
}
private GlyphList[] textRuns = null;
y = getYAdjustment(getVisualBounds()) + (float)getY();
}
return TransformedShape.translatedShape(shape, x, y);
}
+ /**
+ * The size of a tab stop in spaces.
+ *
+ * @return the {@code tabSize} property
+ *
+ * @defaultValue {@code 8}
+ *
+ * @since 14
+ */
+ public final IntegerProperty tabSizeProperty() {
+ return getTextAttribute().tabSizeProperty();
+ }
+
+ /**
+ * Gets the size of a tab stop in spaces.
+ * @return the size of a tab in spaces
+ * @since 14
+ */
+ public final int getTabSize() {
+ if (attributes == null || attributes.tabSize == null) {
+ return TextLayout.DEFAULT_TAB_SIZE;
+ }
+ return getTextAttribute().getTabSize();
+ }
+
+ /**
+ * Sets the size of a tab stop.
+ * @param spaces the size of a tab in spaces. Defaults to 8.
+ * Minimum is 1, lower values will be clamped to 1.
+ * @since 14
+ */
+ public final void setTabSize(int spaces) {
+ tabSizeProperty().set(spaces);
+ }
+
+
/***************************************************************************
* *
* Stylesheet Handling *
* *
**************************************************************************/
/*
* Super-lazy instantiation pattern from Bill Pugh.
*/
- private static class StyleableProperties {
+ private static class StyleableProperties {
- private static final CssMetaData<Text,Font> FONT =
+ private static final CssMetaData<Text,Font> FONT =
new FontCssMetaData<Text>("-fx-font", Font.getDefault()) {
@Override
public boolean isSettable(Text node) {
return node.font == null || !node.font.isBound();
@Override
public StyleableProperty<Font> getStyleableProperty(Text node) {
return (StyleableProperty<Font>)node.fontProperty();
}
- };
+ };
- private static final CssMetaData<Text,Boolean> UNDERLINE =
+ private static final CssMetaData<Text,Boolean> UNDERLINE =
new CssMetaData<Text,Boolean>("-fx-underline",
- BooleanConverter.getInstance(), Boolean.FALSE) {
+ BooleanConverter.getInstance(), Boolean.FALSE) {
@Override
public boolean isSettable(Text node) {
return node.attributes == null ||
node.attributes.underline == null ||
@Override
public StyleableProperty<Boolean> getStyleableProperty(Text node) {
return (StyleableProperty<Boolean>)node.underlineProperty();
}
- };
+ };
- private static final CssMetaData<Text,Boolean> STRIKETHROUGH =
+ private static final CssMetaData<Text,Boolean> STRIKETHROUGH =
new CssMetaData<Text,Boolean>("-fx-strikethrough",
- BooleanConverter.getInstance(), Boolean.FALSE) {
+ BooleanConverter.getInstance(), Boolean.FALSE) {
@Override
public boolean isSettable(Text node) {
return node.attributes == null ||
node.attributes.strikethrough == null ||
@Override
public StyleableProperty<Boolean> getStyleableProperty(Text node) {
return (StyleableProperty<Boolean>)node.strikethroughProperty();
}
- };
+ };
- private static final
- CssMetaData<Text,TextAlignment> TEXT_ALIGNMENT =
- new CssMetaData<Text,TextAlignment>("-fx-text-alignment",
- new EnumConverter<TextAlignment>(TextAlignment.class),
- TextAlignment.LEFT) {
+ private static final
+ CssMetaData<Text,TextAlignment> TEXT_ALIGNMENT =
+ new CssMetaData<Text,TextAlignment>("-fx-text-alignment",
+ new EnumConverter<TextAlignment>(TextAlignment.class),
+ TextAlignment.LEFT) {
@Override
public boolean isSettable(Text node) {
return node.attributes == null ||
node.attributes.textAlignment == null ||
@Override
public StyleableProperty<TextAlignment> getStyleableProperty(Text node) {
return (StyleableProperty<TextAlignment>)node.textAlignmentProperty();
}
- };
+ };
- private static final CssMetaData<Text,VPos> TEXT_ORIGIN =
- new CssMetaData<Text,VPos>("-fx-text-origin",
- new EnumConverter<VPos>(VPos.class),
- VPos.BASELINE) {
+ private static final CssMetaData<Text,VPos> TEXT_ORIGIN =
+ new CssMetaData<Text,VPos>("-fx-text-origin",
+ new EnumConverter<VPos>(VPos.class),
+ VPos.BASELINE) {
@Override
public boolean isSettable(Text node) {
return node.attributes == null ||
node.attributes.textOrigin == null ||
@Override
public StyleableProperty<VPos> getStyleableProperty(Text node) {
return (StyleableProperty<VPos>)node.textOriginProperty();
}
- };
+ };
- private static final CssMetaData<Text,FontSmoothingType>
- FONT_SMOOTHING_TYPE =
- new CssMetaData<Text,FontSmoothingType>(
- "-fx-font-smoothing-type",
- new EnumConverter<FontSmoothingType>(FontSmoothingType.class),
- FontSmoothingType.GRAY) {
+ private static final CssMetaData<Text,FontSmoothingType>
+ FONT_SMOOTHING_TYPE =
+ new CssMetaData<Text,FontSmoothingType>(
+ "-fx-font-smoothing-type",
+ new EnumConverter<FontSmoothingType>(FontSmoothingType.class),
+ FontSmoothingType.GRAY) {
@Override
public boolean isSettable(Text node) {
return node.fontSmoothingType == null ||
!node.fontSmoothingType.isBound();
public StyleableProperty<FontSmoothingType>
getStyleableProperty(Text node) {
return (StyleableProperty<FontSmoothingType>)node.fontSmoothingTypeProperty();
}
- };
+ };
- private static final
- CssMetaData<Text,Number> LINE_SPACING =
- new CssMetaData<Text,Number>("-fx-line-spacing",
- SizeConverter.getInstance(), 0) {
+ private static final
+ CssMetaData<Text,Number> LINE_SPACING =
+ new CssMetaData<Text,Number>("-fx-line-spacing",
+ SizeConverter.getInstance(), 0) {
@Override
public boolean isSettable(Text node) {
return node.attributes == null ||
node.attributes.lineSpacing == null ||
@Override
public StyleableProperty<Number> getStyleableProperty(Text node) {
return (StyleableProperty<Number>)node.lineSpacingProperty();
}
- };
+ };
- private static final CssMetaData<Text, TextBoundsType>
- BOUNDS_TYPE =
- new CssMetaData<Text,TextBoundsType>(
- "-fx-bounds-type",
- new EnumConverter<TextBoundsType>(TextBoundsType.class),
- DEFAULT_BOUNDS_TYPE) {
+ private static final CssMetaData<Text, TextBoundsType>
+ BOUNDS_TYPE =
+ new CssMetaData<Text,TextBoundsType>(
+ "-fx-bounds-type",
+ new EnumConverter<TextBoundsType>(TextBoundsType.class),
+ DEFAULT_BOUNDS_TYPE) {
@Override
public boolean isSettable(Text node) {
return node.boundsType == null || !node.boundsType.isBound();
}
@Override
public StyleableProperty<TextBoundsType> getStyleableProperty(Text node) {
return (StyleableProperty<TextBoundsType>)node.boundsTypeProperty();
}
- };
+ };
+
+ private static final CssMetaData<Text,Number> TAB_SIZE =
+ new CssMetaData<Text,Number>("-fx-tab-size",
+ SizeConverter.getInstance(), TextLayout.DEFAULT_TAB_SIZE) {
+
+ @Override
+ public boolean isSettable(Text node) {
+ return node.attributes == null ||
+ node.attributes.tabSize == null ||
+ !node.attributes.tabSize.isBound();
+ }
- private final static List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
- static {
+ @Override
+ public StyleableProperty<Number> getStyleableProperty(Text node) {
+ return (StyleableProperty<Number>)node.tabSizeProperty();
+ }
+ };
+
+ private final static List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
+ static {
final List<CssMetaData<? extends Styleable, ?>> styleables =
new ArrayList<CssMetaData<? extends Styleable, ?>>(Shape.getClassCssMetaData());
styleables.add(FONT);
styleables.add(UNDERLINE);
styleables.add(STRIKETHROUGH);
styleables.add(TEXT_ALIGNMENT);
styleables.add(TEXT_ORIGIN);
styleables.add(FONT_SMOOTHING_TYPE);
styleables.add(LINE_SPACING);
styleables.add(BOUNDS_TYPE);
+ styleables.add(TAB_SIZE);
STYLEABLES = Collections.unmodifiableList(styleables);
- }
+ }
}
/**
* @return The CssMetaData associated with this class, which may include the
* CssMetaData of its superclasses.
caretBias =
new SimpleBooleanProperty(Text.this, "caretBias", DEFAULT_CARET_BIAS);
}
return caretBias;
}
+
+ private IntegerProperty tabSize;
+
+ final int getTabSize() {
+ return tabSize == null ? TextLayout.DEFAULT_TAB_SIZE : tabSize.get();
+ }
+
+ final IntegerProperty tabSizeProperty() {
+ if (tabSize == null) {
+ tabSize = new StyleableIntegerProperty(TextLayout.DEFAULT_TAB_SIZE) {
+ @Override public Object getBean() { return Text.this; }
+ @Override public String getName() { return "tabSize"; }
+ @Override public CssMetaData getCssMetaData() {
+ return StyleableProperties.TAB_SIZE;
+ }
+ @Override public void set(int v) { super.set((v < 1) ? 1 : v); }
+ @Override protected void invalidated() {
+ TextLayout layout = getTextLayout();
+ if (layout.setTabSize(get())) {
+ needsTextLayout();
+ }
+ NodeHelper.markDirty(Text.this, DirtyBits.TEXT_ATTRS);
+ if (getBoundsType() == TextBoundsType.VISUAL) {
+ NodeHelper.geomChanged(Text.this);
+ }
+ }
+ };
+ }
+ return tabSize;
+ }
}
/**
* Returns a string representation of this {@code Text} object.
* @return a string representation of this {@code Text} object.
< prev index next >