All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jdesktop.swingx.JXMultiThumbSlider Maven / Gradle / Ivy

There is a newer version: 1.7.2
Show newest version
/*
 * $Id: JXMultiThumbSlider.java 4147 2012-02-01 17:13:24Z kschaefe $
 *
 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

package org.jdesktop.swingx;

import org.jdesktop.beans.JavaBean;
import org.jdesktop.swingx.multislider.DefaultMultiThumbModel;
import org.jdesktop.swingx.multislider.MultiThumbModel;
import org.jdesktop.swingx.multislider.ThumbDataEvent;
import org.jdesktop.swingx.multislider.ThumbDataListener;
import org.jdesktop.swingx.multislider.ThumbListener;
import org.jdesktop.swingx.multislider.ThumbRenderer;
import org.jdesktop.swingx.multislider.TrackRenderer;
import org.jdesktop.swingx.plaf.LookAndFeelAddons;
import org.jdesktop.swingx.plaf.MultiThumbSliderAddon;
import org.jdesktop.swingx.plaf.MultiThumbSliderUI;

import javax.swing.JComponent;
import javax.swing.event.MouseInputAdapter;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

/**
 * 

A slider which can have multiple control points or Thumbs

*

The thumbs each represent a value between the minimum and maximum values * of the slider. Thumbs can pass each other when being dragged. Thumbs have * no default visual representation. To customize the look of the thumbs and the * track behind the thumbs you must provide a ThumbRenderer and a TrackRenderer * implementation. To listen for changes to the thumbs you must provide an * implementation of ThumbDataListener. *

* TODOs: * add min/maxvalue convenience methods to jxmultithumbslider * add plafs for windows, mac, and basic (if necessary) * make way to properly control the height. * hide the inner thumb component * * @author joshy */ @JavaBean public class JXMultiThumbSlider extends JComponent { public static final String uiClassID = "MultiThumbSliderUI"; private final ThumbDataListener tdl; private final List thumbs; private ThumbRenderer thumbRenderer; private TrackRenderer trackRenderer; private MultiThumbModel model; private final List listeners = new ArrayList<>(); private ThumbComp selected; static { LookAndFeelAddons.contribute(new MultiThumbSliderAddon()); } /** * Creates a new instance of JMultiThumbSlider */ public JXMultiThumbSlider() { thumbs = new ArrayList<>(); setLayout(null); tdl = new ThumbHandler(); setModel(new DefaultMultiThumbModel<>()); MultiThumbMouseListener mia = new MultiThumbMouseListener(); addMouseListener(mia); addMouseMotionListener(mia); Dimension dim = new Dimension(60, 16); setPreferredSize(dim); setSize(dim); setMinimumSize(new Dimension(30, 16)); updateUI(); } /** * {@inheritDoc} */ @Override public String getUIClassID() { return uiClassID; } public MultiThumbSliderUI getUI() { return (MultiThumbSliderUI) ui; } public void setUI(MultiThumbSliderUI ui) { super.setUI(ui); } @Override public void updateUI() { setUI((MultiThumbSliderUI) LookAndFeelAddons.getUI(this, MultiThumbSliderUI.class)); invalidate(); } @Override protected void paintComponent(Graphics g) { if (isVisible()) { if (trackRenderer != null) { JComponent comp = trackRenderer.getRendererComponent(this); add(comp); comp.paint(g); remove(comp); } else { paintRange((Graphics2D) g); } } } private void paintRange(Graphics2D g) { g.setColor(Color.blue); g.fillRect(0, 0, getWidth(), getHeight()); } private float getThumbValue(int thumbIndex) { return getModel().getThumbAt(thumbIndex).getPosition(); } private float getThumbValue(ThumbComp thumb) { return getThumbValue(thumbs.indexOf(thumb)); } private int getThumbIndex(ThumbComp thumb) { return thumbs.indexOf(thumb); } private void clipThumbPosition(ThumbComp thumb) { if (getThumbValue(thumb) < getModel().getMinimumValue()) { getModel().getThumbAt(getThumbIndex(thumb)).setPosition(getModel().getMinimumValue()); } if (getThumbValue(thumb) > getModel().getMaximumValue()) { getModel().getThumbAt(getThumbIndex(thumb)).setPosition(getModel().getMaximumValue()); } } public ThumbRenderer getThumbRenderer() { return thumbRenderer; } public void setThumbRenderer(ThumbRenderer thumbRenderer) { this.thumbRenderer = thumbRenderer; } public TrackRenderer getTrackRenderer() { return trackRenderer; } public void setTrackRenderer(TrackRenderer trackRenderer) { this.trackRenderer = trackRenderer; } public float getMinimumValue() { return getModel().getMinimumValue(); } public void setMinimumValue(float minimumValue) { getModel().setMinimumValue(minimumValue); } public float getMaximumValue() { return getModel().getMaximumValue(); } public void setMaximumValue(float maximumValue) { getModel().setMaximumValue(maximumValue); } private void setThumbPositionByX(ThumbComp selected) { float range = getModel().getMaximumValue() - getModel().getMinimumValue(); int x = selected.getX(); // adjust to the center of the thumb x += selected.getWidth() / 2; // adjust for the leading space on the slider x -= selected.getWidth() / 2; int w = getWidth(); // adjust for the leading and trailing space on the slider w -= selected.getWidth(); float delta = (float) x / (float) w; int thumbIndex = getThumbIndex(selected); float value = delta * range; getModel().getThumbAt(thumbIndex).setPosition(value); clipThumbPosition(selected); } private void setThumbXByPosition(ThumbComp thumb, float pos) { float lp = getWidth() - thumb.getWidth(); float lu = getModel().getMaximumValue() - getModel().getMinimumValue(); float tp = pos * lp / lu; thumb.setLocation((int) tp - thumb.getWidth() / 2 + thumb.getWidth() / 2, thumb.getY()); } private void recalc() { for (ThumbComp th : thumbs) { setThumbXByPosition(th, getModel().getThumbAt(getThumbIndex(th)).getPosition()); //getPositionAt(getThumbIndex(th))); } } @Override public void setBounds(int x, int y, int w, int h) { super.setBounds(x, y, w, h); recalc(); } public JComponent getSelectedThumb() { return selected; } public int getSelectedIndex() { return getThumbIndex(selected); } public MultiThumbModel getModel() { return model; } public void setModel(MultiThumbModel model) { if (this.model != null) { this.model.removeThumbDataListener(tdl); } this.model = model; this.model.addThumbDataListener(tdl); } public void addMultiThumbListener(ThumbListener listener) { listeners.add(listener); } private class MultiThumbMouseListener extends MouseInputAdapter { @Override public void mousePressed(MouseEvent evt) { ThumbComp handle = findHandle(evt); if (handle != null) { selected = handle; selected.setSelected(true); int thumbIndex = getThumbIndex(selected); for (ThumbListener tl : listeners) { tl.thumbSelected(thumbIndex); } repaint(); } else { selected = null; for (ThumbListener tl : listeners) { tl.thumbSelected(-1); } repaint(); } for (ThumbListener tl : listeners) { tl.mousePressed(evt); } } @Override public void mouseReleased(MouseEvent evt) { if (selected != null) { selected.setSelected(false); } } @Override public void mouseDragged(MouseEvent evt) { if (selected != null) { int nx = (int) evt.getPoint().getX() - selected.getWidth() / 2; if (nx < 0) { nx = 0; } if (nx > getWidth() - selected.getWidth()) { nx = getWidth() - selected.getWidth(); } selected.setLocation(nx, (int) selected.getLocation().getY()); setThumbPositionByX(selected); int thumbIndex = getThumbIndex(selected); for (ThumbListener mtl : listeners) { mtl.thumbMoved(thumbIndex, getModel().getThumbAt(thumbIndex).getPosition()); } repaint(); } } private ThumbComp findHandle(MouseEvent evt) { for (ThumbComp hand : thumbs) { Point p2 = new Point(); p2.setLocation(evt.getPoint().getX() - hand.getX(), evt.getPoint().getY() - hand.getY()); if (hand.contains(p2)) { return hand; } } return null; } } private static class ThumbComp extends JComponent { private final JXMultiThumbSlider slider; ThumbComp(JXMultiThumbSlider slider) { this.slider = slider; Dimension dim = new Dimension(10, 10);//slider.getHeight()); setSize(dim); setMinimumSize(dim); setPreferredSize(dim); setMaximumSize(dim); setBackground(Color.white); } @Override public void paintComponent(Graphics g) { if (slider.getThumbRenderer() != null) { JComponent comp = getRenderer(); comp.setSize(this.getSize()); comp.paint(g); } else { g.setColor(getBackground()); g.fillRect(0, 0, getWidth(), getHeight()); if (isSelected()) { g.setColor(Color.black); g.drawRect(0, 0, getWidth() - 1, getHeight() - 1); } } } private JComponent getRenderer() { return slider.getThumbRenderer().getThumbRendererComponent(slider, slider.getThumbIndex(this), isSelected()); } private boolean selected; public boolean isSelected() { return selected; } public void setSelected(boolean selected) { this.selected = selected; } } private class ThumbHandler implements ThumbDataListener { @Override public void positionChanged(ThumbDataEvent e) { ThumbComp comp = thumbs.get(e.getIndex()); clipThumbPosition(comp); setThumbXByPosition(comp, e.getThumb().getPosition()); repaint(); } @Override public void thumbAdded(ThumbDataEvent evt) { ThumbComp thumb = new ThumbComp(JXMultiThumbSlider.this); thumb.setLocation(0, 0); add(thumb); thumbs.add(evt.getIndex(), thumb); clipThumbPosition(thumb); setThumbXByPosition(thumb, evt.getThumb().getPosition()); repaint(); } @Override public void thumbRemoved(ThumbDataEvent evt) { ThumbComp thumb = thumbs.get(evt.getIndex()); remove(thumb); thumbs.remove(thumb); repaint(); } @Override public void valueChanged(ThumbDataEvent e) { repaint(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy