Thumb Slider Example : Slider « Swing Components « Java

Java
1. 2D Graphics GUI
2. 3D
3. Advanced Graphics
4. Ant
5. Apache Common
6. Chart
7. Collections Data Structure
8. Database SQL JDBC
9. Design Pattern
10. Development Class
11. Email
12. Event
13. File Input Output
14. Game
15. Hibernate
16. J2EE
17. J2ME
18. JDK 6
19. JSP
20. JSTL
21. Language Basics
22. Network Protocol
23. PDF RTF
24. Regular Expressions
25. Security
26. Servlets
27. Spring
28. Swing Components
29. Swing JFC
30. SWT JFace Eclipse
31. Threads
32. Tiny Application
33. Velocity
34. Web Services SOA
35. XML
Microsoft Office Word 2007 Tutorial
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Java » Swing Components » SliderScreenshots 
Thumb Slider Example
Thumb Slider Example

// Example from http://www.crionics.com/products/opensource/faq/swing_ex/SwingExamples.html
/* (swing1.1.1) */


import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BoundedRangeModel;
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.MouseInputAdapter;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicSliderUI;
import javax.swing.plaf.basic.BasicSliderUI.TrackListener;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.metal.MetalSliderUI;

/**
 @version 1.0 9/3/99
 */
public class MThumbSliderExample extends JFrame {
  public MThumbSliderExample() {
    super("MThumbSlider Example");

    JSlider slider = new JSlider();
    slider.putClientProperty("JSlider.isFilled", Boolean.TRUE);

    int n = 2;
    MThumbSlider mSlider = new MThumbSlider(n);
    mSlider.setValueAt(250);
    mSlider.setValueAt(751);
    mSlider.setFillColorAt(Color.green, 0);
    mSlider.setFillColorAt(Color.yellow, 1);
    mSlider.setTrackFillColor(Color.red);
    mSlider.putClientProperty("JSlider.isFilled", Boolean.TRUE);

    getContentPane().setLayout(new FlowLayout());
    getContentPane().add(slider);
    getContentPane().add(mSlider);
  }

  public static void main(String args[]) {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    catch (Exception evt) {}
  
    MThumbSliderExample f = new MThumbSliderExample();
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    f.setSize(30080);
    f.show();
  }
}

class MThumbSlider extends JSlider {
  protected int thumbNum;

  protected BoundedRangeModel[] sliderModels;

  protected Icon[] thumbRenderers;

  protected Color[] fillColors;

  protected Color trackFillColor;

  private static final String uiClassID = "MThumbSliderUI";

  public MThumbSlider(int n) {
    createThumbs(n);
    updateUI();
  }

  protected void createThumbs(int n) {
    thumbNum = n;
    sliderModels = new BoundedRangeModel[n];
    thumbRenderers = new Icon[n];
    fillColors = new Color[n];
    for (int i = 0; i < n; i++) {
      sliderModels[inew DefaultBoundedRangeModel(5000100);
      thumbRenderers[inull;
      fillColors[inull;
    }
  }

  public void updateUI() {
    AssistantUIManager.setUIName(this);
    super.updateUI();

    /*
     * // another way // updateLabelUIs();
     * setUI(AssistantUIManager.createUI(this)); //setUI(new
     * BasicMThumbSliderUI(this)); //setUI(new MetalMThumbSliderUI(this));
     * //setUI(new MotifMThumbSliderUI(this));
     */
  }

  public String getUIClassID() {
    return uiClassID;
  }

  public int getThumbNum() {
    return thumbNum;
  }

  public int getValueAt(int index) {
    return getModelAt(index).getValue();
  }

  public void setValueAt(int n, int index) {
    getModelAt(index).setValue(n);
    // should I fire?
  }

  public int getMinimum() {
    return getModelAt(0).getMinimum();
  }

  public int getMaximum() {
    return getModelAt(0).getMaximum();
  }

  public BoundedRangeModel getModelAt(int index) {
    return sliderModels[index];
  }

  public Icon getThumbRendererAt(int index) {
    return thumbRenderers[index];
  }

  public void setThumbRendererAt(Icon icon, int index) {
    thumbRenderers[index= icon;
  }

  public Color getFillColorAt(int index) {
    return fillColors[index];
  }

  public void setFillColorAt(Color color, int index) {
    fillColors[index= color;
  }

  public Color getTrackFillColor() {
    return trackFillColor;
  }

  public void setTrackFillColor(Color color) {
    trackFillColor = color;
  }
}

class MetalMThumbSliderUI extends MetalSliderUI implements
    MThumbSliderAdditional {

  MThumbSliderAdditionalUI additonalUi;

  MouseInputAdapter mThumbTrackListener;

  public static ComponentUI createUI(JComponent c) {
    return new MetalMThumbSliderUI((JSliderc);
  }

  public MetalMThumbSliderUI() {
    //super(null);
  }

  public MetalMThumbSliderUI(JSlider b) {
    //super(null);
  }

  public void installUI(JComponent c) {
    additonalUi = new MThumbSliderAdditionalUI(this);
    additonalUi.installUI(c);
    mThumbTrackListener = createMThumbTrackListener((JSliderc);
    super.installUI(c);
  }

  public void uninstallUI(JComponent c) {
    super.uninstallUI(c);
    additonalUi.uninstallUI(c);
    additonalUi = null;
    mThumbTrackListener = null;
  }

  protected MouseInputAdapter createMThumbTrackListener(JSlider slider) {
    return additonalUi.trackListener;
  }

  protected TrackListener createTrackListener(JSlider slider) {
    return null;
  }

  protected ChangeListener createChangeListener(JSlider slider) {
    return additonalUi.changeHandler;
  }

  protected void installListeners(JSlider slider) {
    slider.addMouseListener(mThumbTrackListener);
    slider.addMouseMotionListener(mThumbTrackListener);
    slider.addFocusListener(focusListener);
    slider.addComponentListener(componentListener);
    slider.addPropertyChangeListener(propertyChangeListener);
    slider.getModel().addChangeListener(changeListener);
  }

  protected void uninstallListeners(JSlider slider) {
    slider.removeMouseListener(mThumbTrackListener);
    slider.removeMouseMotionListener(mThumbTrackListener);
    slider.removeFocusListener(focusListener);
    slider.removeComponentListener(componentListener);
    slider.removePropertyChangeListener(propertyChangeListener);
    slider.getModel().removeChangeListener(changeListener);
  }

  protected void calculateGeometry() {
    super.calculateGeometry();
    additonalUi.calculateThumbsSize();
    additonalUi.calculateThumbsLocation();
  }

  protected void calculateThumbLocation() {
  }

  Icon thumbRenderer;

  public void paint(Graphics g, JComponent c) {
    Rectangle clip = g.getClipBounds();
    Rectangle[] thumbRects = additonalUi.getThumbRects();
    thumbRect = thumbRects[0];
    int thumbNum = additonalUi.getThumbNum();

    if (slider.getPaintTrack() && clip.intersects(trackRect)) {
      boolean filledSlider_tmp = filledSlider;
      filledSlider = false;
      paintTrack(g);
      filledSlider = filledSlider_tmp;

      if (filledSlider) {
        g.translate(trackRect.x, trackRect.y);

        Point t1 = new Point(00);
        Point t2 = new Point(00);
        Rectangle maxThumbRect = new Rectangle(thumbRect);
        thumbRect = maxThumbRect;

        if (slider.getOrientation() == JSlider.HORIZONTAL) {
          t2.y = (trackRect.height - 1- getThumbOverhang();
          t1.y = t2.y - (getTrackWidth() 1);
          t2.x = trackRect.width - 1;
          int maxPosition = xPositionForValue(slider.getMaximum());
          thumbRect.x = maxPosition - (thumbRect.width / 22;
          thumbRect.y = trackRect.y;
        else {
          t1.x = (trackRect.width - getThumbOverhang())
              - getTrackWidth();
          t2.x = (trackRect.width - getThumbOverhang()) 1;
          t2.y = trackRect.height - 1;
          int maxPosition = yPositionForValue(slider.getMaximum());
          thumbRect.x = trackRect.x;
          thumbRect.y = maxPosition - (thumbRect.height / 22;
        }

        Color fillColor = ((MThumbSliderslider).getTrackFillColor();
        if (fillColor == null) {
          fillColor = MetalLookAndFeel.getControlShadow();
        }
        fillTrack(g, t1, t2, fillColor);

        for (int i = thumbNum - 1<= i; i--) {
          thumbRect = thumbRects[i];
          fillColor = ((MThumbSliderslider).getFillColorAt(i);
          if (fillColor == null) {
            fillColor = MetalLookAndFeel.getControlShadow();
          }
          fillTrack(g, t1, t2, fillColor);
        }

        g.translate(-trackRect.x, -trackRect.y);
      }
    }
    if (slider.getPaintTicks() && clip.intersects(tickRect)) {
      paintTicks(g);
    }
    if (slider.getPaintLabels() && clip.intersects(labelRect)) {
      paintLabels(g);
    }

    for (int i = thumbNum - 1<= i; i--) {
      if (clip.intersects(thumbRects[i])) {
        thumbRect = thumbRects[i];
        thumbRenderer = ((MThumbSliderslider).getThumbRendererAt(i);
        if (thumbRenderer == null) {
          if (slider.getOrientation() == JSlider.HORIZONTAL) {
            thumbRenderer = horizThumbIcon;
          else {
            thumbRenderer = vertThumbIcon;
          }
        }
        paintThumb(g);
      }
    }
  }

  public void paintThumb(Graphics g) {
    thumbRenderer.paintIcon(slider, g, thumbRect.x, thumbRect.y);
  }

  public void fillTrack(Graphics g, Point t1, Point t2, Color fillColor) {
    //                               t1-------------------
    //                               | |
    //                               --------------------t2
    int middleOfThumb = 0;

    if (slider.getOrientation() == JSlider.HORIZONTAL) {
      middleOfThumb = thumbRect.x + (thumbRect.width / 2- trackRect.x;
      if (slider.isEnabled()) {
        g.setColor(fillColor);
        g.fillRect(t1.x + 2, t1.y + 2, middleOfThumb - t1.x - 1, t2.y
            - t1.y - 3);
        g.setColor(fillColor.brighter());
        g.drawLine(t1.x + 1, t1.y + 1, middleOfThumb, t1.y + 1);
        g.drawLine(t1.x + 1, t1.y + 1, t1.x + 1, t2.y - 2);
      else {
        g.setColor(fillColor);
        g.fillRect(t1.x, t1.y, middleOfThumb - t1.x + 2, t2.y - t1.y);
      }
    else {
      middleOfThumb = thumbRect.y + (thumbRect.height / 2- trackRect.y;
      if (slider.isEnabled()) {
        g.setColor(slider.getBackground());
        g.drawLine(t1.x + 1, middleOfThumb, t2.x - 2, middleOfThumb);
        g.drawLine(t1.x + 1, middleOfThumb, t1.x + 1, t2.y - 2);
        g.setColor(fillColor);
        g.fillRect(t1.x + 2, middleOfThumb + 1, t2.x - t1.x - 3, t2.y
            - middleOfThumb);
      else {
        g.setColor(fillColor);
        g.fillRect(t1.x, middleOfThumb + 2, t2.x - - t1.x, t2.y
            - t1.y);
      }
    }
  }

  public void scrollByBlock(int direction) {
  }

  public void scrollByUnit(int direction) {
  }

  //  
  //  MThumbSliderAdditional
  //
  public Rectangle getTrackRect() {
    return trackRect;
  }

  public Dimension getThumbSize() {
    return super.getThumbSize();
  }

  public int xPositionForValue(int value) {
    return super.xPositionForValue(value);
  }

  public int yPositionForValue(int value) {
    return super.yPositionForValue(value);
  }

}

interface MThumbSliderAdditional {

  public Rectangle getTrackRect();

  public Dimension getThumbSize();

  public int xPositionForValue(int value);

  public int yPositionForValue(int value);

}

class MThumbSliderAdditionalUI {

  MThumbSlider mSlider;

  BasicSliderUI ui;

  Rectangle[] thumbRects;

  int thumbNum;

  private transient boolean isDragging;

  Icon thumbRenderer;

  Rectangle trackRect;

  ChangeHandler changeHandler;

  TrackListener trackListener;

  public MThumbSliderAdditionalUI(BasicSliderUI ui) {
    this.ui = ui;
  }

  public void installUI(JComponent c) {
    mSlider = (MThumbSliderc;
    thumbNum = mSlider.getThumbNum();
    thumbRects = new Rectangle[thumbNum];
    for (int i = 0; i < thumbNum; i++) {
      thumbRects[inew Rectangle();
    }
    isDragging = false;
    trackListener = new MThumbSliderAdditionalUI.TrackListener(mSlider);
    changeHandler = new ChangeHandler();
  }

  public void uninstallUI(JComponent c) {
    thumbRects = null;
    trackListener = null;
    changeHandler = null;
  }

  protected void calculateThumbsSize() {
    Dimension size = ((MThumbSliderAdditionalui).getThumbSize();
    for (int i = 0; i < thumbNum; i++) {
      thumbRects[i].setSize(size.width, size.height);
    }
  }

  protected void calculateThumbsLocation() {
    for (int i = 0; i < thumbNum; i++) {
      if (mSlider.getSnapToTicks()) {
        int tickSpacing = mSlider.getMinorTickSpacing();
        if (tickSpacing == 0) {
          tickSpacing = mSlider.getMajorTickSpacing();
        }
        if (tickSpacing != 0) {
          int sliderValue = mSlider.getValueAt(i);
          int snappedValue = sliderValue;
          //int min = mSlider.getMinimumAt(i);
          int min = mSlider.getMinimum();
          if ((sliderValue - min% tickSpacing != 0) {
            float temp = (float) (sliderValue - min)
                (floattickSpacing;
            int whichTick = Math.round(temp);
            snappedValue = min + (whichTick * tickSpacing);
            mSlider.setValueAt(snappedValue, i);
          }
        }
      }
      trackRect = getTrackRect();
      if (mSlider.getOrientation() == JSlider.HORIZONTAL) {
        int value = mSlider.getValueAt(i);
        int valuePosition = ((MThumbSliderAdditionalui)
            .xPositionForValue(value);
        thumbRects[i].x = valuePosition - (thumbRects[i].width / 2);
        thumbRects[i].y = trackRect.y;

      else {
        int valuePosition = ((MThumbSliderAdditionalui)
            .yPositionForValue(mSlider.getValueAt(i))// need
        thumbRects[i].x = trackRect.x;
        thumbRects[i].y = valuePosition - (thumbRects[i].height / 2);
      }
    }
  }

  public int getThumbNum() {
    return thumbNum;
  }

  public Rectangle[] getThumbRects() {
    return thumbRects;
  }

  private static Rectangle unionRect = new Rectangle();

  public void setThumbLocationAt(int x, int y, int index) {
    Rectangle rect = thumbRects[index];
    unionRect.setBounds(rect);

    rect.setLocation(x, y);
    SwingUtilities.computeUnion(rect.x, rect.y, rect.width, rect.height,
        unionRect);
    mSlider.repaint(unionRect.x, unionRect.y, unionRect.width,
        unionRect.height);
  }

  public Rectangle getTrackRect() {
    return ((MThumbSliderAdditionalui).getTrackRect();
  }

  public class ChangeHandler implements ChangeListener {
    public void stateChanged(ChangeEvent e) {
      if (!isDragging) {
        calculateThumbsLocation();
        mSlider.repaint();
      }
    }
  }

  public class TrackListener extends MouseInputAdapter {
    protected transient int offset;

    protected transient int currentMouseX, currentMouseY;

    protected Rectangle adjustingThumbRect = null;

    protected int adjustingThumbIndex;

    protected MThumbSlider slider;

    protected Rectangle trackRect;

    TrackListener(MThumbSlider slider) {
      this.slider = slider;
    }

    public void mousePressed(MouseEvent e) {
      if (!slider.isEnabled()) {
        return;
      }
      currentMouseX = e.getX();
      currentMouseY = e.getY();
      slider.requestFocus();

      for (int i = 0; i < thumbNum; i++) {
        Rectangle rect = thumbRects[i];
        if (rect.contains(currentMouseX, currentMouseY)) {

          switch (slider.getOrientation()) {
          case JSlider.VERTICAL:
            offset = currentMouseY - rect.y;
            break;
          case JSlider.HORIZONTAL:
            offset = currentMouseX - rect.x;
            break;
          }
          isDragging = true;
          slider.setValueIsAdjusting(true);
          adjustingThumbRect = rect;
          adjustingThumbIndex = i;
          return;
        }
      }
    }

    public void mouseDragged(MouseEvent e) {
      if (!slider.isEnabled() || !isDragging
          || !slider.getValueIsAdjusting()
          || adjustingThumbRect == null) {
        return;
      }
      int thumbMiddle = 0;
      currentMouseX = e.getX();
      currentMouseY = e.getY();

      Rectangle rect = thumbRects[adjustingThumbIndex];
      trackRect = getTrackRect();
      switch (slider.getOrientation()) {
      case JSlider.VERTICAL:
        int halfThumbHeight = rect.height / 2;
        int thumbTop = e.getY() - offset;
        int trackTop = trackRect.y;
        int trackBottom = trackRect.y + (trackRect.height - 1);

        thumbTop = Math.max(thumbTop, trackTop - halfThumbHeight);
        thumbTop = Math.min(thumbTop, trackBottom - halfThumbHeight);

        setThumbLocationAt(rect.x, thumbTop, adjustingThumbIndex);

        thumbMiddle = thumbTop + halfThumbHeight;
        mSlider.setValueAt(ui.valueForYPosition(thumbMiddle),
            adjustingThumbIndex);
        break;

      case JSlider.HORIZONTAL:
        int halfThumbWidth = rect.width / 2;
        int thumbLeft = e.getX() - offset;
        int trackLeft = trackRect.x;
        int trackRight = trackRect.x + (trackRect.width - 1);

        thumbLeft = Math.max(thumbLeft, trackLeft - halfThumbWidth);
        thumbLeft = Math.min(thumbLeft, trackRight - halfThumbWidth);

        setThumbLocationAt(thumbLeft, rect.y, adjustingThumbIndex);

        thumbMiddle = thumbLeft + halfThumbWidth;
        mSlider.setValueAt(ui.valueForXPosition(thumbMiddle),
            adjustingThumbIndex);
        break;
      }
    }

    public void mouseReleased(MouseEvent e) {
      if (!slider.isEnabled()) {
        return;
      }
      offset = 0;
      isDragging = false;
      mSlider.setValueIsAdjusting(false);
      mSlider.repaint();
    }

    public boolean shouldScroll(int direction) {
      return false;
    }

  }

}

class AssistantUIManager {

  public static ComponentUI createUI(JComponent c) {
    String componentName = c.getClass().getName();

    int index = componentName.lastIndexOf("."1;
    StringBuffer sb = new StringBuffer();
&nb