ValueSelector.java :  » Graphic-3D » Art-of-Illusion » ArtOfIllusion » ui » Java Open Source

Java Open Source » Graphic 3D » Art of Illusion 
Art of Illusion » ArtOfIllusion » ui » ValueSelector.java
/* Copyright (C) 2006 by Peter Eastman

   This program is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
   Foundation; either version 2 of the License, or (at your option) any later version.

   This program 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 General Public License for more details. */

package artofillusion.ui;

import buoy.widget.*;
import buoy.event.*;
import buoy.xml.*;

import javax.swing.*;
import java.awt.*;
import java.awt.image.*;

/**
 * This class is used for selecting a numeric value within a (possibly unbounded) range.  The user
 * may edit the value either by typing into a text field, or by clicking and dragging on an
 * "adjuster" Widget.  This class is similar to JSlider, but it can be used when the permitted values
 * are not restricted to a finite range.
 */

public class ValueSelector extends RowContainer
{
  private final ValueField field;
  private final CustomWidget adjuster;
  private double minimum, maximum, increment;
  private int lastX;
  private final InfiniteDragListener drag;

  private static Cursor BLANK_CURSOR;
  private static Icon DIAL_IMAGE;
  private static Icon KNOB_IMAGE;

  static
  {
    try
    {
      Image image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB_PRE);
      BLANK_CURSOR = Toolkit.getDefaultToolkit().createCustomCursor(image, new Point(), "");
      DIAL_IMAGE = new IconResource("artofillusion/Icons/dial.png");
      KNOB_IMAGE = new IconResource("artofillusion/Icons/dialKnob.png");
    }
    catch (Exception ex)
    {
    }
  }

  /**
   * Create a ValueSelector.
   *
   * @param value       the initial value
   * @param min         the minimum legal value.  Specify Double.NEGATIVE_INFINITY if the range
   *                    is not bounded from below.
   * @param max         the maximum legal value.  Specify Double.POSITIVE_INFINITY if the range
   *                    is not bounded from above.
   * @param increment   the amount by which the value should change for each pixel the mouse is
   *                    moved after clicking on the adjustor Widget
   */

  public ValueSelector(double value, double min, double max, double increment)
  {
    minimum = min;
    maximum = max;
    this.increment = increment;
    add(field = new ValueField(value, ValueField.NONE));
    field.setValueChecker(new ValueChecker()
    {
      public boolean isValid(double val)
      {
        return (val >= minimum && val <= maximum);
      }
    });
    field.addEventLink(ValueChangedEvent.class, this, "dispatchValueChanged");
    adjuster = new CustomWidget();
    adjuster.addEventLink(RepaintEvent.class, this, "paintDial");
    adjuster.setPreferredSize(new Dimension(DIAL_IMAGE.getIconWidth(), DIAL_IMAGE.getIconHeight()));
    add(adjuster);
    drag = new InfiniteDragListener(adjuster);
    drag.addEventLink(MousePressedEvent.class, this, "mousePressed");
    drag.addEventLink(MouseDraggedEvent.class, this, "mouseDragged");
    drag.addEventLink(MouseReleasedEvent.class, this, "mouseReleased");
  }

  /**
   * Get the current value.
   */

  public double getValue()
  {
    return field.getValue();
  }

  /**
   * Set the current value.
   */

  public void setValue(double value)
  {
    field.setValue(value);
    adjuster.repaint();
  }

  /** Get the minimum allowed value. */

  public double getMinimumValue()
  {
    return minimum;
  }

  /** Set the minimum allowed value. */

  public void setMinimumValue(double min)
  {
    this.minimum = min;
  }

  /** Get the maximum allowed value. */

  public double getMaximumValue()
  {
    return maximum;
  }

  /** Set the maximum allowed value. */

  public void setMaximumValue(double max)
  {
    this.maximum = max;
  }

  public void setEnabled(boolean enabled)
  {
    super.setEnabled(enabled);
    field.setEnabled(enabled);
    drag.setEnabled(enabled);

  }

  private void mousePressed(MousePressedEvent ev)
  {
    lastX = ev.getX();
    setCursor(BLANK_CURSOR);
  }

  private void mouseDragged(MouseDraggedEvent ev)
  {
    if (Double.isNaN(field.getValue()))
      return;
    double scale = (ev.isAltDown() ? 10.0 : 1.0);
    double value = field.getValue()+scale*increment*(ev.getX()-lastX);
    if (value < minimum)
      value = minimum;
    if (value > maximum)
      value = maximum;
    field.setValue(value);
    lastX = ev.getX();
    dispatchValueChanged(ev);
    adjuster.repaint();
  }

  private void mouseReleased(MouseReleasedEvent ev)
  {
    setCursor(null);
    if (!Double.isNaN(field.getValue()))
      dispatchValueChanged(ev);
  }

  /**
   * Dispatch a ValueChangedEvent.
   */

  private void dispatchValueChanged(WidgetEvent originalEvent)
  {
    if (originalEvent.getWidget() == field)
      adjuster.repaint();
    dispatchEvent(new ValueChangedEvent(this, originalEvent instanceof MouseDraggedEvent));
  }

  /**
   * Paint the adjuster widget.
   */

  private void paintDial(RepaintEvent ev)
  {
    DIAL_IMAGE.paintIcon(adjuster.getComponent(), ev.getGraphics(), 0, 0);
    if (!Double.isNaN(field.getValue()) && isEnabled())
    {
      double angle = 0.005*Math.PI*field.getValue()/increment;
      int x = 8+(int) Math.round(4*Math.sin(angle));
      int y = 8-(int) Math.round(4*Math.cos(angle));
      KNOB_IMAGE.paintIcon(adjuster.getComponent(), ev.getGraphics(), x, y);
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.