diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSliderUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSliderUI.java index 35b93faa..9115a87e 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSliderUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSliderUI.java @@ -61,14 +61,14 @@ import com.formdev.flatlaf.util.UIScale; public class FlatSliderUI extends BasicSliderUI { - protected int trackWidth; - protected int thumbWidth; + private int trackWidth; + private int thumbWidth; - protected Color trackColor; - protected Color thumbColor; - protected Color focusColor; - protected Color hoverColor; - protected Color disabledForeground; + private Color trackColor; + private Color thumbColor; + private Color focusColor; + private Color hoverColor; + private Color disabledForeground; private MouseListener hoverListener; private boolean hover; diff --git a/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/ui/FlatRangeSliderUI.java b/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/ui/FlatRangeSliderUI.java index d308b9c3..7fb75b25 100644 --- a/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/ui/FlatRangeSliderUI.java +++ b/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/ui/FlatRangeSliderUI.java @@ -1,34 +1,63 @@ package com.formdev.flatlaf.jideoss.ui; -import java.awt.Cursor; +import java.awt.Color; +import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; -import java.awt.event.MouseEvent; +import java.awt.geom.Path2D; import java.awt.geom.RoundRectangle2D; -import java.lang.reflect.Field; import javax.swing.JComponent; import javax.swing.JSlider; +import javax.swing.LookAndFeel; +import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; -import javax.swing.plaf.basic.BasicSliderUI; -import com.formdev.flatlaf.ui.FlatSliderUI; import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.util.UIScale; -import com.jidesoft.swing.RangeSlider; +import com.jidesoft.plaf.basic.BasicRangeSliderUI; public class FlatRangeSliderUI - extends FlatSliderUI + extends BasicRangeSliderUI + { + private int trackWidth; + private int thumbWidth; + private Color trackColor; + private Color thumbColor; + private Color focusColor; + private Color hoverColor; + private Color disabledForeground; private Rectangle firstThumbRect; - public FlatRangeSliderUI() { - super(); + public FlatRangeSliderUI( JComponent slider ) { + super( (JSlider) slider ); } public static ComponentUI createUI( JComponent slider ) { - return new FlatRangeSliderUI(); + return new FlatRangeSliderUI( slider ); + } + + @Override + public void paint( Graphics g, JComponent c ) { + second = false; + super.paint( g, c ); + + Rectangle clip = g.getClipBounds(); + + firstThumbRect = new Rectangle( thumbRect ); + + second = true; + Point p = adjustThumbForHighValue(); + + if( clip.intersects( thumbRect ) ) { + paintTrack( g ); + paintThumb( g ); + } + + restoreThumbForLowValue( p ); + second = false; } @Override @@ -94,513 +123,105 @@ public class FlatRangeSliderUI } - // ******************************** - // From BasicRangeSliderUI - // ******************************** + //above here the code is same of FlatSliderUI @Override - public void paint( Graphics g, JComponent c ) { - second = false; - super.paint( g, c ); + protected void installDefaults( JSlider slider ) { + super.installDefaults( slider ); - Rectangle clip = g.getClipBounds(); + LookAndFeel.installProperty( slider, "opaque", false ); - firstThumbRect = new Rectangle( thumbRect ); + trackWidth = UIManager.getInt( "Slider.trackWidth" ); + thumbWidth = UIManager.getInt( "Slider.thumbWidth" ); - second = true; - Point p = adjustThumbForHighValue(); - - if( clip.intersects( thumbRect ) ) { - paintTrack( g ); - paintThumb( g ); - } - - restoreThumbForLowValue( p ); - second = false; - } - - protected void restoreThumbForLowValue( Point p ) { - thumbRect.x = p.x; - thumbRect.y = p.y; - } - - protected Point adjustThumbForHighValue() { - Point p = thumbRect.getLocation(); - if( slider.getOrientation() == JSlider.HORIZONTAL ) { - int valuePosition = xPositionForValue( ((RangeSlider) slider).getHighValue() ); - thumbRect.x = valuePosition - (thumbRect.width / 2); - } else { - int valuePosition = yPositionForValue( ((RangeSlider) slider).getHighValue() ); - thumbRect.y = valuePosition - (thumbRect.height / 2); - } - return p; - } - - protected void adjustSnapHighValue() { - int sliderValue = ((RangeSlider) slider).getHighValue(); - int snappedValue = sliderValue; - int majorTickSpacing = slider.getMajorTickSpacing(); - int minorTickSpacing = slider.getMinorTickSpacing(); - int tickSpacing = 0; - - if( minorTickSpacing > 0 ) { - tickSpacing = minorTickSpacing; - } else if( majorTickSpacing > 0 ) { - tickSpacing = majorTickSpacing; - } - - if( tickSpacing != 0 ) { - // If it's not on a tick, change the value - if( (sliderValue - slider.getMinimum()) % tickSpacing != 0 ) { - float temp = (float) (sliderValue - slider.getMinimum()) / (float) tickSpacing; - int whichTick = Math.round( temp ); - snappedValue = slider.getMinimum() + (whichTick * tickSpacing); - } - - if( snappedValue != sliderValue ) { - ((RangeSlider) slider).setHighValue( snappedValue ); - } - } + trackColor = UIManager.getColor( "Slider.trackColor" ); + thumbColor = UIManager.getColor( "Slider.thumbColor" ); + focusColor = FlatUIUtils.getUIColor( "Slider.focusedColor", "Component.focusColor" ); + hoverColor = FlatUIUtils.getUIColor( "Slider.hoverColor", focusColor ); + disabledForeground = UIManager.getColor( "Slider.disabledForeground" ); } @Override - protected void calculateThumbLocation() { - if( slider.getSnapToTicks() ) { - adjustSnapHighValue(); - } - super.calculateThumbLocation(); + protected void uninstallDefaults( JSlider slider ) { + super.uninstallDefaults( slider ); + + trackColor = null; + thumbColor = null; + focusColor = null; + hoverColor = null; + disabledForeground = null; } @Override - protected BasicSliderUI.TrackListener createTrackListener( JSlider slider ) { - return new RangeTrackListener( super.createTrackListener( slider ) ); + public Dimension getPreferredHorizontalSize() { + return UIScale.scale( super.getPreferredHorizontalSize() ); } - protected class RangeTrackListener - extends BasicSliderUI.TrackListener - { - - int handle; - int handleOffset; - int mouseStartLocation; - BasicSliderUI.TrackListener _listener; - - public RangeTrackListener( BasicSliderUI.TrackListener listener ) { - _listener = listener; - } - - /** - * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent) - */ - @Override - public void mousePressed( MouseEvent e ) { - if( !slider.isEnabled() ) { - return; - } - - if( slider.isRequestFocusEnabled() ) { - slider.requestFocus(); - } - - handle = getMouseHandle( e.getX(), e.getY() ); - setMousePressed( handle ); - - if( handle == MOUSE_HANDLE_MAX || handle == MOUSE_HANDLE_MIN || handle == MOUSE_HANDLE_MIDDLE || handle == MOUSE_HANDLE_BOTH ) { - handleOffset = (slider.getOrientation() == JSlider.VERTICAL) - ? e.getY() - yPositionForValue( ((RangeSlider) slider).getLowValue() ) - : e.getX() - xPositionForValue( ((RangeSlider) slider).getLowValue() ); - - mouseStartLocation = (slider.getOrientation() == JSlider.VERTICAL) ? e.getY() : e.getX(); - - slider.getModel().setValueIsAdjusting( true ); - } else if( handle == MOUSE_HANDLE_LOWER || handle == MOUSE_HANDLE_UPPER ) { - _listener.mousePressed( e ); - slider.putClientProperty( RangeSlider.CLIENT_PROPERTY_MOUSE_POSITION, null ); - } - } - - /** - * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent) - */ - @Override - public void mouseDragged( MouseEvent e ) { - if( !slider.isEnabled() ) { - return; - } - - int newLocation = (slider.getOrientation() == JSlider.VERTICAL) ? e.getY() : e.getX(); - - int newValue = (slider.getOrientation() == JSlider.VERTICAL) - ? valueForYPosition( newLocation ) - : valueForXPosition( newLocation ); - - if( newValue < slider.getModel().getMinimum() ) { - newValue = slider.getModel().getMinimum(); - } - - if( newValue > slider.getModel().getMaximum() ) { - newValue = slider.getModel().getMaximum(); - } - - if( handle == MOUSE_HANDLE_BOTH ) { - if( (newLocation - mouseStartLocation) >= 1 ) { - handle = MOUSE_HANDLE_MAX; - } else if( (newLocation - mouseStartLocation) <= -1 ) { - handle = MOUSE_HANDLE_MIN; - } else { - return; - } - } - - RangeSlider rangeSlider = (RangeSlider) slider; - switch( handle ) { - case MOUSE_HANDLE_MIN: - rangeSlider.setLowValue( Math.min( newValue, rangeSlider.getHighValue() ) ); - break; - case MOUSE_HANDLE_MAX: - rangeSlider.setHighValue( Math.max( rangeSlider.getLowValue(), newValue ) ); - break; - case MOUSE_HANDLE_MIDDLE: - if( ((RangeSlider) slider).isRangeDraggable() ) { - int delta = (slider.getOrientation() == JSlider.VERTICAL) - ? valueForYPosition( newLocation - handleOffset ) - rangeSlider.getLowValue() - : valueForXPosition( newLocation - handleOffset ) - rangeSlider.getLowValue(); - if( (delta < 0) && ((rangeSlider.getLowValue() + delta) < rangeSlider.getMinimum()) ) { - delta = rangeSlider.getMinimum() - rangeSlider.getLowValue(); - } - - if( (delta > 0) && ((rangeSlider.getHighValue() + delta) > rangeSlider.getMaximum()) ) { - delta = rangeSlider.getMaximum() - rangeSlider.getHighValue(); - } - - if( delta != 0 ) { - rangeSlider.setLowValue( rangeSlider.getLowValue() + delta ); - rangeSlider.setHighValue( rangeSlider.getHighValue() + delta ); - } - } - break; - } - } - - /** - * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent) - */ - @Override - public void mouseReleased( MouseEvent e ) { - slider.getModel().setValueIsAdjusting( false ); - setMouseReleased( handle ); - _listener.mouseReleased( e ); - } - - private void setCursor( int c ) { - Cursor cursor = Cursor.getPredefinedCursor( c ); - - if( slider.getCursor() != cursor ) { - slider.setCursor( cursor ); - } - } - - /** - * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent) - */ - @Override - public void mouseMoved( MouseEvent e ) { - if( !slider.isEnabled() ) { - return; - } - - int handle = getMouseHandle( e.getX(), e.getY() ); - setMouseRollover( handle ); - switch( handle ) { - case MOUSE_HANDLE_MIN: - case MOUSE_HANDLE_MAX: - case MOUSE_HANDLE_BOTH: - setCursor( Cursor.DEFAULT_CURSOR ); - break; - case MOUSE_HANDLE_MIDDLE: - if( slider instanceof RangeSlider && ((RangeSlider) slider).isRangeDraggable() ) { - setCursor( Cursor.MOVE_CURSOR ); - } else { - setCursor( Cursor.DEFAULT_CURSOR ); - } - break; - case MOUSE_HANDLE_NONE: - default: - setCursor( Cursor.DEFAULT_CURSOR ); - break; - } - } - - /** - * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent) - */ - @Override - public void mouseClicked( MouseEvent e ) { - if( e.getClickCount() == 2 ) { - slider.getModel().setValue( slider.getModel().getMinimum() ); - slider.getModel().setExtent( slider.getModel().getMaximum() - slider.getModel().getMinimum() ); - slider.repaint(); - } - } - - /** - * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent) - */ - @Override - public void mouseEntered( MouseEvent e ) { - hover = true; - slider.repaint(); - } - - /** - * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent) - */ - @Override - public void mouseExited( MouseEvent e ) { - hover = false; - slider.repaint(); - setCursor( Cursor.DEFAULT_CURSOR ); - } + @Override + public Dimension getPreferredVerticalSize() { + return UIScale.scale( super.getPreferredVerticalSize() ); } - protected static final int MOUSE_HANDLE_NONE = 0; - - protected static final int MOUSE_HANDLE_MIN = 1; - - protected static final int MOUSE_HANDLE_MAX = 2; - - protected static final int MOUSE_HANDLE_MIDDLE = 4; - - protected static final int MOUSE_HANDLE_LOWER = 5; - - protected static final int MOUSE_HANDLE_UPPER = 6; - - protected static final int MOUSE_HANDLE_BOTH = 7; - - protected int getMouseHandle( int x, int y ) { - Rectangle rect = trackRect; - - slider.putClientProperty( RangeSlider.CLIENT_PROPERTY_MOUSE_POSITION, null ); - - boolean inMin = false; - boolean inMax = false; - if( thumbRect.contains( x, y ) ) { - inMin = true; - } - Point p = adjustThumbForHighValue(); - if( thumbRect.contains( x, y ) ) { - inMax = true; - } - restoreThumbForLowValue( p ); - if( inMin && inMax ) { - return MOUSE_HANDLE_BOTH; - } else if( inMin ) { - return MOUSE_HANDLE_MIN; - } else if( inMax ) { - return MOUSE_HANDLE_MAX; - } - - if( slider.getOrientation() == JSlider.VERTICAL ) { - int minY = yPositionForValue( ((RangeSlider) slider).getLowValue() ); - int maxY = yPositionForValue( ((RangeSlider) slider).getHighValue() ); - Rectangle midRect = new Rectangle( rect.x, Math.min( minY, maxY ) + thumbRect.height / 2, rect.width, - Math.abs( maxY - minY ) - thumbRect.height ); - if( midRect.contains( x, y ) ) { - return MOUSE_HANDLE_MIDDLE; - } - int sy = rect.y + Math.max( minY, maxY ) + thumbRect.height / 2; - Rectangle lowerRect = new Rectangle( rect.x, sy, rect.width, rect.y + rect.height - sy ); - if( lowerRect.contains( x, y ) ) { - slider.putClientProperty( RangeSlider.CLIENT_PROPERTY_MOUSE_POSITION, true ); - return MOUSE_HANDLE_LOWER; - } - Rectangle upperRect = new Rectangle( rect.x, rect.y, rect.width, - Math.min( maxY, minY ) - thumbRect.height / 2 ); - if( upperRect.contains( x, y ) ) { - slider.putClientProperty( RangeSlider.CLIENT_PROPERTY_MOUSE_POSITION, false ); - return MOUSE_HANDLE_UPPER; - } - - return MOUSE_HANDLE_NONE; - } else { - int minX = xPositionForValue( ((RangeSlider) slider).getLowValue() ); - int maxX = xPositionForValue( ((RangeSlider) slider).getHighValue() ); - - Rectangle midRect = new Rectangle( Math.min( minX, maxX ) + thumbRect.width / 2, rect.y, - Math.abs( maxX - minX ) - thumbRect.width, rect.height ); - if( midRect.contains( x, y ) ) { - return MOUSE_HANDLE_MIDDLE; - } - Rectangle lowerRect = new Rectangle( rect.x, rect.y, Math.min( minX, maxX ) - thumbRect.width / 2 - rect.x, - rect.height ); - if( lowerRect.contains( x, y ) ) { - slider.putClientProperty( RangeSlider.CLIENT_PROPERTY_MOUSE_POSITION, true ); - return MOUSE_HANDLE_LOWER; - } - int sx = rect.x + Math.abs( maxX - minX ) + thumbRect.width / 2; - Rectangle upperRect = new Rectangle( sx, rect.y, rect.width - sx, rect.height ); - if( upperRect.contains( x, y ) ) { - slider.putClientProperty( RangeSlider.CLIENT_PROPERTY_MOUSE_POSITION, false ); - return MOUSE_HANDLE_UPPER; - } - return MOUSE_HANDLE_NONE; - } + @Override + public Dimension getMinimumHorizontalSize() { + return UIScale.scale( super.getMinimumHorizontalSize() ); } - protected boolean hover; - protected boolean second; - protected boolean rollover1; - protected boolean pressed1; - protected boolean rollover2; - protected boolean pressed2; + @Override + public Dimension getMinimumVerticalSize() { + return UIScale.scale( super.getMinimumVerticalSize() ); + } + + @Override + protected int getTickLength() { + return UIScale.scale( super.getTickLength() ); + } + + @Override + protected Dimension getThumbSize() { + return new Dimension( UIScale.scale( thumbWidth ), UIScale.scale( thumbWidth ) ); + } + + @Override + public void paintFocus( Graphics g ) { + // do not paint dashed focus rectangle + } @Override public void paintThumb( Graphics g ) { - try { - Field field = getClass().getSuperclass().getDeclaredField( "rollover" ); - field.setAccessible( true ); - field.set( this, second ? rollover2 : rollover1 ); + g.setColor( FlatUIUtils.deriveColor( slider.isEnabled() ? (FlatUIUtils.isPermanentFocusOwner( slider ) + ? focusColor + : (hover ? hoverColor : thumbColor)) : disabledForeground, thumbColor ) ); - field = getClass().getSuperclass().getDeclaredField( "pressed" ); - field.setAccessible( true ); - field.set( this, second ? pressed2 : pressed1 ); - } catch( NoSuchFieldException e ) { - // e.printStackTrace(); - } catch( IllegalAccessException e ) { - // e.printStackTrace(); - } + if( isRoundThumb() ) + g.fillOval( thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height ); + else { + double w = thumbRect.width; + double h = thumbRect.height; + double wh = w / 2; - super.paintThumb( g ); - } + Path2D thumb = FlatUIUtils.createPath( 0, 0, w, 0, w, (h - wh), wh, h, 0, (h - wh) ); - protected void setMouseRollover( int handle ) { - switch( handle ) { - case MOUSE_HANDLE_MIN: { - rollover1 = true; - rollover2 = false; + Graphics2D g2 = (Graphics2D) g.create(); + try { + g2.translate( thumbRect.x, thumbRect.y ); + if( slider.getOrientation() == JSlider.VERTICAL ) { + if( slider.getComponentOrientation().isLeftToRight() ) { + g2.translate( 0, thumbRect.height ); + g2.rotate( Math.toRadians( 270 ) ); + } else { + g2.translate( thumbRect.width, 0 ); + g2.rotate( Math.toRadians( 90 ) ); + } + } + g2.fill( thumb ); + } finally { + g2.dispose(); } - break; - case MOUSE_HANDLE_MAX: { - rollover2 = true; - rollover1 = false; - } - break; - case MOUSE_HANDLE_MIDDLE: - case MOUSE_HANDLE_BOTH: { - rollover1 = true; - rollover2 = true; - } - break; - case MOUSE_HANDLE_NONE: - rollover1 = false; - rollover2 = false; - break; - } - slider.repaint( thumbRect ); - Point p = adjustThumbForHighValue(); - slider.repaint( thumbRect ); - restoreThumbForLowValue( p ); - } - - protected void setMousePressed( int handle ) { - switch( handle ) { - case MOUSE_HANDLE_MIN: { - pressed1 = true; - pressed2 = false; - } - break; - case MOUSE_HANDLE_MAX: { - pressed2 = true; - pressed1 = false; - } - break; - case MOUSE_HANDLE_MIDDLE: - case MOUSE_HANDLE_BOTH: { - pressed1 = true; - pressed2 = true; - } - break; - case MOUSE_HANDLE_NONE: - pressed1 = false; - pressed2 = false; - break; - } - slider.repaint( thumbRect ); - Point p = adjustThumbForHighValue(); - slider.repaint( thumbRect ); - restoreThumbForLowValue( p ); - } - - @SuppressWarnings( { "UnusedDeclaration" } ) - protected void setMouseReleased( int handle ) { - pressed1 = false; - pressed2 = false; - slider.repaint( thumbRect ); - Point p = adjustThumbForHighValue(); - slider.repaint( thumbRect ); - restoreThumbForLowValue( p ); - } - - @Override - public void scrollByBlock( int direction ) { - synchronized( slider ) { - - int oldValue; - Object clientProperty = slider.getClientProperty( RangeSlider.CLIENT_PROPERTY_MOUSE_POSITION ); - if( clientProperty == null ) { - oldValue = slider.getValue(); - } else if( Boolean.TRUE.equals( clientProperty ) ) { - oldValue = ((RangeSlider) slider).getLowValue(); - } else { - oldValue = ((RangeSlider) slider).getHighValue(); - } - int blockIncrement = (slider.getMaximum() - slider.getMinimum()) / 10; - if( blockIncrement <= 0 && slider.getMaximum() > slider.getMinimum() ) { - - blockIncrement = 1; - } - - slider.putClientProperty( RangeSlider.CLIENT_PROPERTY_ADJUST_ACTION, "scrollByBlock" ); - int delta = blockIncrement * ((direction > 0) ? POSITIVE_SCROLL : NEGATIVE_SCROLL); - if( clientProperty == null ) { - slider.setValue( Math.max( Math.min( oldValue + delta, slider.getMaximum() ), slider.getMinimum() ) ); - } else if( Boolean.TRUE.equals( clientProperty ) ) { - ((RangeSlider) slider) - .setLowValue( Math.max( Math.min( oldValue + delta, slider.getMaximum() ), slider.getMinimum() ) ); - } else { - ((RangeSlider) slider) - .setHighValue( Math.max( Math.min( oldValue + delta, slider.getMaximum() ), slider.getMinimum() ) ); - } - slider.putClientProperty( RangeSlider.CLIENT_PROPERTY_ADJUST_ACTION, null ); } } - @Override - public void scrollByUnit( int direction ) { - synchronized( slider ) { - - int oldValue; - Object clientProperty = slider.getClientProperty( RangeSlider.CLIENT_PROPERTY_MOUSE_POSITION ); - if( clientProperty == null ) { - oldValue = slider.getValue(); - } else if( Boolean.TRUE.equals( clientProperty ) ) { - oldValue = ((RangeSlider) slider).getLowValue(); - } else { - oldValue = ((RangeSlider) slider).getHighValue(); - } - int delta = 1 * ((direction > 0) ? POSITIVE_SCROLL : NEGATIVE_SCROLL); - - slider.putClientProperty( RangeSlider.CLIENT_PROPERTY_ADJUST_ACTION, "scrollByUnit" ); - if( clientProperty == null ) { - slider.setValue( Math.max( Math.min( oldValue + delta, slider.getMaximum() ), slider.getMinimum() ) ); - } else if( Boolean.TRUE.equals( clientProperty ) ) { - ((RangeSlider) slider) - .setLowValue( Math.max( Math.min( oldValue + delta, slider.getMaximum() ), slider.getMinimum() ) ); - } else { - ((RangeSlider) slider) - .setHighValue( Math.max( Math.min( oldValue + delta, slider.getMaximum() ), slider.getMinimum() ) ); - } - slider.putClientProperty( RangeSlider.CLIENT_PROPERTY_ADJUST_ACTION, null ); - } + private boolean isRoundThumb() { + return !slider.getPaintTicks() && !slider.getPaintLabels(); } }