Thread: [Mc4j-cvs] mc4j/src/org/mc4j/console/swing LogarithmicJSlider.java,NONE,1.1 LogarithmicTimeJSlider.j
Brought to you by:
ghinkl
From: Greg H. <gh...@us...> - 2004-04-16 18:49:54
|
Update of /cvsroot/mc4j/mc4j/src/org/mc4j/console/swing In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6737/src/org/mc4j/console/swing Added Files: LogarithmicJSlider.java LogarithmicTimeJSlider.java Log Message: A new Logarithmic version of JSlider, plus one that deals in time to make the sleep delay in the graph popup easier to use. --- NEW FILE: LogarithmicTimeJSlider.java --- /* * Author: Greg Hinkle * * The contents of this file are subject to the Sapient Public License Version 1.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy of the * License at http://mc4j.sf.net/License-SPL.html. * * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, * either express or implied. See the License for the specific language governing rights and limitations * under the License. * * The Original Code is The MC4J Management Console * The Initial Developer of the Original Code is Greg Hinkle (gh...@us...) * Copyright (C) 2004 Greg Hinkle. All Rights Reserved. * * Redistributions of code or binary files using or based on this code must reproduce the * above copyright and disclaimer. For more information see <http://mc4j.sourceforge.net>. */ package org.mc4j.console.swing; import java.text.DecimalFormat; import java.util.Hashtable; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; /** * This extension to the LogarithmicJSlider alters the major tick * labels to label logarithmic time scales from milleseconds to days. * * @author Greg Hinkle (gh...@us...), Apr 12, 2004 * @version $Revision: 1.1 $($Author: ghinkl $ / $Date: 2004/04/16 18:49:39 $) */ public class LogarithmicTimeJSlider extends LogarithmicJSlider { public LogarithmicTimeJSlider(int orientation) { super(orientation); } public LogarithmicTimeJSlider(int min, int max) { super(min, max); } public LogarithmicTimeJSlider(int min, int max, int value) { super(min, max, value); } public LogarithmicTimeJSlider(int orientation, int min, int max, int value) { super(orientation, min, max, value); } public LogarithmicTimeJSlider(BoundedRangeModel brm) { super(brm); } public LogarithmicTimeJSlider() { super(); } protected static DecimalFormat format = new DecimalFormat("#.#"); protected void createLabels(Hashtable table, int increment, int start) { for (int labelIndex = start; labelIndex <= getMaximum(); labelIndex *= increment) { String label = formatMilleseconds(labelIndex); table.put(new Integer(labelIndex), new LabelUIResource(label, JLabel.CENTER)); } } public String getTime() { return formatMilleseconds(getValue()); } public String formatMilleseconds(int labelIndex) { String label; if (labelIndex >= (1000 * 60 * 60 * 24)) { label = format.format(labelIndex / (double)(1000 * 60 * 60 * 24)) + " days"; } else if (labelIndex >= (1000 * 60 * 60)) { label = format.format(labelIndex / (double)(1000 * 60 * 60)) + " hours"; } else if (labelIndex >= (double)(1000 * 60)) { label = format.format(labelIndex / (double)(1000 * 60)) + " mins"; } else if (labelIndex >= 1000) { label = format.format(labelIndex / (double)1000) + " secs"; } else { label = labelIndex + " ms"; } return label; } /** * Just for testing * @param args */ public static void main(String[] args) { JFrame frame = new JFrame(); frame.setSize(408, 408); final LogarithmicTimeJSlider slider = new LogarithmicTimeJSlider(1000, 1000 * 60 * 60 * 24 * 7, 1000); final JLabel label = new JLabel(); slider.setPaintTicks(true); slider.setPaintLabels(true); slider.setMajorTickSpacing(10); slider.setMinorTickSpacing(10); slider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { System.out.println("Value is now: " + slider.getValue()); label.setText("Current value is: " + slider.formatMilleseconds(slider.getValue())); } }); frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS)); frame.getContentPane().add(slider); frame.getContentPane().add(label); frame.setVisible(true); LogSliderUI ui = (LogSliderUI) slider.getUI(); for (int i = 10; i <= 100000; i *= 10) { System.out.println("I: " + i + " xPos: " + ui.xPositionForValue(i) + " valueFor: " + ui.valueForXPosition(ui.xPositionForValue(i))); } } } --- NEW FILE: LogarithmicJSlider.java --- /* * Author: Greg Hinkle * * The contents of this file are subject to the Sapient Public License Version 1.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy of the * License at http://mc4j.sf.net/License-SPL.html. * * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, * either express or implied. See the License for the specific language governing rights and limitations * under the License. * * The Original Code is The MC4J Management Console * The Initial Developer of the Original Code is Greg Hinkle (gh...@us...) * Copyright (C) 2004 Greg Hinkle. All Rights Reserved. * * Redistributions of code or binary files using or based on this code must reproduce the * above copyright and disclaimer. For more information see <http://mc4j.sourceforge.net>. */ package org.mc4j.console.swing; import sun.swing.DefaultLookup; import java.awt.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Enumeration; import java.util.Hashtable; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.plaf.SliderUI; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicSliderUI; /** * This JSlider subclass uses a custom UI to allow a slider to work in * logarithmic scale. Major and minor ticks are drawn for logarithmic * scale as well. * * @author Greg Hinkle (gh...@us...), Apr 10, 2004 * @version $Revision: 1.1 $($Author: ghinkl $ / $Date: 2004/04/16 18:49:39 $) */ public class LogarithmicJSlider extends JSlider { public LogarithmicJSlider(int orientation) { super(orientation); SliderUI ui = new LogSliderUI(this); this.setUI(ui); } public LogarithmicJSlider(int min, int max) { super(min, max); SliderUI ui = new LogSliderUI(this); this.setUI(ui); } public LogarithmicJSlider(int min, int max, int value) { super(min, max, value); SliderUI ui = new LogSliderUI(this); this.setUI(ui); } public LogarithmicJSlider(int orientation, int min, int max, int value) { super(orientation, min, max, value); SliderUI ui = new LogSliderUI(this); this.setUI(ui); } public LogarithmicJSlider(BoundedRangeModel brm) { super(brm); SliderUI ui = new LogSliderUI(this); this.setUI(ui); } public LogarithmicJSlider() { SliderUI ui = new LogSliderUI(this); this.setUI(ui); } public static class LogSliderUI extends BasicSliderUI { public LogSliderUI(JSlider b) { super(b); } public int xPositionForValue(int value) { int min = slider.getMinimum(); int max = slider.getMaximum(); int trackLength = trackRect.width; double valueRange = (double) Math.log(max) - (double) Math.log(min); double pixelsPerValue = (double) trackLength / valueRange; int trackLeft = trackRect.x; int trackRight = trackRect.x + (trackRect.width - 1); int xPosition; if (!drawInverted()) { xPosition = trackLeft; xPosition += Math.round(pixelsPerValue * ((double) Math.log(value) - Math.log(min))); } else { xPosition = trackRight; xPosition -= Math.round(pixelsPerValue * ((double) Math.log(value) - Math.log(min))); } xPosition = Math.max(trackLeft, xPosition); xPosition = Math.min(trackRight, xPosition); return xPosition; } public int yPositionForValue(int value) { // TODO GH: Implement to support vertical log sliders return super.yPositionForValue(value); } public int valueForYPosition(int yPos) { // TODO GH: Implement to support vertical log sliders return super.valueForYPosition(yPos); } public int valueForXPosition(int xPos) { int value; final int minValue = slider.getMinimum(); final int maxValue = slider.getMaximum(); final int trackLength = trackRect.width; final int trackLeft = trackRect.x; final int trackRight = trackRect.x + (trackRect.width - 1); if (xPos <= trackLeft) { value = drawInverted() ? maxValue : minValue; } else if (xPos >= trackRight) { value = drawInverted() ? minValue : maxValue; } else { int distanceFromTrackLeft = xPos - trackLeft; double valueRange = (double) Math.log(maxValue) - (double) Math.log(minValue); //double valuePerPixel = (double)valueRange / (double)trackLength; //int valueFromTrackLeft = // (int)Math.round( Math.pow(3.5,(double)distanceFromTrackLeft * (double)valuePerPixel)); int valueFromTrackLeft = (int) Math.round(Math.pow(Math.E, Math.log(minValue) + ((((double) distanceFromTrackLeft) * valueRange) / (double) trackLength))); value = drawInverted() ? maxValue - valueFromTrackLeft : (int) Math.log(minValue) + valueFromTrackLeft; } return value; } public void paintTicks(Graphics g) { Rectangle tickBounds = tickRect; int i; int maj, min, max; int w = tickBounds.width; int h = tickBounds.height; int centerEffect, tickHeight; g.setColor(DefaultLookup.getColor(slider, this, "Slider.tickColor", Color.black)); maj = slider.getMajorTickSpacing(); min = slider.getMinorTickSpacing(); if (slider.getOrientation() == JSlider.HORIZONTAL) { g.translate(0, tickBounds.y); int value = slider.getMinimum(); int xPos = 0; if (slider.getMinorTickSpacing() > 0) { int majorValue = slider.getMinimum(); while (value <= slider.getMaximum()) { if (value >= majorValue) { value = majorValue; majorValue *= maj; } value += (majorValue / 10.0); xPos = xPositionForValue(value); paintMinorTickForHorizSlider(g, tickBounds, xPos); } } if (slider.getMajorTickSpacing() > 0) { value = slider.getMinimum(); while (value <= slider.getMaximum()) { xPos = xPositionForValue(value); paintMajorTickForHorizSlider(g, tickBounds, xPos); value *= slider.getMajorTickSpacing(); } } g.translate(0, -tickBounds.y); } else { g.translate(tickBounds.x, 0); int value = slider.getMinimum(); int yPos = 0; if (slider.getMinorTickSpacing() > 0) { int majorValue = slider.getMinimum(); int offset = 0; if (!slider.getComponentOrientation().isLeftToRight()) { offset = tickBounds.width - tickBounds.width / 2; g.translate(offset, 0); } while (value <= slider.getMaximum()) { if (value >= majorValue) { value = majorValue; majorValue *= maj; } yPos = yPositionForValue(value); paintMinorTickForVertSlider(g, tickBounds, yPos); value += (majorValue / 10.0); } if (!slider.getComponentOrientation().isLeftToRight()) { g.translate(-offset, 0); } } if (slider.getMajorTickSpacing() > 0) { value = slider.getMinimum(); if (!slider.getComponentOrientation().isLeftToRight()) { g.translate(2, 0); } while (value <= slider.getMaximum()) { yPos = yPositionForValue(value); paintMajorTickForVertSlider(g, tickBounds, yPos); value *= slider.getMajorTickSpacing(); } if (!slider.getComponentOrientation().isLeftToRight()) { g.translate(-2, 0); } } g.translate(-tickBounds.x, 0); } } } public static void main(String[] args) { JFrame frame = new JFrame(); frame.setSize(408, 408); final JSlider slider = new LogarithmicJSlider(100, 10000000, 1000); final JLabel label = new JLabel(); slider.setPaintTicks(true); slider.setPaintLabels(true); slider.setMajorTickSpacing(10); slider.setMinorTickSpacing(10); slider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { System.out.println("Value is now: " + slider.getValue()); label.setText("Current value is: " + slider.getValue()); } }); frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS)); frame.getContentPane().add(slider); frame.getContentPane().add(label); frame.setVisible(true); LogSliderUI ui = (LogSliderUI) slider.getUI(); for (int i = 10; i <= 100000; i *= 10) { System.out.println("I: " + i + " xPos: " + ui.xPositionForValue(i) + " valueFor: " + ui.valueForXPosition(ui.xPositionForValue(i))); } } /** * Creates a hashtable holding the text labels for this slider. This implementation * uses the increment as a log-base. * */ public Hashtable createStandardLabels(int increment, int start) { if (start > getMaximum() || start < getMinimum()) { throw new IllegalArgumentException("Slider label start point out of range."); } if (increment <= 0) { throw new IllegalArgumentException("Label incremement must be > 0"); } class LabelHashtable extends Hashtable implements PropertyChangeListener { int increment = 0; int start = 0; boolean startAtMin = false; public LabelHashtable(int increment, int start) { super(); this.increment = increment; this.start = start; startAtMin = start == getMinimum(); createLabels(this, increment, start); } public void propertyChange(PropertyChangeEvent e) { if (e.getPropertyName().equals("minimum") && startAtMin) { start = getMinimum(); } if (e.getPropertyName().equals("minimum") || e.getPropertyName().equals("maximum")) { Enumeration keys = getLabelTable().keys(); Object key = null; Hashtable hashtable = new Hashtable(); // Save the labels that were added by the developer while (keys.hasMoreElements()) { key = keys.nextElement(); Object value = getLabelTable().get(key); if (!(value instanceof LabelUIResource)) { hashtable.put(key, value); } } clear(); createLabels(this, increment, start); // Add the saved labels keys = hashtable.keys(); while (keys.hasMoreElements()) { key = keys.nextElement(); put(key, hashtable.get(key)); } ((JSlider) e.getSource()).setLabelTable(this); } } } LabelHashtable table = new LabelHashtable(increment, start); if (getLabelTable() != null && (getLabelTable() instanceof PropertyChangeListener)) { removePropertyChangeListener((PropertyChangeListener) getLabelTable()); } addPropertyChangeListener(table); return table; } /** * This method creates the table of labels that are used to label major ticks * on the slider. * @param table * @param increment * @param start */ protected void createLabels(Hashtable table, int increment, int start) { for (int labelIndex = start; labelIndex <= getMaximum(); labelIndex *= increment) { table.put(new Integer(labelIndex), new LabelUIResource("" + labelIndex, JLabel.CENTER)); } } protected class LabelUIResource extends JLabel implements UIResource { public LabelUIResource(String text, int alignment) { super(text, alignment); setName("Slider.label"); } } } |