Skip to content

Commit e3b907e

Browse files
authored
Page up and down tweak (#983)
Page up to first line when visible, and Page down to last when visible.
1 parent 358df2d commit e3b907e

2 files changed

Lines changed: 83 additions & 50 deletions

File tree

Lines changed: 73 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
package org.fxmisc.richtext.keyboard;
22

3-
import javafx.application.Platform;
43
import javafx.geometry.Bounds;
54
import javafx.stage.Stage;
65
import org.fxmisc.richtext.InlineCssTextAreaAppTest;
76
import org.fxmisc.richtext.TextBuildingUtils;
7+
import org.fxmisc.richtext.model.ReadOnlyStyledDocument;
88
import org.junit.Test;
99

1010
import static javafx.scene.input.KeyCode.PAGE_DOWN;
1111
import static javafx.scene.input.KeyCode.PAGE_UP;
1212
import static javafx.scene.input.KeyCode.SHIFT;
1313
import static org.junit.Assert.assertEquals;
1414
import static org.junit.Assert.assertTrue;
15+
import org.testfx.util.WaitForAsyncUtils;
1516

1617
public class PageUpDownTests extends InlineCssTextAreaAppTest {
1718

@@ -20,102 +21,126 @@ public class PageUpDownTests extends InlineCssTextAreaAppTest {
2021
@Override
2122
public void start(Stage stage) throws Exception {
2223
super.start(stage);
24+
clickOn( area );
2325

26+
// Note that these test are Font size sensitive !!!
2427
// allow 6 lines to be displayed
25-
stage.setHeight(90);
28+
stage.setHeight(96);
2629
area.replaceText(EIGHT_LINES);
2730
}
2831

2932
@Test
30-
public void page_up_leaves_caret_at_bottom_of_viewport() {
33+
public void page_up_leaves_caret_at_BOTTOM_of_viewport_when_FIRST_line_NOT_visible() {
3134
interact(() -> {
32-
area.moveTo(5, 0);
35+
insert( 5, 1, " page_up_leaves_caret_at_BOTTOM_of_viewport" );
36+
insert( 7, 1, " page_up_leaves_caret_at_BOTTOM_of_viewport" );
3337
area.requestFollowCaret();
3438
});
35-
assertTrue(area.getSelectedText().isEmpty());
39+
3640
Bounds beforeBounds = area.getCaretBounds().get();
3741

42+
//WaitForAsyncUtils.waitForFxEvents(250);
3843
type(PAGE_UP);
44+
//WaitForAsyncUtils.waitForFxEvents(250);
45+
46+
Bounds afterBounds = area.getCaretBounds().get();
47+
assertEquals(beforeBounds.getMinY(), afterBounds.getMinY(), 6.1);
48+
assertEquals(5, area.getCurrentParagraph());
49+
}
3950

40-
runLater( 150, () -> {
41-
Bounds afterBounds = area.getCaretBounds().get();
42-
assertEquals(8, area.getCaretPosition());
43-
assertTrue(area.getSelectedText().isEmpty());
44-
assertTrue(beforeBounds.getMinY() > afterBounds.getMinY());
51+
@Test
52+
public void page_up_leaves_caret_at_TOP_of_viewport_when_FIRST_line_IS_visible() {
53+
interact(() -> {
54+
insert( 0, 1, " page_up_leaves_caret_at_TOP_of_viewport" );
55+
area.moveTo(4, 0);
56+
area.requestFollowCaret();
4557
});
58+
59+
type(PAGE_UP);
60+
61+
assertEquals(0, area.getCurrentParagraph());
4662
}
4763

4864
@Test
49-
public void page_down_leaves_caret_at_top_of_viewport() throws Exception {
65+
public void page_down_leaves_caret_at_TOP_of_viewport_when_LAST_line_NOT_visible() throws Exception {
5066
interact(() -> {
67+
insert( 0, 1, " page_down_leaves_caret_at_TOP_of_viewport" );
68+
insert( 2, 1, " page_down_leaves_caret_at_TOP_of_viewport" );
5169
area.moveTo(0);
5270
area.requestFollowCaret();
5371
});
54-
assertTrue(area.getSelectedText().isEmpty());
72+
5573
Bounds beforeBounds = area.getCaretBounds().get();
5674

75+
//WaitForAsyncUtils.waitForFxEvents(250);
5776
type(PAGE_DOWN);
77+
//WaitForAsyncUtils.waitForFxEvents(250);
78+
79+
Bounds afterBounds = area.getCaretBounds().get();
80+
assertEquals(beforeBounds.getMinY(), afterBounds.getMinY(), 6.1);
81+
assertEquals(2, area.getCurrentParagraph());
82+
}
5883

59-
runLater( 150, () -> {
60-
Bounds afterBounds = area.getCaretBounds().get();
61-
assertEquals(area.getAbsolutePosition(3, 0), area.getCaretPosition());
62-
assertTrue(area.getSelectedText().isEmpty());
63-
assertTrue(beforeBounds.getMinY() < afterBounds.getMinY());
84+
@Test
85+
public void page_down_leaves_caret_at_BOTTOM_of_viewport_when_LAST_line_IS_visible() throws Exception {
86+
interact(() -> {
87+
insert( 7, 1, " page_down_leaves_caret_at_BOTTOM_of_viewport" );
88+
area.showParagraphAtTop(3);
89+
area.moveTo(3, 0);
6490
});
91+
92+
type(PAGE_DOWN);
93+
94+
assertEquals(7, area.getCurrentParagraph());
95+
assertEquals(area.getLength(), area.getCaretPosition());
6596
}
6697

6798
@Test
6899
public void shift_page_up_leaves_caret_at_bottom_of_viewport_and_makes_selection() {
69100
interact(() -> {
70-
area.moveTo(5, 0);
101+
insert( 5, 1, " SHIFT_page_up_SELECTS_leaving_caret_at_BOTTOM_of_viewport" );
102+
insert( 7, 1, " SHIFT_page_up_SELECTS_leaving_caret_at_BOTTOM_of_viewport" );
103+
area.moveTo(7, 0);
71104
area.requestFollowCaret();
72105
});
73-
assertTrue(area.getSelectedText().isEmpty());
106+
74107
Bounds beforeBounds = area.getCaretBounds().get();
75108

109+
//WaitForAsyncUtils.waitForFxEvents(250);
76110
press(SHIFT).type(PAGE_UP).release(SHIFT);
111+
//WaitForAsyncUtils.waitForFxEvents(250);
77112

78-
runLater( 150, () -> {
79-
Bounds afterBounds = area.getCaretBounds().get();
80-
assertEquals(8, area.getCaretPosition());
81-
assertEquals(area.getText(0, 0, 5, 0), area.getSelectedText());
82-
assertTrue(beforeBounds.getMinY() > afterBounds.getMinY());
83-
});
113+
Bounds afterBounds = area.getCaretBounds().get();
114+
assertEquals(beforeBounds.getMinY(), afterBounds.getMinY(), 6.1);
115+
assertEquals(area.getText(5, 0, 7, 0), area.getSelectedText());
116+
assertEquals(10, area.getCaretPosition());
84117
}
85118

86119
@Test
87120
public void shift_page_down_leaves_caret_at_top_of_viewport_and_makes_selection() {
88121
interact(() -> {
89-
area.moveTo(0);
122+
insert( 2, 1, " SHIFT_page_down_SELECTS_leaving_caret_at_TOP_of_viewport" );
123+
insert( 0, 1, " SHIFT_page_down_SELECTS_leaving_caret_at_TOP_of_viewport" );
90124
area.requestFollowCaret();
91125
});
126+
92127
assertTrue(area.getSelectedText().isEmpty());
93128
Bounds beforeBounds = area.getCaretBounds().get();
94129

130+
//WaitForAsyncUtils.waitForFxEvents(250);
95131
press(SHIFT).type(PAGE_DOWN).release(SHIFT);
96-
97-
runLater( 150, () -> {
98-
Bounds afterBounds = area.getCaretBounds().get();
99-
assertEquals(area.getAbsolutePosition(3, 0), area.getCaretPosition());
100-
assertEquals(area.getText(0, 0, 3, 0), area.getSelectedText());
101-
assertTrue(beforeBounds.getMinY() < afterBounds.getMinY());
102-
});
132+
//WaitForAsyncUtils.waitForFxEvents(250);
133+
134+
Bounds afterBounds = area.getCaretBounds().get();
135+
//assertEquals(beforeBounds.getMinY(), afterBounds.getMinY(), 6.1);
136+
assertEquals(area.getText(1, -1, 3, -1), area.getSelectedText());
137+
assertEquals(119, area.getCaretPosition());
103138
}
104139

105-
// Can't use sleep( t ) as that seems to delay the key press & release actions as well,
106-
// defeating the purpose of it. So here a new thread is created for the delay ...
107-
private void runLater( final long time, final Runnable runFX )
108-
{
109-
new Thread( () -> {
110-
long t0 = System.currentTimeMillis();
111-
long t1 = t0 + time;
112-
113-
while ( t0 < t1 ) try { Thread.sleep( t1 - t0 ); } catch ( Exception e ) {}
114-
finally { t0 = System.currentTimeMillis(); }
115-
116-
Platform.runLater( runFX );
117-
118-
} ).start();
119-
}
140+
141+
private void insert( int p, int col, String text ) {
142+
area.insert( p, col, ReadOnlyStyledDocument.fromString( text, "", "", area.getSegOps() ) );
143+
}
144+
120145
}
121146

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,12 +1255,20 @@ else if ( lineHighlighter != null ) {
12551255

12561256
@Override
12571257
public void prevPage(SelectionPolicy selectionPolicy) {
1258-
page( -1, selectionPolicy );
1258+
// Paging up and we're in the first frame then move/select to start.
1259+
if ( firstVisibleParToAllParIndex() == 0 ) {
1260+
caretSelectionBind.moveTo( 0, selectionPolicy );
1261+
}
1262+
else page( -1, selectionPolicy );
12591263
}
12601264

12611265
@Override
12621266
public void nextPage(SelectionPolicy selectionPolicy) {
1263-
page( +1, selectionPolicy );
1267+
// Paging down and we're in the last frame then move/select to end.
1268+
if ( lastVisibleParToAllParIndex() == getParagraphs().size()-1 ) {
1269+
caretSelectionBind.moveTo( getLength(), selectionPolicy );
1270+
}
1271+
else page( +1, selectionPolicy );
12641272
}
12651273

12661274
/**

0 commit comments

Comments
 (0)