com.alee.laf.slider.WebSliderUI Maven / Gradle / Ivy
/*
* This file is part of WebLookAndFeel library.
*
* WebLookAndFeel library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* WebLookAndFeel library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WebLookAndFeel library. If not, see .
*/
package com.alee.laf.slider;
import com.alee.extended.painter.Painter;
import com.alee.extended.painter.PainterSupport;
import com.alee.global.StyleConstants;
import com.alee.laf.WebLookAndFeel;
import com.alee.laf.label.WebLabelStyle;
import com.alee.utils.ColorUtils;
import com.alee.utils.GraphicsUtils;
import com.alee.utils.LafUtils;
import com.alee.utils.SwingUtils;
import com.alee.utils.swing.BorderMethods;
import com.alee.utils.swing.WebTimer;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicSliderUI;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
/**
* User: mgarin Date: 26.05.11 Time: 18:03
*/
public class WebSliderUI extends BasicSliderUI implements BorderMethods
{
public static final int MAX_DARKNESS = 5;
protected Color trackBgTop = WebSliderStyle.trackBgTop;
protected Color trackBgBottom = WebSliderStyle.trackBgBottom;
protected int trackHeight = WebSliderStyle.trackHeight;
protected int trackRound = WebSliderStyle.trackRound;
protected int trackShadeWidth = WebSliderStyle.trackShadeWidth;
protected boolean drawProgress = WebSliderStyle.drawProgress;
protected int progressRound = WebSliderStyle.progressRound;
protected int progressShadeWidth = WebSliderStyle.progressShadeWidth;
protected boolean drawThumb = WebSliderStyle.drawThumb;
protected Color thumbBgTop = WebSliderStyle.thumbBgTop;
protected Color thumbBgBottom = WebSliderStyle.thumbBgBottom;
protected int thumbWidth = WebSliderStyle.thumbWidth;
protected int thumbHeight = WebSliderStyle.thumbHeight;
protected int thumbRound = WebSliderStyle.thumbRound;
protected int thumbShadeWidth = WebSliderStyle.thumbShadeWidth;
protected boolean angledThumb = WebSliderStyle.angledThumb;
protected boolean sharpThumbAngle = WebSliderStyle.sharpThumbAngle;
protected int thumbAngleLength = WebSliderStyle.thumbAngleLength;
protected boolean animated = WebSliderStyle.animated;
protected boolean rolloverDarkBorderOnly = WebSliderStyle.rolloverDarkBorderOnly;
protected Insets margin = WebLabelStyle.margin;
protected Painter painter = WebLabelStyle.painter;
/**
* Slider listeners.
*/
protected PropertyChangeListener propertyChangeListener;
protected MouseWheelListener mouseWheelListener;
protected ChangeListener changeListener;
protected MouseAdapter mouseAdapter;
/**
* Runtime variables.
*/
protected boolean rollover = false;
protected int rolloverDarkness = 0;
protected WebTimer rolloverTimer;
public WebSliderUI ( final JSlider b )
{
super ( b );
}
public static ComponentUI createUI ( final JComponent c )
{
return new WebSliderUI ( ( JSlider ) c );
}
@Override
public void installUI ( final JComponent c )
{
super.installUI ( c );
// Default settings
SwingUtils.setOrientation ( slider );
LookAndFeel.installProperty ( slider, WebLookAndFeel.OPAQUE_PROPERTY, Boolean.FALSE );
slider.setForeground ( StyleConstants.textColor );
PainterSupport.installPainter ( slider, this.painter );
updateBorder ();
// Orientation change listener
propertyChangeListener = new PropertyChangeListener ()
{
@Override
public void propertyChange ( final PropertyChangeEvent evt )
{
updateBorder ();
}
};
slider.addPropertyChangeListener ( WebLookAndFeel.ORIENTATION_PROPERTY, propertyChangeListener );
// Rollover mouse wheel scroll
mouseWheelListener = new MouseWheelListener ()
{
@Override
public void mouseWheelMoved ( final MouseWheelEvent e )
{
slider.setValue (
Math.min ( Math.max ( slider.getMinimum (), slider.getValue () + e.getWheelRotation () ), slider.getMaximum () ) );
}
};
slider.addMouseWheelListener ( mouseWheelListener );
// todo Requires optimizations
// Fixed value change repaint
changeListener = new ChangeListener ()
{
@Override
public void stateChanged ( final ChangeEvent e )
{
slider.repaint ();
}
};
slider.addChangeListener ( changeListener );
// todo Requires optimizations
// Rollover animator
rolloverTimer = new WebTimer ( "WebProgressBarUI.animator", 40, new ActionListener ()
{
@Override
public void actionPerformed ( final ActionEvent e )
{
if ( rollover && rolloverDarkness < MAX_DARKNESS )
{
rolloverDarkness++;
slider.repaint ();
}
else if ( !rollover && rolloverDarkness > 0 )
{
rolloverDarkness--;
slider.repaint ();
}
else
{
rolloverTimer.stop ();
}
}
} );
mouseAdapter = new MouseAdapter ()
{
@Override
public void mousePressed ( final MouseEvent e )
{
slider.repaint ();
}
@Override
public void mouseReleased ( final MouseEvent e )
{
slider.repaint ();
}
@Override
public void mouseDragged ( final MouseEvent e )
{
slider.repaint ();
}
@Override
public void mouseEntered ( final MouseEvent e )
{
rollover = true;
if ( isAnimated () && c.isEnabled () )
{
rolloverTimer.start ();
}
else
{
rolloverDarkness = MAX_DARKNESS;
slider.repaint ();
}
}
@Override
public void mouseExited ( final MouseEvent e )
{
rollover = false;
if ( isAnimated () && c.isEnabled () )
{
rolloverTimer.start ();
}
else
{
rolloverDarkness = 0;
slider.repaint ();
}
}
};
slider.addMouseListener ( mouseAdapter );
slider.addMouseMotionListener ( mouseAdapter );
}
@Override
public void uninstallUI ( final JComponent c )
{
PainterSupport.uninstallPainter ( slider, this.painter );
slider.removePropertyChangeListener ( WebLookAndFeel.ORIENTATION_PROPERTY, propertyChangeListener );
slider.removeMouseWheelListener ( mouseWheelListener );
slider.removeChangeListener ( changeListener );
slider.removeMouseListener ( mouseAdapter );
slider.removeMouseMotionListener ( mouseAdapter );
super.uninstallUI ( c );
}
@Override
public void updateBorder ()
{
if ( slider != null )
{
// Preserve old borders
if ( SwingUtils.isPreserveBorders ( slider ) )
{
return;
}
// Actual margin
final boolean ltr = slider.getComponentOrientation ().isLeftToRight ();
final Insets m = new Insets ( margin.top, ltr ? margin.left : margin.right, margin.bottom, ltr ? margin.right : margin.left );
// Calculating additional borders
if ( painter != null )
{
// Painter borders
final Insets pi = painter.getMargin ( slider );
m.top += pi.top;
m.bottom += pi.bottom;
m.left += ltr ? pi.left : pi.right;
m.right += ltr ? pi.right : pi.left;
}
// Installing border
slider.setBorder ( LafUtils.createWebBorder ( m ) );
}
}
public boolean isAnimated ()
{
return animated;
}
public void setAnimated ( final boolean animated )
{
this.animated = animated;
}
public boolean isRolloverDarkBorderOnly ()
{
return rolloverDarkBorderOnly;
}
public void setRolloverDarkBorderOnly ( final boolean rolloverDarkBorderOnly )
{
this.rolloverDarkBorderOnly = rolloverDarkBorderOnly;
}
public Color getTrackBgTop ()
{
return trackBgTop;
}
public void setTrackBgTop ( final Color trackBgTop )
{
this.trackBgTop = trackBgTop;
}
public Color getTrackBgBottom ()
{
return trackBgBottom;
}
public void setTrackBgBottom ( final Color trackBgBottom )
{
this.trackBgBottom = trackBgBottom;
}
public int getTrackHeight ()
{
return trackHeight;
}
public void setTrackHeight ( final int trackHeight )
{
this.trackHeight = trackHeight;
}
public int getTrackRound ()
{
return trackRound;
}
public void setTrackRound ( final int trackRound )
{
this.trackRound = trackRound;
}
public int getTrackShadeWidth ()
{
return trackShadeWidth;
}
public void setTrackShadeWidth ( final int trackShadeWidth )
{
this.trackShadeWidth = trackShadeWidth;
}
public boolean isDrawProgress ()
{
return drawProgress;
}
public void setDrawProgress ( final boolean drawProgress )
{
this.drawProgress = drawProgress;
}
public int getProgressRound ()
{
return progressRound;
}
public void setProgressRound ( final int progressRound )
{
this.progressRound = progressRound;
}
public int getProgressShadeWidth ()
{
return progressShadeWidth;
}
public void setProgressShadeWidth ( final int progressShadeWidth )
{
this.progressShadeWidth = progressShadeWidth;
}
public boolean isDrawThumb ()
{
return drawThumb;
}
public void setDrawThumb ( final boolean drawThumb )
{
this.drawThumb = drawThumb;
}
public Color getThumbBgTop ()
{
return thumbBgTop;
}
public void setThumbBgTop ( final Color thumbBgTop )
{
this.thumbBgTop = thumbBgTop;
}
public Color getThumbBgBottom ()
{
return thumbBgBottom;
}
public void setThumbBgBottom ( final Color thumbBgBottom )
{
this.thumbBgBottom = thumbBgBottom;
}
public int getThumbWidth ()
{
return thumbWidth;
}
public void setThumbWidth ( final int thumbWidth )
{
this.thumbWidth = thumbWidth;
}
public int getThumbHeight ()
{
return thumbHeight;
}
public void setThumbHeight ( final int thumbHeight )
{
this.thumbHeight = thumbHeight;
}
public int getThumbRound ()
{
return thumbRound;
}
public void setThumbRound ( final int thumbRound )
{
this.thumbRound = thumbRound;
}
public int getThumbShadeWidth ()
{
return thumbShadeWidth;
}
public void setThumbShadeWidth ( final int thumbShadeWidth )
{
this.thumbShadeWidth = thumbShadeWidth;
}
public boolean isAngledThumb ()
{
return angledThumb;
}
public void setAngledThumb ( final boolean angledThumb )
{
this.angledThumb = angledThumb;
}
public boolean isSharpThumbAngle ()
{
return sharpThumbAngle;
}
public void setSharpThumbAngle ( final boolean sharpThumbAngle )
{
this.sharpThumbAngle = sharpThumbAngle;
}
public int getThumbAngleLength ()
{
return thumbAngleLength;
}
public void setThumbAngleLength ( final int thumbAngleLength )
{
this.thumbAngleLength = thumbAngleLength;
}
public Insets getMargin ()
{
return margin;
}
public void setMargin ( final Insets margin )
{
this.margin = margin;
updateBorder ();
}
public Painter getPainter ()
{
return painter;
}
public void setPainter ( final Painter painter )
{
PainterSupport.uninstallPainter ( slider, this.painter );
this.painter = painter;
PainterSupport.installPainter ( slider, this.painter );
updateBorder ();
}
@Override
protected Dimension getThumbSize ()
{
if ( slider.getOrientation () == JSlider.HORIZONTAL )
{
return new Dimension ( thumbWidth, thumbHeight );
}
else
{
return new Dimension ( thumbHeight, thumbWidth );
}
}
@Override
public void paint ( final Graphics g, final JComponent c )
{
// Force painter to draw background
if ( painter != null )
{
painter.paint ( ( Graphics2D ) g, SwingUtils.size ( c ), c );
}
super.paint ( g, c );
}
@Override
public void paintFocus ( final Graphics g )
{
// Do not paint default focus
}
@Override
public void paintThumb ( final Graphics g )
{
if ( drawThumb )
{
final Graphics2D g2d = ( Graphics2D ) g;
final Object aa = GraphicsUtils.setupAntialias ( g2d );
// Thumb shape
final Shape ts = getThumbShape ();
// // Thumb shade
// if ( slider.isEnabled () )
// {
// LafUtils.drawShade ( g2d, ts, StyleConstants.shadeColor, thumbShadeWidth );
// }
// Thumb background
if ( slider.getOrientation () == JSlider.HORIZONTAL )
{
g2d.setPaint ( new GradientPaint ( 0, thumbRect.y, thumbBgTop, 0, thumbRect.y + thumbRect.height, thumbBgBottom ) );
}
else
{
g2d.setPaint ( new GradientPaint ( thumbRect.x, 0, thumbBgTop, thumbRect.x + thumbRect.width, 0, thumbBgBottom ) );
}
g2d.fill ( ts );
// Thumb border
g2d.setPaint ( slider.isEnabled () ? StyleConstants.darkBorderColor : StyleConstants.disabledBorderColor );
g2d.draw ( ts );
// Thumb focus
// LafUtils.drawCustomWebFocus ( g2d, slider, FocusType.fieldFocus, ts );
GraphicsUtils.restoreAntialias ( g2d, aa );
}
}
protected Color getBorderColor ()
{
return ColorUtils.getIntermediateColor ( StyleConstants.borderColor, StyleConstants.darkBorderColor, getProgress () );
}
protected float getProgress ()
{
return ( float ) rolloverDarkness / MAX_DARKNESS;
}
protected Shape getThumbShape ()
{
if ( angledThumb && ( slider.getPaintLabels () || slider.getPaintTicks () ) )
{
if ( slider.getOrientation () == JSlider.HORIZONTAL )
{
final GeneralPath gp = new GeneralPath ( GeneralPath.WIND_EVEN_ODD );
gp.moveTo ( thumbRect.x, thumbRect.y + thumbRound );
gp.quadTo ( thumbRect.x, thumbRect.y, thumbRect.x + thumbRound, thumbRect.y );
gp.lineTo ( thumbRect.x + thumbRect.width - thumbRound, thumbRect.y );
gp.quadTo ( thumbRect.x + thumbRect.width, thumbRect.y, thumbRect.x + thumbRect.width, thumbRect.y + thumbRound );
gp.lineTo ( thumbRect.x + thumbRect.width, thumbRect.y + thumbRect.height - thumbAngleLength );
if ( sharpThumbAngle )
{
gp.lineTo ( thumbRect.x + thumbRect.width / 2, thumbRect.y + thumbRect.height );
gp.lineTo ( thumbRect.x, thumbRect.y + thumbRect.height - thumbAngleLength );
}
else
{
gp.quadTo ( thumbRect.x + thumbRect.width, thumbRect.y + thumbRect.height - thumbAngleLength / 2,
thumbRect.x + thumbRect.width / 2, thumbRect.y + thumbRect.height );
gp.quadTo ( thumbRect.x, thumbRect.y + thumbRect.height - thumbAngleLength / 2, thumbRect.x,
thumbRect.y + thumbRect.height - thumbAngleLength );
}
gp.closePath ();
return gp;
}
else
{
final GeneralPath gp = new GeneralPath ( GeneralPath.WIND_EVEN_ODD );
if ( slider.getComponentOrientation ().isLeftToRight () )
{
gp.moveTo ( thumbRect.x, thumbRect.y + thumbRound );
gp.quadTo ( thumbRect.x, thumbRect.y, thumbRect.x + thumbRound, thumbRect.y );
gp.lineTo ( thumbRect.x + thumbRect.width - thumbAngleLength, thumbRect.y );
if ( sharpThumbAngle )
{
gp.lineTo ( thumbRect.x + thumbRect.width, thumbRect.y + thumbRect.height / 2 );
gp.lineTo ( thumbRect.x + thumbRect.width - thumbAngleLength, thumbRect.y + thumbRect.height );
}
else
{
gp.quadTo ( thumbRect.x + thumbRect.width - thumbAngleLength / 2, thumbRect.y, thumbRect.x + thumbRect.width,
thumbRect.y + thumbRect.height / 2 );
gp.quadTo ( thumbRect.x + thumbRect.width - thumbAngleLength / 2, thumbRect.y + thumbRect.height,
thumbRect.x + thumbRect.width - thumbAngleLength, thumbRect.y + thumbRect.height );
}
gp.lineTo ( thumbRect.x + thumbRound, thumbRect.y + thumbRect.height );
gp.quadTo ( thumbRect.x, thumbRect.y + thumbRect.height, thumbRect.x, thumbRect.y + thumbRect.height - thumbRound );
}
else
{
gp.moveTo ( thumbRect.x + thumbRect.width - thumbRound, thumbRect.y );
gp.quadTo ( thumbRect.x + thumbRect.width, thumbRect.y, thumbRect.x + thumbRect.width, thumbRect.y + thumbRound );
gp.lineTo ( thumbRect.x + thumbRect.width, thumbRect.y + thumbRect.height - thumbRound );
gp.quadTo ( thumbRect.x + thumbRect.width, thumbRect.y + thumbRect.height, thumbRect.x + thumbRect.width - thumbRound,
thumbRect.y + thumbRect.height );
gp.lineTo ( thumbRect.x + thumbAngleLength, thumbRect.y + thumbRect.height );
if ( sharpThumbAngle )
{
gp.lineTo ( thumbRect.x, thumbRect.y + thumbRect.height / 2 );
gp.lineTo ( thumbRect.x + thumbAngleLength, thumbRect.y );
}
else
{
gp.quadTo ( thumbRect.x + thumbAngleLength / 2, thumbRect.y + thumbRect.height, thumbRect.x,
thumbRect.y + thumbRect.height / 2 );
gp.quadTo ( thumbRect.x + thumbAngleLength / 2, thumbRect.y, thumbRect.x + thumbAngleLength, thumbRect.y );
}
}
gp.closePath ();
return gp;
}
}
else
{
return new RoundRectangle2D.Double ( thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height, thumbRound * 2,
thumbRound * 2 );
}
}
@Override
public void paintTrack ( final Graphics g )
{
final Graphics2D g2d = ( Graphics2D ) g;
final Object aa = GraphicsUtils.setupAntialias ( g2d );
// Track shape
final Shape ss = getTrackShape ();
// Track background & shade
{
// Track shade
if ( slider.isEnabled () )
{
GraphicsUtils.drawShade ( g2d, ss, slider.isFocusOwner () ? StyleConstants.fieldFocusColor : StyleConstants.shadeColor,
trackShadeWidth );
}
// Track background
if ( slider.getOrientation () == JSlider.HORIZONTAL )
{
g2d.setPaint ( new GradientPaint ( 0, trackRect.y, trackBgTop, 0, trackRect.y + trackRect.height, trackBgBottom ) );
}
else
{
g2d.setPaint ( new GradientPaint ( trackRect.x, 0, trackBgTop, trackRect.x + trackRect.width, 0, trackBgBottom ) );
}
g2d.fill ( ss );
}
// Inner progress line
if ( drawProgress )
{
// Progress shape
final Shape ps = getProgressShape ();
// Progress shade
if ( slider.isEnabled () )
{
GraphicsUtils.drawShade ( g2d, ps, StyleConstants.shadeColor, progressShadeWidth );
}
// Progress background
final Rectangle bounds = ss.getBounds ();
if ( slider.getOrientation () == JSlider.HORIZONTAL )
{
g2d.setPaint (
new GradientPaint ( 0, bounds.y + progressShadeWidth, Color.WHITE, 0, bounds.y + bounds.height - progressShadeWidth,
new Color ( 223, 223, 223 ) )
);
}
else
{
g2d.setPaint (
new GradientPaint ( bounds.x + progressShadeWidth, 0, Color.WHITE, bounds.x + bounds.width - progressShadeWidth, 0,
new Color ( 223, 223, 223 ) )
);
}
g2d.fill ( ps );
// Progress border
g2d.setPaint ( slider.isEnabled () ? StyleConstants.darkBorderColor : StyleConstants.disabledBorderColor );
g2d.draw ( ps );
}
// Track border & focus
{
// Track border
g2d.setPaint ( slider.isEnabled () ?
( rolloverDarkBorderOnly && !isDragging () ? getBorderColor () : StyleConstants.darkBorderColor ) :
StyleConstants.disabledBorderColor );
g2d.draw ( ss );
}
GraphicsUtils.restoreAntialias ( g2d, aa );
}
protected Shape getTrackShape ()
{
if ( trackRound > 0 )
{
if ( slider.getOrientation () == JSlider.HORIZONTAL )
{
return new RoundRectangle2D.Double ( trackRect.x - trackRound, trackRect.y + trackRect.height / 2 - trackHeight / 2,
trackRect.width + trackRound * 2 - 1, trackHeight, trackRound * 2, trackRound * 2 );
}
else
{
return new RoundRectangle2D.Double ( trackRect.x + trackRect.width / 2 - trackHeight / 2, trackRect.y - trackRound,
trackHeight, trackRect.height + trackRound * 2 - 1, trackRound * 2, trackRound * 2 );
}
}
else
{
if ( slider.getOrientation () == JSlider.HORIZONTAL )
{
return new Rectangle2D.Double ( trackRect.x, trackRect.y + trackRect.height / 2 - trackHeight / 2, trackRect.width - 1,
trackHeight );
}
else
{
return new Rectangle2D.Double ( trackRect.x + trackRect.width / 2 - trackHeight / 2, trackRect.y, trackHeight,
trackRect.height - 1 );
}
}
}
protected Shape getProgressShape ()
{
if ( trackRound > 0 )
{
if ( slider.getOrientation () == JSlider.HORIZONTAL )
{
final int x;
final int w;
if ( slider.getComponentOrientation ().isLeftToRight () )
{
x = trackRect.x - trackRound + progressShadeWidth;
w = thumbRect.x + thumbRect.width / 2 + progressRound - x;
}
else
{
x = thumbRect.x + thumbRect.width / 2 - progressRound;
w = trackRect.x + trackRect.width + trackRound -
progressShadeWidth - 1 - x;
}
return new RoundRectangle2D.Double ( x, trackRect.y + trackRect.height / 2 - trackHeight / 2 + progressShadeWidth, w,
trackHeight - progressShadeWidth * 2, progressRound * 2, progressRound * 2 );
}
else
{
final int y = thumbRect.y + thumbRect.height / 2;
final int h = trackRect.y + trackRect.height + trackRound - progressShadeWidth - y - 1;
return new RoundRectangle2D.Double ( trackRect.x + progressShadeWidth + trackRect.width / 2 - trackHeight / 2, y,
trackHeight - progressShadeWidth * 2, h, progressRound * 2, progressRound * 2 );
}
}
else
{
if ( slider.getOrientation () == JSlider.HORIZONTAL )
{
final int x;
final int w;
if ( slider.getComponentOrientation ().isLeftToRight () )
{
x = trackRect.x + progressShadeWidth;
w = thumbRect.x + thumbRect.width / 2 - x;
}
else
{
x = thumbRect.x + thumbRect.width / 2;
w = trackRect.x + trackRect.width - progressShadeWidth - 1 - x;
}
return new Rectangle2D.Double ( x, trackRect.y + trackRect.height / 2 - trackHeight / 2 + progressShadeWidth, w,
trackHeight - progressShadeWidth * 2 );
}
else
{
final int y = trackRect.y + progressShadeWidth;
final int h = thumbRect.y + thumbRect.height / 2 - y;
return new Rectangle2D.Double ( trackRect.x + progressShadeWidth + trackRect.width / 2 - trackHeight / 2, y,
trackHeight - progressShadeWidth * 2, h );
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy