Slider: snap to ticks is now done while dragging the thumb

This commit is contained in:
Karl Tauber
2020-12-20 17:32:01 +01:00
parent 4fdd44858f
commit 53854a4d13
4 changed files with 254 additions and 185 deletions

View File

@@ -6,7 +6,12 @@ FlatLaf Change Log
#### New features and improvements #### New features and improvements
- Slider: Clicking on track now immediately moves the thumb to mouse location - Slider: Clicking on track now immediately moves the thumb to mouse location
and starts dragging the thumb. and starts dragging the thumb. Use `UIManager.put(
"Slider.scrollOnTrackClick", true )` to enable old behavior that scrolls the
thumb when clicking on track.
- Slider: Snap to ticks is now done while dragging the thumb. Use
`UIManager.put( "Slider.snapToTicksOnReleased", true )` to enable old behavior
that snaps to ticks on mouse released.
- Extras: Added standard component extension classes that provides easy access - Extras: Added standard component extension classes that provides easy access
to FlatLaf specific client properties (see package to FlatLaf specific client properties (see package
`com.formdev.flatlaf.extras.components`). `com.formdev.flatlaf.extras.components`).

View File

@@ -543,8 +543,8 @@ debug*/
// move the mouse event coordinates back to current mouse location // move the mouse event coordinates back to current mouse location
e.translatePoint( -tx, -ty ); e.translatePoint( -tx, -ty );
// invoke super mouseDragged() to update thumb location // invoke mouseDragged() to update thumb location
super.mouseDragged( e ); mouseDragged( e );
setThumbPressed( true ); setThumbPressed( true );
} }
@@ -555,6 +555,20 @@ debug*/
super.mouseReleased( e ); super.mouseReleased( e );
} }
@Override
public void mouseDragged( MouseEvent e ) {
super.mouseDragged( e );
if( isDragging() &&
slider.getSnapToTicks() &&
slider.isEnabled() &&
!UIManager.getBoolean( "Slider.snapToTicksOnReleased" ) )
{
calculateThumbLocation();
slider.repaint();
}
}
protected void setThumbHover( boolean hover ) { protected void setThumbHover( boolean hover ) {
if( hover != thumbHover ) { if( hover != thumbHover ) {
thumbHover = hover; thumbHover = hover;

View File

@@ -19,6 +19,7 @@ package com.formdev.flatlaf.testing;
import java.awt.*; import java.awt.*;
import javax.swing.*; import javax.swing.*;
import javax.swing.border.*; import javax.swing.border.*;
import javax.swing.event.ChangeListener;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.extras.components.*; import com.formdev.flatlaf.extras.components.*;
import com.formdev.flatlaf.extras.components.FlatButton.ButtonType; import com.formdev.flatlaf.extras.components.FlatButton.ButtonType;
@@ -49,6 +50,15 @@ public class FlatComponentsTest
allSliders = new JSlider[] { slider1, slider2, slider3, slider4, slider5, slider6 }; allSliders = new JSlider[] { slider1, slider2, slider3, slider4, slider5, slider6 };
roundSliders = new JSlider[] { slider1, slider2, slider6 }; roundSliders = new JSlider[] { slider1, slider2, slider6 };
directionalSliders = new JSlider[] { slider3, slider4, slider5 }; directionalSliders = new JSlider[] { slider3, slider4, slider5 };
ChangeListener sliderChanged = e -> {
JSlider slider = (JSlider) e.getSource();
String text = slider.getValue() + " " + slider.getValueIsAdjusting();
sliderValueLabel.setText( text );
// System.out.println( text );
};
for( JSlider slider : allSliders )
slider.addChangeListener( sliderChanged );
} }
private void changeProgress() { private void changeProgress() {
@@ -375,6 +385,7 @@ public class FlatComponentsTest
JLabel sliderLabel = new JLabel(); JLabel sliderLabel = new JLabel();
slider1 = new JSlider(); slider1 = new JSlider();
slider6 = new JSlider(); slider6 = new JSlider();
JPanel panel8 = new JPanel();
JPanel panel6 = new JPanel(); JPanel panel6 = new JPanel();
sliderPaintTrackCheckBox = new JCheckBox(); sliderPaintTrackCheckBox = new JCheckBox();
sliderPaintTicksCheckBox = new FlatTriStateCheckBox(); sliderPaintTicksCheckBox = new FlatTriStateCheckBox();
@@ -383,16 +394,17 @@ public class FlatComponentsTest
sliderSnapToTicksCheckBox = new JCheckBox(); sliderSnapToTicksCheckBox = new JCheckBox();
majorTickSpacingSpinner = new JSpinner(); majorTickSpacingSpinner = new JSpinner();
minorTickSpacingSpinner = new JSpinner(); minorTickSpacingSpinner = new JSpinner();
sliderValueLabel = new JLabel();
JPanel panel7 = new JPanel();
indeterminateCheckBox = new JCheckBox();
squareCheckBox = new JCheckBox();
largeHeightCheckBox = new JCheckBox();
JLabel sliderLabel2 = new JLabel(); JLabel sliderLabel2 = new JLabel();
slider3 = new JSlider(); slider3 = new JSlider();
slider5 = new JSlider(); slider5 = new JSlider();
JLabel progressBarLabel = new JLabel(); JLabel progressBarLabel = new JLabel();
progressBar1 = new FlatProgressBar(); progressBar1 = new FlatProgressBar();
progressBar2 = new FlatProgressBar(); progressBar2 = new FlatProgressBar();
JPanel panel7 = new JPanel();
indeterminateCheckBox = new JCheckBox();
squareCheckBox = new JCheckBox();
largeHeightCheckBox = new JCheckBox();
JLabel toolTipLabel = new JLabel(); JLabel toolTipLabel = new JLabel();
JToolTip toolTip1 = new JToolTip(); JToolTip toolTip1 = new JToolTip();
JToolTip toolTip2 = new JToolTip(); JToolTip toolTip2 = new JToolTip();
@@ -1302,6 +1314,18 @@ public class FlatComponentsTest
slider6.setValue(30); slider6.setValue(30);
add(slider6, "cell 1 19 3 1"); add(slider6, "cell 1 19 3 1");
//======== panel8 ========
{
panel8.setLayout(new MigLayout(
"ltr,insets 0,hidemode 3",
// columns
"[]",
// rows
"[]" +
"[]" +
"[]" +
"[]"));
//======== panel6 ======== //======== panel6 ========
{ {
panel6.setBorder(new TitledBorder("JSlider Control")); panel6.setBorder(new TitledBorder("JSlider Control"));
@@ -1312,6 +1336,7 @@ public class FlatComponentsTest
// rows // rows
"[]0" + "[]0" +
"[]0" + "[]0" +
"[]0" +
"[]")); "[]"));
//---- sliderPaintTrackCheckBox ---- //---- sliderPaintTrackCheckBox ----
@@ -1349,8 +1374,43 @@ public class FlatComponentsTest
minorTickSpacingSpinner.setModel(new SpinnerNumberModel(10, 0, 100, 5)); minorTickSpacingSpinner.setModel(new SpinnerNumberModel(10, 0, 100, 5));
minorTickSpacingSpinner.addChangeListener(e -> minorThickSpacingChanged()); minorTickSpacingSpinner.addChangeListener(e -> minorThickSpacingChanged());
panel6.add(minorTickSpacingSpinner, "cell 0 2"); panel6.add(minorTickSpacingSpinner, "cell 0 2");
//---- sliderValueLabel ----
sliderValueLabel.setText("slider value");
panel6.add(sliderValueLabel, "cell 0 3");
} }
add(panel6, "cell 4 19 1 2,grow"); panel8.add(panel6, "cell 0 0 1 2,grow");
//======== panel7 ========
{
panel7.setBorder(new TitledBorder("JProgressBar Control"));
panel7.setLayout(new MigLayout(
"ltr,insets 0,hidemode 3",
// columns
"[]" +
"[fill]",
// rows
"[]0" +
"[]"));
//---- indeterminateCheckBox ----
indeterminateCheckBox.setText("indeterminate");
indeterminateCheckBox.addActionListener(e -> indeterminateProgress());
panel7.add(indeterminateCheckBox, "cell 0 0");
//---- squareCheckBox ----
squareCheckBox.setText("square");
squareCheckBox.addActionListener(e -> squareChanged());
panel7.add(squareCheckBox, "cell 1 0");
//---- largeHeightCheckBox ----
largeHeightCheckBox.setText("large height");
largeHeightCheckBox.addActionListener(e -> largeHeightChanged());
panel7.add(largeHeightCheckBox, "cell 0 1,aligny top,growy 0");
}
panel8.add(panel7, "cell 0 2 1 2,grow");
}
add(panel8, "cell 4 19 1 4");
//---- sliderLabel2 ---- //---- sliderLabel2 ----
sliderLabel2.setText("baseline"); sliderLabel2.setText("baseline");
@@ -1387,35 +1447,6 @@ public class FlatComponentsTest
progressBar2.setValue(60); progressBar2.setValue(60);
add(progressBar2, "cell 1 21 3 1,growx"); add(progressBar2, "cell 1 21 3 1,growx");
//======== panel7 ========
{
panel7.setBorder(new TitledBorder("JProgressBar Control"));
panel7.setLayout(new MigLayout(
"ltr,insets 0,hidemode 3",
// columns
"[]" +
"[fill]",
// rows
"[]0" +
"[]"));
//---- indeterminateCheckBox ----
indeterminateCheckBox.setText("indeterminate");
indeterminateCheckBox.addActionListener(e -> indeterminateProgress());
panel7.add(indeterminateCheckBox, "cell 0 0");
//---- squareCheckBox ----
squareCheckBox.setText("square");
squareCheckBox.addActionListener(e -> squareChanged());
panel7.add(squareCheckBox, "cell 1 0");
//---- largeHeightCheckBox ----
largeHeightCheckBox.setText("large height");
largeHeightCheckBox.addActionListener(e -> largeHeightChanged());
panel7.add(largeHeightCheckBox, "cell 0 1,aligny top,growy 0");
}
add(panel7, "cell 4 21 1 2,grow");
//---- toolTipLabel ---- //---- toolTipLabel ----
toolTipLabel.setText("JToolTip:"); toolTipLabel.setText("JToolTip:");
add(toolTipLabel, "cell 0 22"); add(toolTipLabel, "cell 0 22");
@@ -1579,13 +1610,14 @@ public class FlatComponentsTest
private JCheckBox sliderSnapToTicksCheckBox; private JCheckBox sliderSnapToTicksCheckBox;
private JSpinner majorTickSpacingSpinner; private JSpinner majorTickSpacingSpinner;
private JSpinner minorTickSpacingSpinner; private JSpinner minorTickSpacingSpinner;
private JLabel sliderValueLabel;
private JCheckBox indeterminateCheckBox;
private JCheckBox squareCheckBox;
private JCheckBox largeHeightCheckBox;
private JSlider slider3; private JSlider slider3;
private JSlider slider5; private JSlider slider5;
private FlatProgressBar progressBar1; private FlatProgressBar progressBar1;
private FlatProgressBar progressBar2; private FlatProgressBar progressBar2;
private JCheckBox indeterminateCheckBox;
private JCheckBox squareCheckBox;
private JCheckBox largeHeightCheckBox;
// JFormDesigner - End of variables declaration //GEN-END:variables // JFormDesigner - End of variables declaration //GEN-END:variables
//---- class TestDefaultButton -------------------------------------------- //---- class TestDefaultButton --------------------------------------------

View File

@@ -1158,7 +1158,13 @@ new FormModel {
} ) } )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$columnConstraints": "[]" "$columnConstraints": "[]"
"$rowConstraints": "[]0[]0[]" "$rowConstraints": "[][][][]"
"$layoutConstraints": "ltr,insets 0,hidemode 3"
} ) {
name: "panel8"
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$columnConstraints": "[]"
"$rowConstraints": "[]0[]0[]0[]"
"$layoutConstraints": "ltr,insets 0,hidemode 3" "$layoutConstraints": "ltr,insets 0,hidemode 3"
} ) { } ) {
name: "panel6" name: "panel6"
@@ -1234,8 +1240,60 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2" "value": "cell 0 2"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "sliderValueLabel"
"text": "slider value"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 19 1 2,grow" "value": "cell 0 3"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0 1 2,grow"
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$columnConstraints": "[][fill]"
"$rowConstraints": "[]0[]"
"$layoutConstraints": "ltr,insets 0,hidemode 3"
} ) {
name: "panel7"
"border": new javax.swing.border.TitledBorder( "JProgressBar Control" )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "indeterminateCheckBox"
"text": "indeterminate"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "indeterminateProgress", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "squareCheckBox"
"text": "square"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "squareChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "largeHeightCheckBox"
"text": "large height"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "largeHeightChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1,aligny top,growy 0"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2 1 2,grow"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 19 1 4"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "sliderLabel2" name: "sliderLabel2"
@@ -1296,46 +1354,6 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 21 3 1,growx" "value": "cell 1 21 3 1,growx"
} ) } )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$columnConstraints": "[][fill]"
"$rowConstraints": "[]0[]"
"$layoutConstraints": "ltr,insets 0,hidemode 3"
} ) {
name: "panel7"
"border": new javax.swing.border.TitledBorder( "JProgressBar Control" )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "indeterminateCheckBox"
"text": "indeterminate"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "indeterminateProgress", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "squareCheckBox"
"text": "square"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "squareChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "largeHeightCheckBox"
"text": "large height"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "largeHeightChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1,aligny top,growy 0"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 21 1 2,grow"
} )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "toolTipLabel" name: "toolTipLabel"
"text": "JToolTip:" "text": "JToolTip:"