Skip to content

Commit 29f6c5f

Browse files
committed
FlatAnimatorTest: added test for precise scrolling with trackpad
1 parent 419a689 commit 29f6c5f

4 files changed

Lines changed: 77 additions & 46 deletions

File tree

flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatAnimatorTest.java

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ public static void main( String[] args ) {
4646
FlatAnimatorTest() {
4747
initComponents();
4848

49+
updateChartDelayedChanged();
50+
4951
lineChartPanel.setSecondWidth( 500 );
5052
mouseWheelTestPanel.lineChartPanel = lineChartPanel;
5153
}
@@ -90,16 +92,16 @@ private void clearChart() {
9092

9193
private void initComponents() {
9294
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
93-
JLabel label1 = new JLabel();
95+
JLabel linearLabel = new JLabel();
9496
linearScrollBar = new JScrollBar();
95-
JLabel label2 = new JLabel();
97+
JLabel easeInOutLabel = new JLabel();
9698
easeInOutScrollBar = new JScrollBar();
9799
startButton = new JButton();
98-
JLabel label3 = new JLabel();
100+
JLabel mouseWheelTestLabel = new JLabel();
99101
mouseWheelTestPanel = new FlatAnimatorTest.MouseWheelTestPanel();
100-
JScrollPane scrollPane1 = new JScrollPane();
102+
JScrollPane lineChartScrollPane = new JScrollPane();
101103
lineChartPanel = new FlatSmoothScrollingTest.LineChartPanel();
102-
JLabel label4 = new JLabel();
104+
JLabel lineChartInfoLabel = new JLabel();
103105
updateChartDelayedCheckBox = new JCheckBox();
104106
JButton clearChartButton = new JButton();
105107

@@ -112,24 +114,23 @@ private void initComponents() {
112114
// rows
113115
"[]" +
114116
"[]" +
115-
"[]" +
116-
"[]" +
117+
"[]para" +
117118
"[top]" +
118119
"[400,grow,fill]" +
119120
"[]"));
120121

121-
//---- label1 ----
122-
label1.setText("Linear:");
123-
add(label1, "cell 0 0");
122+
//---- linearLabel ----
123+
linearLabel.setText("Linear:");
124+
add(linearLabel, "cell 0 0");
124125

125126
//---- linearScrollBar ----
126127
linearScrollBar.setOrientation(Adjustable.HORIZONTAL);
127128
linearScrollBar.setBlockIncrement(1);
128129
add(linearScrollBar, "cell 1 0");
129130

130-
//---- label2 ----
131-
label2.setText("Ease in out:");
132-
add(label2, "cell 0 1");
131+
//---- easeInOutLabel ----
132+
easeInOutLabel.setText("Ease in out:");
133+
add(easeInOutLabel, "cell 0 1");
133134

134135
//---- easeInOutScrollBar ----
135136
easeInOutScrollBar.setOrientation(Adjustable.HORIZONTAL);
@@ -141,36 +142,36 @@ private void initComponents() {
141142
startButton.addActionListener(e -> start());
142143
add(startButton, "cell 0 2");
143144

144-
//---- label3 ----
145-
label3.setText("Mouse wheel test:");
146-
add(label3, "cell 0 4");
145+
//---- mouseWheelTestLabel ----
146+
mouseWheelTestLabel.setText("Mouse wheel test:");
147+
add(mouseWheelTestLabel, "cell 0 3");
147148

148149
//---- mouseWheelTestPanel ----
149150
mouseWheelTestPanel.setBorder(new LineBorder(Color.red));
150-
add(mouseWheelTestPanel, "cell 1 4,height 100");
151+
add(mouseWheelTestPanel, "cell 1 3,height 100");
151152

152-
//======== scrollPane1 ========
153+
//======== lineChartScrollPane ========
153154
{
154-
scrollPane1.setViewportView(lineChartPanel);
155+
lineChartScrollPane.putClientProperty("JScrollPane.smoothScrolling", false);
156+
lineChartScrollPane.setViewportView(lineChartPanel);
155157
}
156-
add(scrollPane1, "cell 0 5 2 1");
158+
add(lineChartScrollPane, "cell 0 4 2 1");
157159

158-
//---- label4 ----
159-
label4.setText("X: time (500ms per line) / Y: value (10% per line)");
160-
add(label4, "cell 0 6 2 1");
160+
//---- lineChartInfoLabel ----
161+
lineChartInfoLabel.setText("X: time (500ms per line) / Y: value (10% per line)");
162+
add(lineChartInfoLabel, "cell 0 5 2 1");
161163

162164
//---- updateChartDelayedCheckBox ----
163165
updateChartDelayedCheckBox.setText("Update chart delayed");
164166
updateChartDelayedCheckBox.setMnemonic('U');
165-
updateChartDelayedCheckBox.setSelected(true);
166167
updateChartDelayedCheckBox.addActionListener(e -> updateChartDelayedChanged());
167-
add(updateChartDelayedCheckBox, "cell 0 6 2 1,alignx right,growx 0");
168+
add(updateChartDelayedCheckBox, "cell 0 5 2 1,alignx right,growx 0");
168169

169170
//---- clearChartButton ----
170171
clearChartButton.setText("Clear Chart");
171172
clearChartButton.setMnemonic('C');
172173
clearChartButton.addActionListener(e -> clearChart());
173-
add(clearChartButton, "cell 0 6 2 1,alignx right,growx 0");
174+
add(clearChartButton, "cell 0 5 2 1,alignx right,growx 0");
174175
// JFormDesigner - End of component initialization //GEN-END:initComponents
175176
}
176177

@@ -228,14 +229,36 @@ static class MouseWheelTestPanel
228229

229230
@Override
230231
public void mouseWheelMoved( MouseWheelEvent e ) {
231-
lineChartPanel.addValue( 0.5 + (e.getWheelRotation() / 10.), true, Color.red );
232+
double preciseWheelRotation = e.getPreciseWheelRotation();
232233

233-
// start next animation at the current value
234-
startValue = value;
234+
// add a dot in the middle of the chart for the wheel rotation
235+
// for unprecise wheels the rotation value is usually -1 or +1
236+
// for precise wheels the rotation value is in range ca. -10 to +10,
237+
// depending how fast the wheel is rotated
238+
lineChartPanel.addValue( 0.5 + (preciseWheelRotation / 20.), true, Color.red );
235239

236240
// increase/decrease target value if animation is in progress
237-
targetValue = (targetValue < 0 ? value : targetValue) + (STEP * e.getWheelRotation());
238-
targetValue = Math.min( Math.max( targetValue, 0 ), MAX_VALUE );
241+
int newValue = (int) ((targetValue < 0 ? value : targetValue) + (STEP * preciseWheelRotation));
242+
newValue = Math.min( Math.max( newValue, 0 ), MAX_VALUE );
243+
244+
if( preciseWheelRotation != 0 &&
245+
preciseWheelRotation != e.getWheelRotation() )
246+
{
247+
// do not use animation for precise scrolling (e.g. with trackpad)
248+
249+
// stop running animation (if any)
250+
animator.stop();
251+
252+
value = newValue;
253+
valueLabel.setText( String.valueOf( value ) );
254+
255+
lineChartPanel.addValue( value / (double) MAX_VALUE, Color.red );
256+
return;
257+
}
258+
259+
// start next animation at the current value
260+
startValue = value;
261+
targetValue = newValue;
239262

240263
// restart animator
241264
animator.cancel();

flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatAnimatorTest.jfd

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ new FormModel {
99
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
1010
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
1111
"$columnConstraints": "[fill][grow,fill]"
12-
"$rowConstraints": "[][][][][top][400,grow,fill][]"
12+
"$rowConstraints": "[][][]para[top][400,grow,fill][]"
1313
} ) {
1414
name: "this"
1515
add( new FormComponent( "javax.swing.JLabel" ) {
16-
name: "label1"
16+
name: "linearLabel"
1717
"text": "Linear:"
1818
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
1919
"value": "cell 0 0"
@@ -29,7 +29,7 @@ new FormModel {
2929
"value": "cell 1 0"
3030
} )
3131
add( new FormComponent( "javax.swing.JLabel" ) {
32-
name: "label2"
32+
name: "easeInOutLabel"
3333
"text": "Ease in out:"
3434
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
3535
"value": "cell 0 1"
@@ -55,10 +55,10 @@ new FormModel {
5555
"value": "cell 0 2"
5656
} )
5757
add( new FormComponent( "javax.swing.JLabel" ) {
58-
name: "label3"
58+
name: "mouseWheelTestLabel"
5959
"text": "Mouse wheel test:"
6060
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
61-
"value": "cell 0 4"
61+
"value": "cell 0 3"
6262
} )
6363
add( new FormComponent( "com.formdev.flatlaf.testing.FlatAnimatorTest$MouseWheelTestPanel" ) {
6464
name: "mouseWheelTestPanel"
@@ -67,44 +67,44 @@ new FormModel {
6767
"JavaCodeGenerator.variableLocal": false
6868
}
6969
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
70-
"value": "cell 1 4,height 100"
70+
"value": "cell 1 3,height 100"
7171
} )
7272
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
73-
name: "scrollPane1"
73+
name: "lineChartScrollPane"
74+
"$client.JScrollPane.smoothScrolling": false
7475
add( new FormComponent( "com.formdev.flatlaf.testing.FlatSmoothScrollingTest$LineChartPanel" ) {
7576
name: "lineChartPanel"
7677
auxiliary() {
7778
"JavaCodeGenerator.variableLocal": false
7879
}
7980
} )
8081
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
81-
"value": "cell 0 5 2 1"
82+
"value": "cell 0 4 2 1"
8283
} )
8384
add( new FormComponent( "javax.swing.JLabel" ) {
84-
name: "label4"
85+
name: "lineChartInfoLabel"
8586
"text": "X: time (500ms per line) / Y: value (10% per line)"
8687
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
87-
"value": "cell 0 6 2 1"
88+
"value": "cell 0 5 2 1"
8889
} )
8990
add( new FormComponent( "javax.swing.JCheckBox" ) {
9091
name: "updateChartDelayedCheckBox"
9192
"text": "Update chart delayed"
9293
"mnemonic": 85
93-
"selected": true
9494
auxiliary() {
9595
"JavaCodeGenerator.variableLocal": false
9696
}
9797
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "updateChartDelayedChanged", false ) )
9898
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
99-
"value": "cell 0 6 2 1,alignx right,growx 0"
99+
"value": "cell 0 5 2 1,alignx right,growx 0"
100100
} )
101101
add( new FormComponent( "javax.swing.JButton" ) {
102102
name: "clearChartButton"
103103
"text": "Clear Chart"
104104
"mnemonic": 67
105105
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "clearChart", false ) )
106106
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
107-
"value": "cell 0 6 2 1,alignx right,growx 0"
107+
"value": "cell 0 5 2 1,alignx right,growx 0"
108108
} )
109109
}, new FormLayoutConstraints( null ) {
110110
"location": new java.awt.Point( 0, 0 )

flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatSmoothScrollingTest.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ private void initComponents() {
347347

348348
//======== scrollPane1 ========
349349
{
350+
scrollPane1.putClientProperty("JScrollPane.smoothScrolling", false);
350351
scrollPane1.setViewportView(lineChartPanel);
351352
}
352353
add(scrollPane1, "cell 0 5 4 1,width 100");
@@ -465,7 +466,7 @@ static class LineChartPanel
465466
implements Scrollable
466467
{
467468
private static final int NEW_SEQUENCE_TIME_LAG = 500;
468-
private static final int NEW_SEQUENCE_GAP = 20;
469+
private static final int NEW_SEQUENCE_GAP = 50;
469470

470471
private int secondWidth = 1000;
471472

@@ -538,9 +539,15 @@ private void repaintAndRevalidate() {
538539

539540
// scroll horizontally
540541
if( lastUsedChartColor != null ) {
542+
// compute chart width of last used color and start of last sequence
541543
int[] lastSeqX = new int[1];
542544
int cw = chartWidth( color2dataMap.get( lastUsedChartColor ), lastSeqX );
543-
scrollRectToVisible( new Rectangle( lastSeqX[0], 0, cw - lastSeqX[0], getHeight() ) );
545+
546+
// scroll to end of last sequence (of last used color)
547+
int lastSeqWidth = cw - lastSeqX[0];
548+
int width = Math.min( lastSeqWidth, getParent().getWidth() );
549+
int x = cw - width;
550+
scrollRectToVisible( new Rectangle( x, 0, width, getHeight() ) );
544551
}
545552
}
546553

flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatSmoothScrollingTest.jfd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ new FormModel {
148148
} )
149149
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
150150
name: "scrollPane1"
151+
"$client.JScrollPane.smoothScrolling": false
151152
add( new FormComponent( "com.formdev.flatlaf.testing.FlatSmoothScrollingTest$LineChartPanel" ) {
152153
name: "lineChartPanel"
153154
} )

0 commit comments

Comments
 (0)