ScrollBar: set valueIsAdjusting property to true while smooth scrolling animation is running (issue #50)

This commit is contained in:
Karl Tauber
2020-08-04 21:30:44 +02:00
parent 889b5ea56a
commit 736305849a
3 changed files with 199 additions and 1 deletions

View File

@@ -473,6 +473,8 @@ public class FlatScrollBarUI
if( animator != null )
animator.cancel();
scrollbar.setValueIsAdjusting( true );
// if invoked while animation is running, calculation of new value
// should start at the previous target value
if( targetValue != Integer.MIN_VALUE )
@@ -487,7 +489,8 @@ public class FlatScrollBarUI
scrollbar.setValue( oldValue );
setValueAnimated( newValue );
}
} else
scrollbar.setValueIsAdjusting( false );
inRunAndSetValueAnimated = false;
}
@@ -498,6 +501,8 @@ public class FlatScrollBarUI
private int delta;
public void setValueAnimated( int value ) {
scrollbar.setValueIsAdjusting( true );
// create animator
if( animator == null ) {
int duration = FlatUIUtils.getUIInt( "ScrollPane.smoothScrolling.duration", 200 );
@@ -510,9 +515,15 @@ public class FlatScrollBarUI
return;
}
// re-enable valueIsAdjusting if disabled while animation is running
// (e.g. in mouse released listener)
if( !scrollbar.getValueIsAdjusting() )
scrollbar.setValueIsAdjusting( true );
scrollbar.setValue( targetValue - delta + Math.round( delta * fraction ) );
}, () -> {
targetValue = Integer.MIN_VALUE;
scrollbar.setValueIsAdjusting( false );
});
animator.setResolution( resolution );

View File

@@ -0,0 +1,144 @@
/*
* Copyright 2020 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.testing;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.util.ArrayList;
import java.util.Arrays;
import javax.swing.*;
import net.miginfocom.swing.*;
/**
* @author Karl Tauber
*/
public class FlatSmoothScrollingTest
extends FlatTestPanel
{
public static void main( String[] args ) {
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatSmoothScrollingTest" );
UIManager.put( "ScrollBar.showButtons", true );
frame.showFrame( FlatSmoothScrollingTest::new );
} );
}
FlatSmoothScrollingTest() {
initComponents();
scrollPane1.getVerticalScrollBar().addAdjustmentListener( new AdjustmentHandler( "list vert" ) );
scrollPane1.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentHandler( "list horz" ) );
ArrayList<String> items = new ArrayList<>();
for( char ch = '0'; ch < 'z'; ch++ ) {
char[] chars = new char[ch - '0' + 1];
Arrays.fill( chars, ch );
items.add( new String( chars ) );
}
list1.setModel( new AbstractListModel<String>() {
@Override
public int getSize() {
return items.size();
}
@Override
public String getElementAt( int index ) {
return items.get( index );
}
} );
}
private void smoothScrollingChanged() {
UIManager.put( "ScrollPane.smoothScrolling", smoothScrollingCheckBox.isSelected() );
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
smoothScrollingCheckBox = new JCheckBox();
listLabel = new JLabel();
scrollPane1 = new JScrollPane();
list1 = new JList<>();
//======== this ========
setLayout(new MigLayout(
"ltr,insets dialog,hidemode 3",
// columns
"[]" +
"[200]",
// rows
"[]" +
"[::200,grow,fill]"));
//---- smoothScrollingCheckBox ----
smoothScrollingCheckBox.setText("Smooth scrolling");
smoothScrollingCheckBox.setSelected(true);
smoothScrollingCheckBox.addActionListener(e -> smoothScrollingChanged());
add(smoothScrollingCheckBox, "cell 0 0 2 1,alignx left,growx 0");
//---- listLabel ----
listLabel.setText("JList:");
add(listLabel, "cell 0 1,aligny top,growy 0");
//======== scrollPane1 ========
{
scrollPane1.setViewportView(list1);
}
add(scrollPane1, "cell 1 1,growx");
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JCheckBox smoothScrollingCheckBox;
private JLabel listLabel;
private JScrollPane scrollPane1;
private JList<String> list1;
// JFormDesigner - End of variables declaration //GEN-END:variables
//---- class AdjustmentHandler --------------------------------------------
private static class AdjustmentHandler
implements AdjustmentListener
{
private final String name;
private int count;
AdjustmentHandler( String name ) {
this.name = name;
}
@Override
public void adjustmentValueChanged( AdjustmentEvent e ) {
System.out.printf( "%s (%d): %s %3d %b%n",
name, ++count,
adjustmentType2Str( e.getAdjustmentType() ),
e.getValue(),
e.getValueIsAdjusting() );
}
private String adjustmentType2Str( int adjustmentType ) {
switch( adjustmentType ) {
case AdjustmentEvent.UNIT_INCREMENT: return "UNIT_INCREMENT";
case AdjustmentEvent.UNIT_DECREMENT: return "UNIT_DECREMENT";
case AdjustmentEvent.BLOCK_INCREMENT: return "BLOCK_INCREMENT";
case AdjustmentEvent.BLOCK_DECREMENT: return "BLOCK_DECREMENT";
case AdjustmentEvent.TRACK: return "TRACK";
default: return "unknown type";
}
}
}
}

View File

@@ -0,0 +1,43 @@
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
root: new FormRoot {
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$columnConstraints": "[][200]"
"$rowConstraints": "[][::200,grow,fill]"
} ) {
name: "this"
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "smoothScrollingCheckBox"
"text": "Smooth scrolling"
"selected": true
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "smoothScrollingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "listLabel"
"text": "JList:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1,aligny top,growy 0"
} )
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
name: "scrollPane1"
add( new FormComponent( "javax.swing.JList" ) {
name: "list1"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
"JavaCodeGenerator.variableLocal": false
}
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1,growx"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 790, 715 )
} )
}
}