65 import java.util.List;
66 import javafx.beans.property.BooleanProperty;
67 import javafx.beans.property.DoubleProperty;
68 import javafx.beans.property.DoublePropertyBase;
69 import javafx.beans.property.IntegerProperty;
70 import javafx.beans.property.IntegerPropertyBase;
71 import javafx.beans.property.ObjectProperty;
72 import javafx.beans.property.ObjectPropertyBase;
73 import javafx.beans.property.ReadOnlyDoubleProperty;
74 import javafx.beans.property.ReadOnlyDoubleWrapper;
75 import javafx.beans.property.ReadOnlyObjectProperty;
76 import javafx.beans.property.SimpleBooleanProperty;
77 import javafx.beans.property.SimpleObjectProperty;
78 import javafx.beans.property.StringProperty;
79 import javafx.beans.property.StringPropertyBase;
80 import javafx.css.CssMetaData;
81 import javafx.css.FontCssMetaData;
82 import javafx.css.Styleable;
83 import javafx.css.StyleableBooleanProperty;
84 import javafx.css.StyleableDoubleProperty;
85 import javafx.css.StyleableObjectProperty;
86 import javafx.css.StyleableProperty;
87 import javafx.geometry.BoundingBox;
88 import javafx.geometry.Bounds;
89 import javafx.geometry.NodeOrientation;
90 import javafx.geometry.Point2D;
91 import javafx.geometry.VPos;
92 import javafx.scene.Node;
93
94 /**
95 * The {@code Text} class defines a node that displays a text.
96 *
97 * Paragraphs are separated by {@code '\n'} and the text is wrapped on
98 * paragraph boundaries.
99 *
100 <PRE>
101 import javafx.scene.text.*;
102
103 Text t = new Text(10, 50, "This is a test");
104 t.setFont(new Font(20));
290 layout = null;
291 TextFlow parent = (TextFlow)getParent();
292 return parent.getTextLayout();
293 }
294 if (layout == null) {
295 TextLayoutFactory factory = Toolkit.getToolkit().getTextLayoutFactory();
296 layout = factory.createLayout();
297 String string = getTextInternal();
298 Object font = getFontInternal();
299 TextAlignment alignment = getTextAlignment();
300 if (alignment == null) alignment = DEFAULT_TEXT_ALIGNMENT;
301 layout.setContent(string, font);
302 layout.setAlignment(alignment.ordinal());
303 layout.setLineSpacing((float)getLineSpacing());
304 layout.setWrapWidth((float)getWrappingWidth());
305 if (getEffectiveNodeOrientation() == NodeOrientation.RIGHT_TO_LEFT) {
306 layout.setDirection(TextLayout.DIRECTION_RTL);
307 } else {
308 layout.setDirection(TextLayout.DIRECTION_LTR);
309 }
310 }
311 return layout;
312 }
313
314 private GlyphList[] textRuns = null;
315 private BaseBounds spanBounds = new RectBounds(); /* relative to the textlayout */
316 private boolean spanBoundsInvalid = true;
317
318 void layoutSpan(GlyphList[] runs) {
319 TextSpan span = getTextSpan();
320 int count = 0;
321 for (int i = 0; i < runs.length; i++) {
322 GlyphList run = runs[i];
323 if (run.getTextSpan() == span) {
324 count++;
325 }
326 }
327 textRuns = new GlyphList[count];
328 count = 0;
329 for (int i = 0; i < runs.length; i++) {
1250 /*
1251 * Note: This method MUST only be called via its accessor method.
1252 */
1253 private com.sun.javafx.geom.Shape doConfigShape() {
1254 if (ShapeHelper.getMode(this) == NGShape.Mode.EMPTY || getTextInternal().length() == 0) {
1255 return new Path2D();
1256 }
1257 com.sun.javafx.geom.Shape shape = getShape();
1258 float x, y;
1259 if (isSpan()) {
1260 BaseBounds bounds = getSpanBounds();
1261 x = -bounds.getMinX();
1262 y = -bounds.getMinY();
1263 } else {
1264 x = (float)getX();
1265 y = getYAdjustment(getVisualBounds()) + (float)getY();
1266 }
1267 return TransformedShape.translatedShape(shape, x, y);
1268 }
1269
1270 /***************************************************************************
1271 * *
1272 * Stylesheet Handling *
1273 * *
1274 **************************************************************************/
1275
1276 /*
1277 * Super-lazy instantiation pattern from Bill Pugh.
1278 */
1279 private static class StyleableProperties {
1280
1281 private static final CssMetaData<Text,Font> FONT =
1282 new FontCssMetaData<Text>("-fx-font", Font.getDefault()) {
1283
1284 @Override
1285 public boolean isSettable(Text node) {
1286 return node.font == null || !node.font.isBound();
1287 }
1288
1289 @Override
1290 public StyleableProperty<Font> getStyleableProperty(Text node) {
1291 return (StyleableProperty<Font>)node.fontProperty();
1292 }
1293 };
1294
1295 private static final CssMetaData<Text,Boolean> UNDERLINE =
1296 new CssMetaData<Text,Boolean>("-fx-underline",
1297 BooleanConverter.getInstance(), Boolean.FALSE) {
1298
1299 @Override
1300 public boolean isSettable(Text node) {
1301 return node.attributes == null ||
1302 node.attributes.underline == null ||
1303 !node.attributes.underline.isBound();
1304 }
1305
1306 @Override
1307 public StyleableProperty<Boolean> getStyleableProperty(Text node) {
1308 return (StyleableProperty<Boolean>)node.underlineProperty();
1309 }
1310 };
1311
1312 private static final CssMetaData<Text,Boolean> STRIKETHROUGH =
1313 new CssMetaData<Text,Boolean>("-fx-strikethrough",
1314 BooleanConverter.getInstance(), Boolean.FALSE) {
1315
1316 @Override
1317 public boolean isSettable(Text node) {
1318 return node.attributes == null ||
1319 node.attributes.strikethrough == null ||
1320 !node.attributes.strikethrough.isBound();
1321 }
1322
1323 @Override
1324 public StyleableProperty<Boolean> getStyleableProperty(Text node) {
1325 return (StyleableProperty<Boolean>)node.strikethroughProperty();
1326 }
1327 };
1328
1329 private static final
1330 CssMetaData<Text,TextAlignment> TEXT_ALIGNMENT =
1331 new CssMetaData<Text,TextAlignment>("-fx-text-alignment",
1332 new EnumConverter<TextAlignment>(TextAlignment.class),
1333 TextAlignment.LEFT) {
1334
1335 @Override
1336 public boolean isSettable(Text node) {
1337 return node.attributes == null ||
1338 node.attributes.textAlignment == null ||
1339 !node.attributes.textAlignment.isBound();
1340 }
1341
1342 @Override
1343 public StyleableProperty<TextAlignment> getStyleableProperty(Text node) {
1344 return (StyleableProperty<TextAlignment>)node.textAlignmentProperty();
1345 }
1346 };
1347
1348 private static final CssMetaData<Text,VPos> TEXT_ORIGIN =
1349 new CssMetaData<Text,VPos>("-fx-text-origin",
1350 new EnumConverter<VPos>(VPos.class),
1351 VPos.BASELINE) {
1352
1353 @Override
1354 public boolean isSettable(Text node) {
1355 return node.attributes == null ||
1356 node.attributes.textOrigin == null ||
1357 !node.attributes.textOrigin.isBound();
1358 }
1359
1360 @Override
1361 public StyleableProperty<VPos> getStyleableProperty(Text node) {
1362 return (StyleableProperty<VPos>)node.textOriginProperty();
1363 }
1364 };
1365
1366 private static final CssMetaData<Text,FontSmoothingType>
1367 FONT_SMOOTHING_TYPE =
1368 new CssMetaData<Text,FontSmoothingType>(
1369 "-fx-font-smoothing-type",
1370 new EnumConverter<FontSmoothingType>(FontSmoothingType.class),
1371 FontSmoothingType.GRAY) {
1372
1373 @Override
1374 public boolean isSettable(Text node) {
1375 return node.fontSmoothingType == null ||
1376 !node.fontSmoothingType.isBound();
1377 }
1378
1379 @Override
1380 public StyleableProperty<FontSmoothingType>
1381 getStyleableProperty(Text node) {
1382
1383 return (StyleableProperty<FontSmoothingType>)node.fontSmoothingTypeProperty();
1384 }
1385 };
1386
1387 private static final
1388 CssMetaData<Text,Number> LINE_SPACING =
1389 new CssMetaData<Text,Number>("-fx-line-spacing",
1390 SizeConverter.getInstance(), 0) {
1391
1392 @Override
1393 public boolean isSettable(Text node) {
1394 return node.attributes == null ||
1395 node.attributes.lineSpacing == null ||
1396 !node.attributes.lineSpacing.isBound();
1397 }
1398
1399 @Override
1400 public StyleableProperty<Number> getStyleableProperty(Text node) {
1401 return (StyleableProperty<Number>)node.lineSpacingProperty();
1402 }
1403 };
1404
1405 private static final CssMetaData<Text, TextBoundsType>
1406 BOUNDS_TYPE =
1407 new CssMetaData<Text,TextBoundsType>(
1408 "-fx-bounds-type",
1409 new EnumConverter<TextBoundsType>(TextBoundsType.class),
1410 DEFAULT_BOUNDS_TYPE) {
1411
1412 @Override
1413 public boolean isSettable(Text node) {
1414 return node.boundsType == null || !node.boundsType.isBound();
1415 }
1416
1417 @Override
1418 public StyleableProperty<TextBoundsType> getStyleableProperty(Text node) {
1419 return (StyleableProperty<TextBoundsType>)node.boundsTypeProperty();
1420 }
1421 };
1422
1423 private final static List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
1424 static {
1425 final List<CssMetaData<? extends Styleable, ?>> styleables =
1426 new ArrayList<CssMetaData<? extends Styleable, ?>>(Shape.getClassCssMetaData());
1427 styleables.add(FONT);
1428 styleables.add(UNDERLINE);
1429 styleables.add(STRIKETHROUGH);
1430 styleables.add(TEXT_ALIGNMENT);
1431 styleables.add(TEXT_ORIGIN);
1432 styleables.add(FONT_SMOOTHING_TYPE);
1433 styleables.add(LINE_SPACING);
1434 styleables.add(BOUNDS_TYPE);
1435 STYLEABLES = Collections.unmodifiableList(styleables);
1436 }
1437 }
1438
1439 /**
1440 * @return The CssMetaData associated with this class, which may include the
1441 * CssMetaData of its superclasses.
1442 * @since JavaFX 8.0
1443 */
1444 public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
1445 return StyleableProperties.STYLEABLES;
1446 }
1447
1448 /**
1449 * {@inheritDoc}
1450 *
1451 * @since JavaFX 8.0
1452 */
1453
1454
1455 @Override
1456 public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
1804 notifyAccessibleAttributeChanged(AccessibleAttribute.SELECTION_END);
1805 }
1806 };
1807 }
1808 return caretPosition;
1809 }
1810
1811 private BooleanProperty caretBias;
1812
1813 final boolean isCaretBias() {
1814 return caretBias == null ? DEFAULT_CARET_BIAS : caretBias.get();
1815 }
1816
1817 final BooleanProperty caretBiasProperty() {
1818 if (caretBias == null) {
1819 caretBias =
1820 new SimpleBooleanProperty(Text.this, "caretBias", DEFAULT_CARET_BIAS);
1821 }
1822 return caretBias;
1823 }
1824 }
1825
1826 /**
1827 * Returns a string representation of this {@code Text} object.
1828 * @return a string representation of this {@code Text} object.
1829 */
1830 @Override
1831 public String toString() {
1832 final StringBuilder sb = new StringBuilder("Text[");
1833
1834 String id = getId();
1835 if (id != null) {
1836 sb.append("id=").append(id).append(", ");
1837 }
1838
1839 sb.append("text=\"").append(getText()).append("\"");
1840 sb.append(", x=").append(getX());
1841 sb.append(", y=").append(getY());
1842 sb.append(", alignment=").append(getTextAlignment());
1843 sb.append(", origin=").append(getTextOrigin());
|
65 import java.util.List;
66 import javafx.beans.property.BooleanProperty;
67 import javafx.beans.property.DoubleProperty;
68 import javafx.beans.property.DoublePropertyBase;
69 import javafx.beans.property.IntegerProperty;
70 import javafx.beans.property.IntegerPropertyBase;
71 import javafx.beans.property.ObjectProperty;
72 import javafx.beans.property.ObjectPropertyBase;
73 import javafx.beans.property.ReadOnlyDoubleProperty;
74 import javafx.beans.property.ReadOnlyDoubleWrapper;
75 import javafx.beans.property.ReadOnlyObjectProperty;
76 import javafx.beans.property.SimpleBooleanProperty;
77 import javafx.beans.property.SimpleObjectProperty;
78 import javafx.beans.property.StringProperty;
79 import javafx.beans.property.StringPropertyBase;
80 import javafx.css.CssMetaData;
81 import javafx.css.FontCssMetaData;
82 import javafx.css.Styleable;
83 import javafx.css.StyleableBooleanProperty;
84 import javafx.css.StyleableDoubleProperty;
85 import javafx.css.StyleableIntegerProperty;
86 import javafx.css.StyleableObjectProperty;
87 import javafx.css.StyleableProperty;
88 import javafx.geometry.BoundingBox;
89 import javafx.geometry.Bounds;
90 import javafx.geometry.NodeOrientation;
91 import javafx.geometry.Point2D;
92 import javafx.geometry.VPos;
93 import javafx.scene.Node;
94
95 /**
96 * The {@code Text} class defines a node that displays a text.
97 *
98 * Paragraphs are separated by {@code '\n'} and the text is wrapped on
99 * paragraph boundaries.
100 *
101 <PRE>
102 import javafx.scene.text.*;
103
104 Text t = new Text(10, 50, "This is a test");
105 t.setFont(new Font(20));
291 layout = null;
292 TextFlow parent = (TextFlow)getParent();
293 return parent.getTextLayout();
294 }
295 if (layout == null) {
296 TextLayoutFactory factory = Toolkit.getToolkit().getTextLayoutFactory();
297 layout = factory.createLayout();
298 String string = getTextInternal();
299 Object font = getFontInternal();
300 TextAlignment alignment = getTextAlignment();
301 if (alignment == null) alignment = DEFAULT_TEXT_ALIGNMENT;
302 layout.setContent(string, font);
303 layout.setAlignment(alignment.ordinal());
304 layout.setLineSpacing((float)getLineSpacing());
305 layout.setWrapWidth((float)getWrappingWidth());
306 if (getEffectiveNodeOrientation() == NodeOrientation.RIGHT_TO_LEFT) {
307 layout.setDirection(TextLayout.DIRECTION_RTL);
308 } else {
309 layout.setDirection(TextLayout.DIRECTION_LTR);
310 }
311 layout.setTabSize(getTabSize());
312 }
313 return layout;
314 }
315
316 private GlyphList[] textRuns = null;
317 private BaseBounds spanBounds = new RectBounds(); /* relative to the textlayout */
318 private boolean spanBoundsInvalid = true;
319
320 void layoutSpan(GlyphList[] runs) {
321 TextSpan span = getTextSpan();
322 int count = 0;
323 for (int i = 0; i < runs.length; i++) {
324 GlyphList run = runs[i];
325 if (run.getTextSpan() == span) {
326 count++;
327 }
328 }
329 textRuns = new GlyphList[count];
330 count = 0;
331 for (int i = 0; i < runs.length; i++) {
1252 /*
1253 * Note: This method MUST only be called via its accessor method.
1254 */
1255 private com.sun.javafx.geom.Shape doConfigShape() {
1256 if (ShapeHelper.getMode(this) == NGShape.Mode.EMPTY || getTextInternal().length() == 0) {
1257 return new Path2D();
1258 }
1259 com.sun.javafx.geom.Shape shape = getShape();
1260 float x, y;
1261 if (isSpan()) {
1262 BaseBounds bounds = getSpanBounds();
1263 x = -bounds.getMinX();
1264 y = -bounds.getMinY();
1265 } else {
1266 x = (float)getX();
1267 y = getYAdjustment(getVisualBounds()) + (float)getY();
1268 }
1269 return TransformedShape.translatedShape(shape, x, y);
1270 }
1271
1272 /**
1273 * The size of a tab stop in spaces.
1274 *
1275 * @return the {@code tabSize} property
1276 *
1277 * @defaultValue {@code 8}
1278 *
1279 * @since 14
1280 */
1281 public final IntegerProperty tabSizeProperty() {
1282 return getTextAttribute().tabSizeProperty();
1283 }
1284
1285 /**
1286 * Gets the size of a tab stop in spaces.
1287 * @return the size of a tab in spaces
1288 * @since 14
1289 */
1290 public final int getTabSize() {
1291 if (attributes == null || attributes.tabSize == null) {
1292 return TextLayout.DEFAULT_TAB_SIZE;
1293 }
1294 return getTextAttribute().getTabSize();
1295 }
1296
1297 /**
1298 * Sets the size of a tab stop.
1299 * @param spaces the size of a tab in spaces. Defaults to 8.
1300 * Minimum is 1, lower values will be clamped to 1.
1301 * @since 14
1302 */
1303 public final void setTabSize(int spaces) {
1304 tabSizeProperty().set(spaces);
1305 }
1306
1307
1308 /***************************************************************************
1309 * *
1310 * Stylesheet Handling *
1311 * *
1312 **************************************************************************/
1313
1314 /*
1315 * Super-lazy instantiation pattern from Bill Pugh.
1316 */
1317 private static class StyleableProperties {
1318
1319 private static final CssMetaData<Text,Font> FONT =
1320 new FontCssMetaData<Text>("-fx-font", Font.getDefault()) {
1321
1322 @Override
1323 public boolean isSettable(Text node) {
1324 return node.font == null || !node.font.isBound();
1325 }
1326
1327 @Override
1328 public StyleableProperty<Font> getStyleableProperty(Text node) {
1329 return (StyleableProperty<Font>)node.fontProperty();
1330 }
1331 };
1332
1333 private static final CssMetaData<Text,Boolean> UNDERLINE =
1334 new CssMetaData<Text,Boolean>("-fx-underline",
1335 BooleanConverter.getInstance(), Boolean.FALSE) {
1336
1337 @Override
1338 public boolean isSettable(Text node) {
1339 return node.attributes == null ||
1340 node.attributes.underline == null ||
1341 !node.attributes.underline.isBound();
1342 }
1343
1344 @Override
1345 public StyleableProperty<Boolean> getStyleableProperty(Text node) {
1346 return (StyleableProperty<Boolean>)node.underlineProperty();
1347 }
1348 };
1349
1350 private static final CssMetaData<Text,Boolean> STRIKETHROUGH =
1351 new CssMetaData<Text,Boolean>("-fx-strikethrough",
1352 BooleanConverter.getInstance(), Boolean.FALSE) {
1353
1354 @Override
1355 public boolean isSettable(Text node) {
1356 return node.attributes == null ||
1357 node.attributes.strikethrough == null ||
1358 !node.attributes.strikethrough.isBound();
1359 }
1360
1361 @Override
1362 public StyleableProperty<Boolean> getStyleableProperty(Text node) {
1363 return (StyleableProperty<Boolean>)node.strikethroughProperty();
1364 }
1365 };
1366
1367 private static final
1368 CssMetaData<Text,TextAlignment> TEXT_ALIGNMENT =
1369 new CssMetaData<Text,TextAlignment>("-fx-text-alignment",
1370 new EnumConverter<TextAlignment>(TextAlignment.class),
1371 TextAlignment.LEFT) {
1372
1373 @Override
1374 public boolean isSettable(Text node) {
1375 return node.attributes == null ||
1376 node.attributes.textAlignment == null ||
1377 !node.attributes.textAlignment.isBound();
1378 }
1379
1380 @Override
1381 public StyleableProperty<TextAlignment> getStyleableProperty(Text node) {
1382 return (StyleableProperty<TextAlignment>)node.textAlignmentProperty();
1383 }
1384 };
1385
1386 private static final CssMetaData<Text,VPos> TEXT_ORIGIN =
1387 new CssMetaData<Text,VPos>("-fx-text-origin",
1388 new EnumConverter<VPos>(VPos.class),
1389 VPos.BASELINE) {
1390
1391 @Override
1392 public boolean isSettable(Text node) {
1393 return node.attributes == null ||
1394 node.attributes.textOrigin == null ||
1395 !node.attributes.textOrigin.isBound();
1396 }
1397
1398 @Override
1399 public StyleableProperty<VPos> getStyleableProperty(Text node) {
1400 return (StyleableProperty<VPos>)node.textOriginProperty();
1401 }
1402 };
1403
1404 private static final CssMetaData<Text,FontSmoothingType>
1405 FONT_SMOOTHING_TYPE =
1406 new CssMetaData<Text,FontSmoothingType>(
1407 "-fx-font-smoothing-type",
1408 new EnumConverter<FontSmoothingType>(FontSmoothingType.class),
1409 FontSmoothingType.GRAY) {
1410
1411 @Override
1412 public boolean isSettable(Text node) {
1413 return node.fontSmoothingType == null ||
1414 !node.fontSmoothingType.isBound();
1415 }
1416
1417 @Override
1418 public StyleableProperty<FontSmoothingType>
1419 getStyleableProperty(Text node) {
1420
1421 return (StyleableProperty<FontSmoothingType>)node.fontSmoothingTypeProperty();
1422 }
1423 };
1424
1425 private static final
1426 CssMetaData<Text,Number> LINE_SPACING =
1427 new CssMetaData<Text,Number>("-fx-line-spacing",
1428 SizeConverter.getInstance(), 0) {
1429
1430 @Override
1431 public boolean isSettable(Text node) {
1432 return node.attributes == null ||
1433 node.attributes.lineSpacing == null ||
1434 !node.attributes.lineSpacing.isBound();
1435 }
1436
1437 @Override
1438 public StyleableProperty<Number> getStyleableProperty(Text node) {
1439 return (StyleableProperty<Number>)node.lineSpacingProperty();
1440 }
1441 };
1442
1443 private static final CssMetaData<Text, TextBoundsType>
1444 BOUNDS_TYPE =
1445 new CssMetaData<Text,TextBoundsType>(
1446 "-fx-bounds-type",
1447 new EnumConverter<TextBoundsType>(TextBoundsType.class),
1448 DEFAULT_BOUNDS_TYPE) {
1449
1450 @Override
1451 public boolean isSettable(Text node) {
1452 return node.boundsType == null || !node.boundsType.isBound();
1453 }
1454
1455 @Override
1456 public StyleableProperty<TextBoundsType> getStyleableProperty(Text node) {
1457 return (StyleableProperty<TextBoundsType>)node.boundsTypeProperty();
1458 }
1459 };
1460
1461 private static final CssMetaData<Text,Number> TAB_SIZE =
1462 new CssMetaData<Text,Number>("-fx-tab-size",
1463 SizeConverter.getInstance(), TextLayout.DEFAULT_TAB_SIZE) {
1464
1465 @Override
1466 public boolean isSettable(Text node) {
1467 return node.attributes == null ||
1468 node.attributes.tabSize == null ||
1469 !node.attributes.tabSize.isBound();
1470 }
1471
1472 @Override
1473 public StyleableProperty<Number> getStyleableProperty(Text node) {
1474 return (StyleableProperty<Number>)node.tabSizeProperty();
1475 }
1476 };
1477
1478 private final static List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
1479 static {
1480 final List<CssMetaData<? extends Styleable, ?>> styleables =
1481 new ArrayList<CssMetaData<? extends Styleable, ?>>(Shape.getClassCssMetaData());
1482 styleables.add(FONT);
1483 styleables.add(UNDERLINE);
1484 styleables.add(STRIKETHROUGH);
1485 styleables.add(TEXT_ALIGNMENT);
1486 styleables.add(TEXT_ORIGIN);
1487 styleables.add(FONT_SMOOTHING_TYPE);
1488 styleables.add(LINE_SPACING);
1489 styleables.add(BOUNDS_TYPE);
1490 styleables.add(TAB_SIZE);
1491 STYLEABLES = Collections.unmodifiableList(styleables);
1492 }
1493 }
1494
1495 /**
1496 * @return The CssMetaData associated with this class, which may include the
1497 * CssMetaData of its superclasses.
1498 * @since JavaFX 8.0
1499 */
1500 public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
1501 return StyleableProperties.STYLEABLES;
1502 }
1503
1504 /**
1505 * {@inheritDoc}
1506 *
1507 * @since JavaFX 8.0
1508 */
1509
1510
1511 @Override
1512 public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
1860 notifyAccessibleAttributeChanged(AccessibleAttribute.SELECTION_END);
1861 }
1862 };
1863 }
1864 return caretPosition;
1865 }
1866
1867 private BooleanProperty caretBias;
1868
1869 final boolean isCaretBias() {
1870 return caretBias == null ? DEFAULT_CARET_BIAS : caretBias.get();
1871 }
1872
1873 final BooleanProperty caretBiasProperty() {
1874 if (caretBias == null) {
1875 caretBias =
1876 new SimpleBooleanProperty(Text.this, "caretBias", DEFAULT_CARET_BIAS);
1877 }
1878 return caretBias;
1879 }
1880
1881 private IntegerProperty tabSize;
1882
1883 final int getTabSize() {
1884 return tabSize == null ? TextLayout.DEFAULT_TAB_SIZE : tabSize.get();
1885 }
1886
1887 final IntegerProperty tabSizeProperty() {
1888 if (tabSize == null) {
1889 tabSize = new StyleableIntegerProperty(TextLayout.DEFAULT_TAB_SIZE) {
1890 @Override public Object getBean() { return Text.this; }
1891 @Override public String getName() { return "tabSize"; }
1892 @Override public CssMetaData getCssMetaData() {
1893 return StyleableProperties.TAB_SIZE;
1894 }
1895 @Override public void set(int v) { super.set((v < 1) ? 1 : v); }
1896 @Override protected void invalidated() {
1897 TextLayout layout = getTextLayout();
1898 if (layout.setTabSize(get())) {
1899 needsTextLayout();
1900 }
1901 NodeHelper.markDirty(Text.this, DirtyBits.TEXT_ATTRS);
1902 if (getBoundsType() == TextBoundsType.VISUAL) {
1903 NodeHelper.geomChanged(Text.this);
1904 }
1905 }
1906 };
1907 }
1908 return tabSize;
1909 }
1910 }
1911
1912 /**
1913 * Returns a string representation of this {@code Text} object.
1914 * @return a string representation of this {@code Text} object.
1915 */
1916 @Override
1917 public String toString() {
1918 final StringBuilder sb = new StringBuilder("Text[");
1919
1920 String id = getId();
1921 if (id != null) {
1922 sb.append("id=").append(id).append(", ");
1923 }
1924
1925 sb.append("text=\"").append(getText()).append("\"");
1926 sb.append(", x=").append(getX());
1927 sb.append(", y=").append(getY());
1928 sb.append(", alignment=").append(getTextAlignment());
1929 sb.append(", origin=").append(getTextOrigin());
|