Java/Swing Components/Slider
Содержание
Slider With ToolTip Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html import java.util.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; /**
* @version 1.0 10/4/99 */
public class SliderWithToolTipExample extends JFrame {
public SliderWithToolTipExample() { super("Mad Level"); JSlider s = new JSlider(JSlider.VERTICAL, 0, 120, 60) { String[] tooltips = {"Call 911", "Seeing red", "Really mad", "Ticked off", "Slightly peeved", "Oh bother", "Feel good"}; public String getToolTipText(MouseEvent e) { Point p = e.getPoint(); Rectangle rect = new Rectangle(); rect = getBounds(rect); int n = getLabelTable().size(); int index = n * p.y / rect.height; return tooltips[index]; } }; s.setPaintTicks(true); s.setMajorTickSpacing(20); s.setPaintLabels( true ); s.putClientProperty( "JSlider.isFilled", Boolean.TRUE ); s.setToolTipText(""); getContentPane().setLayout(new FlowLayout()); getContentPane().add(s); } public static void main (String args[]) { SliderWithToolTipExample f = new SliderWithToolTipExample(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.setSize (120, 250); f.show(); }
}
</source>
Thumb Slider Example
<source lang="java">
// Example from http://www.crionics.ru/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.ruponentUI; 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(25, 0); mSlider.setValueAt(75, 1); 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(300, 80); 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[i] = new DefaultBoundedRangeModel(50, 0, 0, 100); thumbRenderers[i] = null; fillColors[i] = null; } } 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((JSlider) c); } public MetalMThumbSliderUI() { //super(null); } public MetalMThumbSliderUI(JSlider b) { //super(null); } public void installUI(JComponent c) { additonalUi = new MThumbSliderAdditionalUI(this); additonalUi.installUI(c); mThumbTrackListener = createMThumbTrackListener((JSlider) c); 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(0, 0); Point t2 = new Point(0, 0); 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 / 2) - 2; 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 / 2) - 2; } Color fillColor = ((MThumbSlider) slider).getTrackFillColor(); if (fillColor == null) { fillColor = MetalLookAndFeel.getControlShadow(); } fillTrack(g, t1, t2, fillColor); for (int i = thumbNum - 1; 0 <= i; i--) { thumbRect = thumbRects[i]; fillColor = ((MThumbSlider) slider).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; 0 <= i; i--) { if (clip.intersects(thumbRects[i])) { thumbRect = thumbRects[i]; thumbRenderer = ((MThumbSlider) slider).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 - 2 - middleOfThumb); } else { g.setColor(fillColor); g.fillRect(t1.x, middleOfThumb + 2, t2.x - 1 - 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 = (MThumbSlider) c; thumbNum = mSlider.getThumbNum(); thumbRects = new Rectangle[thumbNum]; for (int i = 0; i < thumbNum; i++) { thumbRects[i] = new 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 = ((MThumbSliderAdditional) ui).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) / (float) tickSpacing; 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 = ((MThumbSliderAdditional) ui) .xPositionForValue(value); thumbRects[i].x = valuePosition - (thumbRects[i].width / 2); thumbRects[i].y = trackRect.y; } else { int valuePosition = ((MThumbSliderAdditional) ui) .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.ruputeUnion(rect.x, rect.y, rect.width, rect.height, unionRect); mSlider.repaint(unionRect.x, unionRect.y, unionRect.width, unionRect.height); } public Rectangle getTrackRect() { return ((MThumbSliderAdditional) ui).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(); sb.append(componentName.substring(0, index)); // // UIManager.getLookAndFeel().getName() // // [ Metal ] [ Motif ] [ Mac ] [ Windows ] // Metal CDE/Motif Macintosh Windows // String lookAndFeelName = UIManager.getLookAndFeel().getName(); if (lookAndFeelName.startsWith("CDE/")) { lookAndFeelName = lookAndFeelName.substring(4, lookAndFeelName .length()); } sb.append(lookAndFeelName); sb.append(componentName.substring(index)); sb.append("UI"); ComponentUI componentUI = getInstance(sb.toString()); if (componentUI == null) { sb.setLength(0); sb.append(componentName.substring(0, index)); sb.append("Basic"); sb.append(componentName.substring(index)); sb.append("UI"); componentUI = getInstance(sb.toString()); } return componentUI; } private static ComponentUI getInstance(String name) { try { return (ComponentUI) Class.forName(name).newInstance(); } catch (ClassNotFoundException ex) { } catch (IllegalAccessException ex) { ex.printStackTrace(); } catch (InstantiationException ex) { ex.printStackTrace(); } return null; } public static void setUIName(JComponent c) { String key = c.getUIClassID(); String uiClassName = (String) UIManager.get(key); if (uiClassName == null) { String componentName = c.getClass().getName(); int index = componentName.lastIndexOf(".") + 1; StringBuffer sb = new StringBuffer(); sb.append(componentName.substring(0, index)); String lookAndFeelName = UIManager.getLookAndFeel().getName(); if (lookAndFeelName.startsWith("CDE/")) { lookAndFeelName = lookAndFeelName.substring(4, lookAndFeelName .length()); } sb.append(lookAndFeelName); sb.append(key); UIManager.put(key, sb.toString()); } } public AssistantUIManager() { }
}
</source>
Thumb Slider Example 1
<source lang="java">
// Example from http://www.crionics.ru/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.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.ruponentUI; import javax.swing.plaf.basic.BasicSliderUI; import com.sun.java.swing.plaf.motif.MotifSliderUI; /**
* @version 1.0 9/3/99 */
public class MThumbSliderExample1 extends JFrame {
public MThumbSliderExample1() { super("MThumbSlider Example"); JSlider slider = new JSlider(); int n = 2; MThumbSlider mSlider = new MThumbSlider(n); mSlider.setValueAt(25, 0); mSlider.setValueAt(75, 1); getContentPane().setLayout(new FlowLayout()); getContentPane().add(slider); getContentPane().add(mSlider); } public static void main(String args[]) { try { UIManager .setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); } catch (Exception ex) { System.err.println("Error loading L&F: " + ex); } MThumbSliderExample1 f = new MThumbSliderExample1(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.setSize(300, 80); 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[i] = new DefaultBoundedRangeModel(50, 0, 0, 100); thumbRenderers[i] = null; fillColors[i] = null; } } 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 MotifMThumbSliderUI extends MotifSliderUI implements
MThumbSliderAdditional { MThumbSliderAdditionalUI additonalUi; MouseInputAdapter mThumbTrackListener; public static ComponentUI createUI(JComponent c) { return new MotifMThumbSliderUI((JSlider) c); } public MotifMThumbSliderUI() { super(null); } public MotifMThumbSliderUI(JSlider b) { super(b); } public void installUI(JComponent c) { additonalUi = new MThumbSliderAdditionalUI(this); additonalUi.installUI(c); mThumbTrackListener = createMThumbTrackListener((JSlider) c); 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() { } Rectangle zeroRect = new Rectangle(); public void paint(Graphics g, JComponent c) { Rectangle clip = g.getClipBounds(); thumbRect = zeroRect; super.paint(g, c); int thumbNum = additonalUi.getThumbNum(); Rectangle[] thumbRects = additonalUi.getThumbRects(); for (int i = thumbNum - 1; 0 <= i; i--) { if (clip.intersects(thumbRects[i])) { thumbRect = thumbRects[i]; paintThumb(g); } } } protected void installKeyboardActions(JSlider slider) { } protected void uninstallKeyboardActions(JSlider slider) { } 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 = (MThumbSlider) c; thumbNum = mSlider.getThumbNum(); thumbRects = new Rectangle[thumbNum]; for (int i = 0; i < thumbNum; i++) { thumbRects[i] = new 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 = ((MThumbSliderAdditional) ui).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) / (float) tickSpacing; 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 = ((MThumbSliderAdditional) ui) .xPositionForValue(value); thumbRects[i].x = valuePosition - (thumbRects[i].width / 2); thumbRects[i].y = trackRect.y; } else { int valuePosition = ((MThumbSliderAdditional) ui) .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.ruputeUnion(rect.x, rect.y, rect.width, rect.height, unionRect); mSlider.repaint(unionRect.x, unionRect.y, unionRect.width, unionRect.height); } public Rectangle getTrackRect() { return ((MThumbSliderAdditional) ui).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(); sb.append(componentName.substring(0, index)); // // UIManager.getLookAndFeel().getName() // // [ Metal ] [ Motif ] [ Mac ] [ Windows ] // Metal CDE/Motif Macintosh Windows // String lookAndFeelName = UIManager.getLookAndFeel().getName(); if (lookAndFeelName.startsWith("CDE/")) { lookAndFeelName = lookAndFeelName.substring(4, lookAndFeelName .length()); } sb.append(lookAndFeelName); sb.append(componentName.substring(index)); sb.append("UI"); ComponentUI componentUI = getInstance(sb.toString()); if (componentUI == null) { sb.setLength(0); sb.append(componentName.substring(0, index)); sb.append("Basic"); sb.append(componentName.substring(index)); sb.append("UI"); componentUI = getInstance(sb.toString()); } return componentUI; } private static ComponentUI getInstance(String name) { try { return (ComponentUI) Class.forName(name).newInstance(); } catch (ClassNotFoundException ex) { } catch (IllegalAccessException ex) { ex.printStackTrace(); } catch (InstantiationException ex) { ex.printStackTrace(); } return null; } public static void setUIName(JComponent c) { String key = c.getUIClassID(); String uiClassName = (String) UIManager.get(key); if (uiClassName == null) { String componentName = c.getClass().getName(); int index = componentName.lastIndexOf(".") + 1; StringBuffer sb = new StringBuffer(); sb.append(componentName.substring(0, index)); String lookAndFeelName = UIManager.getLookAndFeel().getName(); if (lookAndFeelName.startsWith("CDE/")) { lookAndFeelName = lookAndFeelName.substring(4, lookAndFeelName .length()); } sb.append(lookAndFeelName); sb.append(key); UIManager.put(key, sb.toString()); } } public AssistantUIManager() { }
}
</source>
Thumb Slider Example 2
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; 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.ruponentUI; import javax.swing.plaf.basic.BasicSliderUI; /**
* @version 1.0 9/3/99 */
public class MThumbSliderExample2 extends JFrame {
public MThumbSliderExample2() { super("MThumbSlider Example"); JSlider slider = new JSlider(); slider.setUI(new javax.swing.plaf.basic.BasicSliderUI(slider)); int n = 2; MThumbSlider mSlider = new MThumbSlider(n); mSlider.setValueAt(25, 0); mSlider.setValueAt(75, 1); mSlider.setUI(new BasicMThumbSliderUI()); getContentPane().setLayout(new FlowLayout()); getContentPane().add(slider); getContentPane().add(mSlider); } public static void main(String args[]) { try { UIManager .setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); } catch (Exception ex) { System.err.println("Error loading L&F: " + ex); } MThumbSliderExample2 f = new MThumbSliderExample2(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.setSize(300, 100); 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[i] = new DefaultBoundedRangeModel(50, 0, 0, 100); thumbRenderers[i] = null; fillColors[i] = null; } } 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 BasicMThumbSliderUI extends BasicSliderUI implements
MThumbSliderAdditional { MThumbSliderAdditionalUI additonalUi; MouseInputAdapter mThumbTrackListener; public static ComponentUI createUI(JComponent c) { return new BasicMThumbSliderUI((JSlider) c); } public BasicMThumbSliderUI() { super(null); } public BasicMThumbSliderUI(JSlider b) { super(b); } public void installUI(JComponent c) { additonalUi = new MThumbSliderAdditionalUI(this); additonalUi.installUI(c); mThumbTrackListener = createMThumbTrackListener((JSlider) c); 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() { } Rectangle zeroRect = new Rectangle(); public void paint(Graphics g, JComponent c) { Rectangle clip = g.getClipBounds(); thumbRect = zeroRect; super.paint(g, c); int thumbNum = additonalUi.getThumbNum(); Rectangle[] thumbRects = additonalUi.getThumbRects(); for (int i = thumbNum - 1; 0 <= i; i--) { if (clip.intersects(thumbRects[i])) { thumbRect = thumbRects[i]; paintThumb(g); } } } 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 = (MThumbSlider) c; thumbNum = mSlider.getThumbNum(); thumbRects = new Rectangle[thumbNum]; for (int i = 0; i < thumbNum; i++) { thumbRects[i] = new 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 = ((MThumbSliderAdditional) ui).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) / (float) tickSpacing; 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 = ((MThumbSliderAdditional) ui) .xPositionForValue(value); thumbRects[i].x = valuePosition - (thumbRects[i].width / 2); thumbRects[i].y = trackRect.y; } else { int valuePosition = ((MThumbSliderAdditional) ui) .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.ruputeUnion(rect.x, rect.y, rect.width, rect.height, unionRect); mSlider.repaint(unionRect.x, unionRect.y, unionRect.width, unionRect.height); } public Rectangle getTrackRect() { return ((MThumbSliderAdditional) ui).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(); sb.append(componentName.substring(0, index)); // // UIManager.getLookAndFeel().getName() // // [ Metal ] [ Motif ] [ Mac ] [ Windows ] // Metal CDE/Motif Macintosh Windows // String lookAndFeelName = UIManager.getLookAndFeel().getName(); if (lookAndFeelName.startsWith("CDE/")) { lookAndFeelName = lookAndFeelName.substring(4, lookAndFeelName .length()); } sb.append(lookAndFeelName); sb.append(componentName.substring(index)); sb.append("UI"); ComponentUI componentUI = getInstance(sb.toString()); if (componentUI == null) { sb.setLength(0); sb.append(componentName.substring(0, index)); sb.append("Basic"); sb.append(componentName.substring(index)); sb.append("UI"); componentUI = getInstance(sb.toString()); } return componentUI; } private static ComponentUI getInstance(String name) { try { return (ComponentUI) Class.forName(name).newInstance(); } catch (ClassNotFoundException ex) { } catch (IllegalAccessException ex) { ex.printStackTrace(); } catch (InstantiationException ex) { ex.printStackTrace(); } return null; } public static void setUIName(JComponent c) { String key = c.getUIClassID(); String uiClassName = (String) UIManager.get(key); if (uiClassName == null) { String componentName = c.getClass().getName(); int index = componentName.lastIndexOf(".") + 1; StringBuffer sb = new StringBuffer(); sb.append(componentName.substring(0, index)); String lookAndFeelName = UIManager.getLookAndFeel().getName(); if (lookAndFeelName.startsWith("CDE/")) { lookAndFeelName = lookAndFeelName.substring(4, lookAndFeelName .length()); } sb.append(lookAndFeelName); sb.append(key); UIManager.put(key, sb.toString()); } } public AssistantUIManager() { }
}
</source>