Skip to content

Commit 0968269

Browse files
Merge pull request #418 from JordanMartinez/addShowMethods
Add show methods
2 parents dbe68a3 + c223a2d commit 0968269

2 files changed

Lines changed: 132 additions & 0 deletions

File tree

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package org.fxmisc.richtext.demo;
2+
3+
import javafx.application.Application;
4+
import javafx.event.ActionEvent;
5+
import javafx.geometry.Pos;
6+
import javafx.scene.Scene;
7+
import javafx.scene.control.Button;
8+
import javafx.scene.control.TextField;
9+
import javafx.scene.layout.BorderPane;
10+
import javafx.scene.layout.VBox;
11+
import javafx.stage.Stage;
12+
import org.fxmisc.flowless.VirtualizedScrollPane;
13+
import org.fxmisc.richtext.InlineCssTextArea;
14+
15+
import java.util.function.Consumer;
16+
import java.util.function.Function;
17+
18+
public class ShowLineDemo extends Application {
19+
20+
public static final int MIN_LINE_INDEX = 0;
21+
22+
private class NumbersOnlyField extends TextField {
23+
24+
NumbersOnlyField() {
25+
super();
26+
setOnKeyTyped(ke -> {
27+
String keyEventText = ke.getCharacter();
28+
if (Character.isDigit(keyEventText.charAt(0))) {
29+
if (getSelectedText().isEmpty()) {
30+
appendText(keyEventText);
31+
} else {
32+
replaceText(getSelection(), keyEventText);
33+
}
34+
}
35+
ke.consume();
36+
});
37+
}
38+
39+
public int getTextAsInt() {
40+
String text = getText();
41+
if (text.isEmpty()) {
42+
setText(String.valueOf(MIN_LINE_INDEX));
43+
return MIN_LINE_INDEX;
44+
} else {
45+
return Integer.parseInt(text);
46+
}
47+
}
48+
49+
}
50+
51+
private final NumbersOnlyField field = new NumbersOnlyField();
52+
{
53+
field.setPromptText("Input a number to indicate which line you want to show");
54+
}
55+
56+
@Override
57+
public void start(Stage primaryStage) throws Exception {
58+
StringBuilder sb = new StringBuilder();
59+
int max = 100;
60+
for (int i = 0; i < max; i++) {
61+
sb.append("Line Index: ").append(i).append("\n");
62+
}
63+
sb.append("Line Index: ").append(max);
64+
InlineCssTextArea area = new InlineCssTextArea(sb.toString());
65+
VirtualizedScrollPane<InlineCssTextArea> vsPane = new VirtualizedScrollPane<>(area);
66+
67+
Function<Integer, Integer> clamp = i -> Math.max(0, Math.min(i, area.getLength() - 1));
68+
Button showInViewportButton = createButton("Show line somewhere in Viewport", ae -> {
69+
area.showParagraphInViewport(clamp.apply(field.getTextAsInt()));
70+
});
71+
Button showAtViewportTopButton = createButton("Show line at top of viewport", ae -> {
72+
area.showParagraphAtTop(clamp.apply(field.getTextAsInt()));
73+
});
74+
Button showAtViewportBottomButton = createButton("Show line at bottom of viewport", ae -> {
75+
area.showParagraphAtBottom(clamp.apply(field.getTextAsInt()));
76+
});
77+
78+
VBox vbox = new VBox(field, showInViewportButton, showAtViewportTopButton, showAtViewportBottomButton);
79+
vbox.setAlignment(Pos.CENTER);
80+
81+
BorderPane root = new BorderPane();
82+
root.setCenter(vsPane);
83+
root.setBottom(vbox);
84+
85+
Scene scene = new Scene(root, 700, 500);
86+
primaryStage.setScene(scene);
87+
primaryStage.show();
88+
89+
}
90+
91+
private Button createButton(String text, Consumer<ActionEvent> handler) {
92+
Button b = new Button(text);
93+
b.setOnAction(ae -> {
94+
handler.accept(ae);
95+
field.requestFocus();
96+
});
97+
return b;
98+
}
99+
100+
}

richtextfx/src/main/java/org/fxmisc/richtext/GenericStyledArea.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,38 @@ void show(double y) {
973973
virtualFlow.show(y);
974974
}
975975

976+
/**
977+
* Shows the paragraph somewhere in the viewport. If the line is already visible, no noticeable change occurs.
978+
* If line is above the current view, it appears at the top of the viewport. If the line is below the current
979+
* view, it appears at the bottom of the viewport.
980+
*/
981+
public void showParagraphInViewport(int paragraphIndex) {
982+
virtualFlow.show(paragraphIndex);
983+
}
984+
985+
/**
986+
* Lays out the viewport so that the paragraph is the first line (top) displayed in the viewport. Note: if
987+
* the given area does not have enough lines that follow the given line to span its entire height, the paragraph
988+
* may not appear at the very top of the viewport. Instead, it may simply be shown in the viewport. For example,
989+
* given an unwrapped area whose height could show 10 lines but whose content only has 3 lines, calling
990+
* {@code showParagraphAtTop(3)} would be no different than {@code showParagraphAtTop(1)}.
991+
*/
992+
public void showParagraphAtTop(int paragraphIndex) {
993+
virtualFlow.showAsFirst(paragraphIndex);
994+
}
995+
996+
/**
997+
* Lays out the viewport so that the paragraph is the last line (bottom) displayed in the viewport. Note: if
998+
* the given area does not have enough lines preceding the given line to span its entire height, the paragraph
999+
* may not appear at the very bottom of the viewport. Instead, it may appear towards the bottom of the viewport
1000+
* with some extra space following it. For example, given an unwrapped area whose height could show 10 lines but
1001+
* whose content only has 7 lines, calling {@code showParagraphAtBottom(1)} would be no different than calling
1002+
* {@code showParagraphAtBottom(7)}.
1003+
*/
1004+
public void showParagraphAtBottom(int paragraphIndex) {
1005+
virtualFlow.showAsLast(paragraphIndex);
1006+
}
1007+
9761008
void showCaretAtBottom() {
9771009
int parIdx = getCurrentParagraph();
9781010
Cell<Paragraph<PS, SEG, S>, ParagraphBox<PS, SEG, S>> cell = virtualFlow.getCell(parIdx);

0 commit comments

Comments
 (0)