Package com.sshtools.ui.swing

Source Code of com.sshtools.ui.swing.NumericTextField$ADocument

/*
*  SSHTools - Java SSH2 API
*
*  Copyright (C) 2002 Lee David Painter.
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Library General Public License
*  as published by the Free Software Foundation; either version 2 of
*  the License, or (at your option) any later version.
*
*  You may also distribute it and/or modify it under the terms of the
*  Apache style J2SSH Software License. A copy of which should have
*  been provided with the distribution.
*
*  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
*  License document supplied with your distribution for more details.
*
*/

package com.sshtools.ui.swing;

import java.awt.Color;
import java.awt.event.FocusEvent;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.text.ParseException;

import javax.swing.JTextField;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

/**
*
*
* @author $author$
*/
public class NumericTextField
    extends XTextField {
  private Color positiveBackground;
  private DecimalFormatSymbols symbols;

  //  Private instance variables
  private NumberFormat numberFormat;
  private boolean selectAllOnFocusGain;
  private int wColumnWidth;

  /**
   * Creates a new NumericTextField object.
   *
   * @param min
   * @param max
   */
  public NumericTextField(Number min, Number max) {
    this(min, max, min);
  }

  /**
   * Creates a new NumericTextField object.
   *
   * @param min
   * @param max
   * @param initial
   * @param rightJustify
   */
  public NumericTextField(Number min, Number max, Number initial,
                          boolean rightJustify) {
    this(min, max, initial, rightJustify, null);
  }

  /**
   * Creates a new NumericTextField object.
   *
   * @param min
   * @param max
   * @param initial
   */
  public NumericTextField(Number min, Number max, Number initial) {
    this(min, max, initial, true);
  }

  /**
   * Creates a new NumericTextField object.
   *
   * @param min
   * @param max
   * @param initial
   * @param rightJustify
   * @param numberFormat
   *
   * @throws IllegalArgumentException
   */
  public NumericTextField(Number min, Number max, Number initial,
                          boolean rightJustify, NumberFormat numberFormat) {
    super(Math.max(min.toString().length(), max.toString().length()));
    setNumberFormat(numberFormat);

    if (min.getClass().equals(max.getClass())
        && max.getClass().equals(initial.getClass())) {
      setDocument(new ADocument(min, max));
      setValue(initial);
    }
    else {
      throw new IllegalArgumentException(
          "All arguments must be of the same class");
    }

    setRightJustify(rightJustify);
  }

  /*
   *  Overides <code>JTextFields</codes> calculation of the width of a single
   *  character (M space)
   *
   *  @return column width based on '9'
   *  public int getColumnWidth() {
   *  if (wColumnWidth==0) {
   *  FontMetrics metrics = getFontMetrics(getFont());
   *  wColumnWidth = metrics.charWidth('W');
   *  }
   *  return wColumnWidth;
   *  }
   */
  protected void processFocusEvent(FocusEvent e) {
    super.processFocusEvent(e);

    if (!e.isTemporary()) {
      switch (e.getID()) {
        case FocusEvent.FOCUS_LOST:

          if (getNumberFormat() != null) {
            String s = getNumberFormat().format(getValue()).toString();

            if (!getText().equals(s)) {
              setText(s);
            }
          }

          break;

        case FocusEvent.FOCUS_GAINED:

          if (isSelectAllOnFocusGain()) {
            selectAll();
          }

          break;
      }
    }
  }

  /**
   *
   *
   * @return
   */
  public boolean isSelectAllOnFocusGain() {
    return selectAllOnFocusGain;
  }

  /**
   *
   *
   * @param selectAllOnFocusGain
   */
  public void setSelectAllOnFocusGain(boolean selectAllOnFocusGain) {
    this.selectAllOnFocusGain = selectAllOnFocusGain;
  }

  /**
   *
   *
   * @param max
   */
  public void setMaximum(Number max) {
    ( (ADocument) getDocument()).setMaximum(max);
  }

  /**
   *
   *
   * @return
   */
  public Number getMaximum() {
    return ( (ADocument) getDocument()).max;
  }

  /**
   *
   *
   * @param min
   */
  public void setMinimum(Number min) {
    ( (ADocument) getDocument()).setMinimum(min);
  }

  /**
   *
   *
   * @return
   */
  public Number getMinimum() {
    return ( (ADocument) getDocument()).min;
  }

  /**
   *
   *
   * @param numberFormat
   */
  public void setNumberFormat(NumberFormat numberFormat) {
    this.numberFormat = numberFormat;

    if (numberFormat instanceof DecimalFormat) {
      symbols = ( (DecimalFormat) numberFormat).getDecimalFormatSymbols();
    }
    else {
      symbols = new DecimalFormatSymbols();
    }
  }

  /**
   *
   *
   * @return
   */
  public NumberFormat getNumberFormat() {
    return numberFormat;
  }

  /**
   *
   *
   * @param rightJustify
   */
  public void setRightJustify(boolean rightJustify) {
    setHorizontalAlignment(rightJustify ? JTextField.RIGHT : JTextField.LEFT);
  }

  /**
   *
   *
   * @return
   */
  public boolean isRightJustify() {
    return getHorizontalAlignment() == JTextField.RIGHT;
  }

  /**
   *
   *
   * @param s
   */
  public void setText(String s) {
    ADocument doc = (ADocument) getDocument();
    Number oldValue = doc.currentVal;

    try {
      doc.currentVal = doc.parse(s);
    }
    catch (Exception e) {
      e.printStackTrace();

      return;
    }

    if (oldValue != doc.currentVal) {
      doc.checkingEnabled = false;
      super.setText(s);
      doc.checkingEnabled = true;
    }
  }

  /**
   *
   *
   * @param i
   */
  public void setValue(Number i) {
    setText(i.toString());
  }

  /**
   *
   *
   * @return
   */
  public Number getValue() {
    return ( (ADocument) getDocument()).getValue();
  }

  //  Supporting classes
  class ADocument
      extends PlainDocument {
    Number currentVal;
    Number max;
    Number min;
    boolean checkingEnabled = true;
    boolean rightJustify = true;

    public ADocument(Number min, Number max) {
      this.min = min;
      this.max = max;

      if (min.getClass().equals(Byte.class)) {
        currentVal = new Byte( (byte) 0);
      }
      else {
        if (min.getClass().equals(Short.class)) {
          currentVal = new Short( (short) 0);
        }
        else {
          if (min.getClass().equals(Integer.class)) {
            currentVal = new Integer(0);
          }
          else {
            if (min.getClass().equals(Long.class)) {
              currentVal = new Long(0L);
            }
            else {
              if (min.getClass().equals(Float.class)) {
                currentVal = new Float(0f);
              }
              else {
                currentVal = new Double(0d);
              }
            }
          }
        }
      }
    }

    public void setMaximum(Number max) {
      this.max = max;
    }

    public void setMinimum(Number min) {
      this.min = min;
    }

    public void setRightJustify(boolean rightJustify) {
      this.rightJustify = rightJustify;
    }

    public boolean isRightJustify() {
      return rightJustify;
    }

    public Number getValue() {
      return currentVal;
    }

    public void insertString(int offs, String str, AttributeSet a) throws
        BadLocationException {
      if (str == null) {
        return;
      }

      if (!checkingEnabled) {
        super.insertString(offs, str, a);

        return;
      }

      String proposedResult = null;

      if (getLength() == 0) {
        proposedResult = str;
      }
      else {
        StringBuffer currentBuffer = new StringBuffer(getText(0,
            getLength()));
        currentBuffer.insert(offs, str);
        proposedResult = currentBuffer.toString();
      }

      try {
        currentVal = parse(proposedResult);
        super.insertString(offs, str, a);
      }
      catch (Exception e) {
      }
    }

    public Number parse(String proposedResult) throws NumberFormatException {
      Double d = new Double(0d);

      //   See if the proposed result matches the number format (if any)
      if (!proposedResult.equals(String.valueOf(symbols.getMinusSign()))
          && (proposedResult.length() != 0)) {
        if (getNumberFormat() != null) {
          //   Strip out everything from the proposed result other than the
          //   numbers and and decimal separators
          StringBuffer sB = new StringBuffer();

          for (int i = 0; i < proposedResult.length(); i++) {
            char ch = proposedResult.charAt(i);

            if ( (ch == symbols.getDecimalSeparator())
                || ( (ch >= '0') && (ch <= '9'))) {
              sB.append(ch);
            }
          }

          String s = sB.toString();

          //   Find out how many digits there are before the decimal place
          int i = 0;

          for (;
               (i < s.length())
               && (s.charAt(i) != symbols.getDecimalSeparator());
               i++) {
            ;
          }

          int before = i;
          int after = 0;

          if (before < s.length()) {
            after = s.length() - i - 1;
          }

          if (before > getNumberFormat().getMaximumIntegerDigits()) {
            throw new NumberFormatException(
                "More digits BEFORE the decimal separator than allowed:"
                + proposedResult);
          }

          if (after > getNumberFormat().getMaximumFractionDigits()) {
            throw new NumberFormatException(
                "More digits AFTER the decimal separator than allowed:"
                + proposedResult);
          }

          //   Now try to parse the field against the number format
          try {
            d = new Double(getNumberFormat().parse(proposedResult)
                           .doubleValue());
          }
          catch (ParseException pE) {
            throw new NumberFormatException("Failed to parse. "
                                            + proposedResult + pE.getMessage());
          }
        }
        //   Just use the default parse
        else {
          d = new Double(proposedResult);
        }
      }

      //   Now determine if the number if within range
      if ( (d.doubleValue() >= min.doubleValue())
          && (d.doubleValue() <= max.doubleValue())) {
        //   Now create the real type
        if (min.getClass().equals(Byte.class)) {
          return new Byte(d.byteValue());
        }
        else {
          if (min.getClass().equals(Short.class)) {
            return new Short(d.shortValue());
          }
          else {
            if (min.getClass().equals(Integer.class)) {
              return new Integer(d.intValue());
            }
            else {
              if (min.getClass().equals(Long.class)) {
                return new Long(d.longValue());
              }
              else {
                if (min.getClass().equals(Float.class)) {
                  return new Float(d.floatValue());
                }
                else {
                  return d;
                }
              }
            }
          }
        }
      }
      else {
        throw new NumberFormatException(d
                                        + " Is out of range. Minimum is " +
                                        min.doubleValue()
                                        + ", Maximum is " + max.doubleValue());
      }
    }

    public void remove(int offs, int len) throws BadLocationException {
      if (!checkingEnabled) {
        super.remove(offs, len);

        return;
      }

      String currentText = getText(0, getLength());
      String beforeOffset = currentText.substring(0, offs);
      String afterOffset = currentText.substring(len + offs,
                                                 currentText.length());
      String proposedResult = beforeOffset + afterOffset;

      try {
        currentVal = parse(proposedResult);
        super.remove(offs, len);
      }
      catch (Exception e) {
      }
    }
  }
}
TOP

Related Classes of com.sshtools.ui.swing.NumericTextField$ADocument

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.