import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.Ellipse2D; import javax.swing.JComponent; import javax.swing.JSlider; import javax.swing.SwingConstants; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicSliderUI; public class CustomSliderUI extends BasicSliderUI { private final BasicStroke stroke = new BasicStroke(2f); private JSlider slider; public CustomSliderUI(JSlider b) { super(b); this.slider = b; } public static ComponentUI createUI(JComponent c) { return new CustomSliderUI((JSlider)c); } @Override protected void calculateThumbSize() { super.calculateThumbSize(); thumbRect.setSize(thumbRect.width, thumbRect.height); } /** Creates a listener to handle track events in the specified slider.*/ @Override protected TrackListener createTrackListener(JSlider slider) { return new TrackListener(); } @Override protected void calculateThumbLocation() { // Call superclass method for lower thumb location. super.calculateThumbLocation(); // Adjust upper value to snap to ticks if necessary. if (slider.getSnapToTicks()) { int upperValue = slider.getValue() + slider.getExtent(); int snappedValue = upperValue; 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 ((upperValue - slider.getMinimum()) % tickSpacing != 0) { float temp = (float)(upperValue - slider.getMinimum()) / (float)tickSpacing; int whichTick = Math.round(temp); snappedValue = slider.getMinimum() + (whichTick * tickSpacing); } if (snappedValue != upperValue) { slider.setExtent(snappedValue - slider.getValue()); } } } // Calculate upper thumb location. The thumb is centered over its // value on the track. if (slider.getOrientation() == JSlider.HORIZONTAL) { int upperPosition = xPositionForValue(slider.getValue() + slider.getExtent()); thumbRect.x = upperPosition - (thumbRect.width / 2); thumbRect.y = trackRect.y; } else { int upperPosition = yPositionForValue(slider.getValue() + slider.getExtent()); thumbRect.x = trackRect.x; thumbRect.y = upperPosition - (thumbRect.height / 2); } slider.repaint(); } /** Returns the size of a thumb. * Parent method not use size from LaF * @return size of trumb */ @Override protected Dimension getThumbSize() { return new Dimension(5, 10); } private Shape createThumbShape(int width, int height) { Ellipse2D shape = new Ellipse2D.Double(0, 0, width, height); return shape; } @Override public void paintTrack(Graphics g) { Graphics2D g2d = (Graphics2D) g; Stroke old = g2d.getStroke(); g2d.setStroke(stroke); g2d.setPaint(slider.isEnabled() ? Color.LIGHT_GRAY : Color.WHITE); Color oldColor = slider.isEnabled() ? Color.LIGHT_GRAY : Color.WHITE; Rectangle trackBounds = trackRect; if (slider.getOrientation() == SwingConstants.HORIZONTAL) { g2d.drawLine(trackRect.x, trackRect.y + trackRect.height / 2, trackRect.x + trackRect.width, trackRect.y + trackRect.height / 2); int lowerX = thumbRect.width / 2; int upperX = thumbRect.x + (thumbRect.width / 2); int cy = (trackBounds.height / 2) - 2; g2d.translate(trackBounds.x, trackBounds.y + cy); g2d.setColor(slider.isEnabled() ? Color.BLACK : Color.LIGHT_GRAY); g2d.drawLine(lowerX - trackBounds.x, 2, upperX - trackBounds.x, 2); g2d.translate(-trackBounds.x, -(trackBounds.y + cy)); g2d.setColor(oldColor); } g2d.setStroke(old); } /** Overrides superclass method to do nothing. Thumb painting is handled * within the paint() method.*/ @Override public void paintThumb(Graphics g) { Rectangle knobBounds = thumbRect; int w = knobBounds.width; int h = knobBounds.height; Graphics2D g2d = (Graphics2D) g.create(); Shape thumbShape = createThumbShape(w - 1, h - 1); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.translate(knobBounds.x, knobBounds.y); g2d.setColor(slider.isEnabled() ? Color.LIGHT_GRAY : Color.WHITE); g2d.fill(thumbShape); g2d.setColor(slider.isEnabled() ? Color.BLACK : Color.LIGHT_GRAY); g2d.draw(thumbShape); g2d.dispose(); } }