Skip to content

Commit 7b06190

Browse files
hjohnaghaisas
authored andcommitted
8242548: Wrapped labeled controls using -fx-line-spacing cut text off
Reviewed-by: aghaisas, kcr
1 parent 435671e commit 7b06190

File tree

4 files changed

+53
-5
lines changed

4 files changed

+53
-5
lines changed

modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/skin/Utils.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,17 +417,27 @@ public static String computeClippedText(Font font, String text, double width,
417417
}
418418

419419
public static String computeClippedWrappedText(Font font, String text, double width,
420-
double height, OverrunStyle truncationStyle,
420+
double height, double lineSpacing, OverrunStyle truncationStyle,
421421
String ellipsisString, TextBoundsType boundsType) {
422422
if (font == null) {
423423
throw new IllegalArgumentException("Must specify a font");
424424
}
425425

426+
// The height given does not need to include the line spacing after
427+
// the last line to be able to render that last line correctly.
428+
//
429+
// However the calculations include the line spacing as part of a
430+
// line's height. In order to not cut off the last line because its
431+
// line spacing wouldn't fit, the height used for the calculation
432+
// is increased here with the line spacing amount.
433+
434+
height += lineSpacing;
435+
426436
String ellipsis = (truncationStyle == CLIP) ? "" : ellipsisString;
427437
int eLen = ellipsis.length();
428438
// Do this before using helper, as it's not reentrant.
429439
double eWidth = computeTextWidth(font, ellipsis, 0);
430-
double eHeight = computeTextHeight(font, ellipsis, 0, boundsType);
440+
double eHeight = computeTextHeight(font, ellipsis, 0, lineSpacing, boundsType);
431441

432442
if (width < eWidth || height < eHeight) {
433443
// The ellipsis doesn't fit.
@@ -438,7 +448,7 @@ public static String computeClippedWrappedText(Font font, String text, double wi
438448
helper.setFont(font);
439449
helper.setWrappingWidth((int)Math.ceil(width));
440450
helper.setBoundsType(boundsType);
441-
helper.setLineSpacing(0);
451+
helper.setLineSpacing(lineSpacing);
442452

443453
boolean leading = (truncationStyle == LEADING_ELLIPSIS ||
444454
truncationStyle == LEADING_WORD_ELLIPSIS);

modules/javafx.controls/src/main/java/javafx/scene/control/skin/LabeledSkinBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1107,7 +1107,7 @@ private void updateDisplayedText(double w, double h) {
11071107
String ellipsisString = labeled.getEllipsisString();
11081108

11091109
if (labeled.isWrapText()) {
1110-
result = Utils.computeClippedWrappedText(font, s, wrapWidth, wrapHeight, truncationStyle, ellipsisString, text.getBoundsType());
1110+
result = Utils.computeClippedWrappedText(font, s, wrapWidth, wrapHeight, labeled.getLineSpacing(), truncationStyle, ellipsisString, text.getBoundsType());
11111111
} else if (multiline) {
11121112
StringBuilder sb = new StringBuilder();
11131113

modules/javafx.controls/src/test/java/test/javafx/scene/control/skin/LabelSkinTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ public class LabelSkinTest {
136136
assertTrue(skin.propertyChanged);
137137
}
138138

139+
@Test public void lineSpacingChangesOnLabelShouldInvoke_handleControlPropertyChanged() {
140+
skin.addWatchedProperty(label.lineSpacingProperty());
141+
label.setLineSpacing(1.0);
142+
assertTrue(skin.propertyChanged);
143+
}
144+
139145
@Test public void textChangesOnLabelShouldInvoke_handleControlPropertyChanged() {
140146
skin.addWatchedProperty(label.textProperty());
141147
label.setText("Bust my buffers!");
@@ -279,6 +285,15 @@ public class LabelSkinTest {
279285
assertFalse(skin.get_invalidText());
280286
}
281287

288+
@Test public void lineSpacingChangesOnLabelShouldInvalidateLayoutAndDisplayText() {
289+
label.layout();
290+
skin.updateDisplayedText();
291+
292+
label.setLineSpacing(1.0);
293+
assertTrue(label.isNeedsLayout());
294+
assertTrue(skin.get_invalidText());
295+
}
296+
282297
@Test public void textChangesOnLabelShouldInvalidateLayoutAndDisplayTextAndTextWidth() {
283298
label.layout();
284299
skin.updateDisplayedText();
@@ -1145,6 +1160,26 @@ public class LabelSkinTest {
11451160
assertTrue(height >= singleLineHeight * 5);
11461161
}
11471162

1163+
@Test public void whenTextHasNewlinesAndPositiveLineSpacing_computePrefHeight_IncludesTheMultipleLinesAndLineSpacingInThePrefHeight() {
1164+
label.setLineSpacing(2);
1165+
label.setText("This\nis a test\nof the emergency\nbroadcast system.\nThis is only a test");
1166+
label.setPadding(new Insets(0, 0, 0, 0));
1167+
final double singleLineHeight = Utils.computeTextHeight(label.getFont(), " ", 0, text.getBoundsType());
1168+
final double expectedHeight = singleLineHeight * 5 + label.getLineSpacing() * 5 - label.getLineSpacing();
1169+
final double height = label.prefHeight(-1);
1170+
assertEquals(expectedHeight, height, 0);
1171+
}
1172+
1173+
@Test public void whenTextHasNewlinesAndNegativeLineSpacing_computePrefHeight_IncludesTheMultipleLinesAndLineSpacingInThePrefHeight() {
1174+
label.setLineSpacing(-2);
1175+
label.setText("This\nis a test\nof the emergency\nbroadcast system.\nThis is only a test");
1176+
label.setPadding(new Insets(0, 0, 0, 0));
1177+
final double singleLineHeight = Utils.computeTextHeight(label.getFont(), " ", 0, text.getBoundsType());
1178+
final double expectedHeight = singleLineHeight * 5 + label.getLineSpacing() * 5 - label.getLineSpacing();
1179+
final double height = label.prefHeight(-1);
1180+
assertEquals(expectedHeight, height, 0);
1181+
}
1182+
11481183
@Test public void whenTextHasNewlinesAfterPreviousComputationOf_computePrefHeight_IncludesTheMultipleLinesInThePrefHeight() {
11491184
label.setText("This is a test");
11501185
final double oldPrefHeight = label.prefHeight(-1);

modules/javafx.graphics/src/test/java/test/com/sun/javafx/pgstub/StubTextLayout.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public boolean setContent(TextSpan[] spans) {
4848
private Font font;
4949
private int tabSize = DEFAULT_TAB_SIZE;
5050
private int nullFontSize = 0;
51+
private float spacing;
5152

5253
@Override
5354
public boolean setContent(String text, Object font) {
@@ -69,6 +70,8 @@ public boolean setWrapWidth(float wrapWidth) {
6970

7071
@Override
7172
public boolean setLineSpacing(float spacing) {
73+
this.spacing = spacing;
74+
7275
return true;
7376
}
7477

@@ -92,7 +95,7 @@ public BaseBounds getBounds(TextSpan filter, BaseBounds bounds) {
9295
final double fontSize = (font == null ? nullFontSize : ((Font)font).getSize());
9396
final String[] lines = getText().split("\n");
9497
double width = 0.0;
95-
double height = fontSize * lines.length;
98+
double height = fontSize * lines.length + spacing * (lines.length - 1);
9699
for (String line : lines) {
97100
final int length;
98101
if (line.contains("\t")) {

0 commit comments

Comments
 (0)