Save This Page
Home » j2ssh-0.2.9-src » com.sshtools.common.ui » [javadoc | source]
    1   /*
    2    *  SSHTools - Java SSH2 API
    3    *
    4    *  Copyright (C) 2002-2003 Lee David Painter and Contributors.
    5    *
    6    *  Contributions made by:
    7    *
    8    *  Brett Smith
    9    *  Richard Pernavas
   10    *  Erwin Bolwidt
   11    *
   12    *  This program is free software; you can redistribute it and/or
   13    *  modify it under the terms of the GNU General Public License
   14    *  as published by the Free Software Foundation; either version 2
   15    *  of the License, or (at your option) any later version.
   16    *
   17    *  This program is distributed in the hope that it will be useful,
   18    *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   19    *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   20    *  GNU General Public License for more details.
   21    *
   22    *  You should have received a copy of the GNU General Public License
   23    *  along with this program; if not, write to the Free Software
   24    *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   25    */
   26   package com.sshtools.common.ui;
   27   
   28   import java.awt.Color;
   29   import java.awt.event.FocusEvent;
   30   
   31   import java.text.DecimalFormat;
   32   import java.text.DecimalFormatSymbols;
   33   import java.text.NumberFormat;
   34   import java.text.ParseException;
   35   
   36   import javax.swing.JTextField;
   37   import javax.swing.text.AttributeSet;
   38   import javax.swing.text.BadLocationException;
   39   import javax.swing.text.PlainDocument;
   40   
   41   
   42   /**
   43    *
   44    *
   45    * @author $author$
   46    * @version $Revision: 1.14 $
   47    */
   48   public class NumericTextField extends XTextField {
   49       private Color positiveBackground;
   50       private DecimalFormatSymbols symbols;
   51   
   52       //  Private instance variables
   53       private NumberFormat numberFormat;
   54       private boolean selectAllOnFocusGain;
   55       private int wColumnWidth;
   56   
   57       /**
   58   * Creates a new NumericTextField object.
   59   *
   60   * @param min
   61   * @param max
   62   */
   63       public NumericTextField(Number min, Number max) {
   64           this(min, max, min);
   65       }
   66   
   67       /**
   68   * Creates a new NumericTextField object.
   69   *
   70   * @param min
   71   * @param max
   72   * @param initial
   73   * @param rightJustify
   74   */
   75       public NumericTextField(Number min, Number max, Number initial,
   76           boolean rightJustify) {
   77           this(min, max, initial, rightJustify, null);
   78       }
   79   
   80       /**
   81   * Creates a new NumericTextField object.
   82   *
   83   * @param min
   84   * @param max
   85   * @param initial
   86   */
   87       public NumericTextField(Number min, Number max, Number initial) {
   88           this(min, max, initial, true);
   89       }
   90   
   91       /**
   92   * Creates a new NumericTextField object.
   93   *
   94   * @param min
   95   * @param max
   96   * @param initial
   97   * @param rightJustify
   98   * @param numberFormat
   99   *
  100   * @throws IllegalArgumentException
  101   */
  102       public NumericTextField(Number min, Number max, Number initial,
  103           boolean rightJustify, NumberFormat numberFormat) {
  104           super(Math.max(min.toString().length(), max.toString().length()));
  105           setNumberFormat(numberFormat);
  106   
  107           if (min.getClass().equals(max.getClass()) &&
  108                   max.getClass().equals(initial.getClass())) {
  109               setDocument(new ADocument(min, max));
  110               setValue(initial);
  111           } else {
  112               throw new IllegalArgumentException(
  113                   "All arguments must be of the same class");
  114           }
  115   
  116           setRightJustify(rightJustify);
  117       }
  118   
  119       /*
  120   *  Overides <code>JTextFields</codes> calculation of the width of a single
  121   *  character (M space)
  122   *
  123   *  @return column width based on '9'
  124   *  public int getColumnWidth() {
  125   *  if (wColumnWidth==0) {
  126   *  FontMetrics metrics = getFontMetrics(getFont());
  127   *  wColumnWidth = metrics.charWidth('W');
  128   *  }
  129   *  return wColumnWidth;
  130   *  }
  131   */
  132       protected void processFocusEvent(FocusEvent e) {
  133           super.processFocusEvent(e);
  134   
  135           if (!e.isTemporary()) {
  136               switch (e.getID()) {
  137               case FocusEvent.FOCUS_LOST:
  138   
  139                   if (getNumberFormat() != null) {
  140                       String s = getNumberFormat().format(getValue()).toString();
  141   
  142                       if (!getText().equals(s)) {
  143                           setText(s);
  144                       }
  145                   }
  146   
  147                   break;
  148   
  149               case FocusEvent.FOCUS_GAINED:
  150   
  151                   if (isSelectAllOnFocusGain()) {
  152                       selectAll();
  153                   }
  154   
  155                   break;
  156               }
  157           }
  158       }
  159   
  160       /**
  161   *
  162   *
  163   * @return
  164   */
  165       public boolean isSelectAllOnFocusGain() {
  166           return selectAllOnFocusGain;
  167       }
  168   
  169       /**
  170   *
  171   *
  172   * @param selectAllOnFocusGain
  173   */
  174       public void setSelectAllOnFocusGain(boolean selectAllOnFocusGain) {
  175           this.selectAllOnFocusGain = selectAllOnFocusGain;
  176       }
  177   
  178       /**
  179   *
  180   *
  181   * @param max
  182   */
  183       public void setMaximum(Number max) {
  184           ((ADocument) getDocument()).setMaximum(max);
  185       }
  186   
  187       /**
  188   *
  189   *
  190   * @return
  191   */
  192       public Number getMaximum() {
  193           return ((ADocument) getDocument()).max;
  194       }
  195   
  196       /**
  197   *
  198   *
  199   * @param min
  200   */
  201       public void setMinimum(Number min) {
  202           ((ADocument) getDocument()).setMinimum(min);
  203       }
  204   
  205       /**
  206   *
  207   *
  208   * @return
  209   */
  210       public Number getMinimum() {
  211           return ((ADocument) getDocument()).min;
  212       }
  213   
  214       /**
  215   *
  216   *
  217   * @param numberFormat
  218   */
  219       public void setNumberFormat(NumberFormat numberFormat) {
  220           this.numberFormat = numberFormat;
  221   
  222           if (numberFormat instanceof DecimalFormat) {
  223               symbols = ((DecimalFormat) numberFormat).getDecimalFormatSymbols();
  224           } else {
  225               symbols = new DecimalFormatSymbols();
  226           }
  227       }
  228   
  229       /**
  230   *
  231   *
  232   * @return
  233   */
  234       public NumberFormat getNumberFormat() {
  235           return numberFormat;
  236       }
  237   
  238       /**
  239   *
  240   *
  241   * @param rightJustify
  242   */
  243       public void setRightJustify(boolean rightJustify) {
  244           setHorizontalAlignment(rightJustify ? JTextField.RIGHT : JTextField.LEFT);
  245       }
  246   
  247       /**
  248   *
  249   *
  250   * @return
  251   */
  252       public boolean isRightJustify() {
  253           return getHorizontalAlignment() == JTextField.RIGHT;
  254       }
  255   
  256       /**
  257   *
  258   *
  259   * @param s
  260   */
  261       public void setText(String s) {
  262           ADocument doc = (ADocument) getDocument();
  263           Number oldValue = doc.currentVal;
  264   
  265           try {
  266               doc.currentVal = doc.parse(s);
  267           } catch (Exception e) {
  268               e.printStackTrace();
  269   
  270               return;
  271           }
  272   
  273           if (oldValue != doc.currentVal) {
  274               doc.checkingEnabled = false;
  275               super.setText(s);
  276               doc.checkingEnabled = true;
  277           }
  278       }
  279   
  280       /**
  281   *
  282   *
  283   * @param i
  284   */
  285       public void setValue(Number i) {
  286           setText(i.toString());
  287       }
  288   
  289       /**
  290   *
  291   *
  292   * @return
  293   */
  294       public Number getValue() {
  295           return ((ADocument) getDocument()).getValue();
  296       }
  297   
  298       //  Supporting classes
  299       class ADocument extends PlainDocument {
  300           Number currentVal;
  301           Number max;
  302           Number min;
  303           boolean checkingEnabled = true;
  304           boolean rightJustify = true;
  305   
  306           public ADocument(Number min, Number max) {
  307               this.min = min;
  308               this.max = max;
  309   
  310               if (min.getClass().equals(Byte.class)) {
  311                   currentVal = new Byte((byte) 0);
  312               } else {
  313                   if (min.getClass().equals(Short.class)) {
  314                       currentVal = new Short((short) 0);
  315                   } else {
  316                       if (min.getClass().equals(Integer.class)) {
  317                           currentVal = new Integer(0);
  318                       } else {
  319                           if (min.getClass().equals(Long.class)) {
  320                               currentVal = new Long(0L);
  321                           } else {
  322                               if (min.getClass().equals(Float.class)) {
  323                                   currentVal = new Float(0f);
  324                               } else {
  325                                   currentVal = new Double(0d);
  326                               }
  327                           }
  328                       }
  329                   }
  330               }
  331           }
  332   
  333           public void setMaximum(Number max) {
  334               this.max = max;
  335           }
  336   
  337           public void setMinimum(Number min) {
  338               this.min = min;
  339           }
  340   
  341           public void setRightJustify(boolean rightJustify) {
  342               this.rightJustify = rightJustify;
  343           }
  344   
  345           public boolean isRightJustify() {
  346               return rightJustify;
  347           }
  348   
  349           public Number getValue() {
  350               return currentVal;
  351           }
  352   
  353           public void insertString(int offs, String str, AttributeSet a)
  354               throws BadLocationException {
  355               if (str == null) {
  356                   return;
  357               }
  358   
  359               if (!checkingEnabled) {
  360                   super.insertString(offs, str, a);
  361   
  362                   return;
  363               }
  364   
  365               String proposedResult = null;
  366   
  367               if (getLength() == 0) {
  368                   proposedResult = str;
  369               } else {
  370                   StringBuffer currentBuffer = new StringBuffer(getText(0,
  371                               getLength()));
  372                   currentBuffer.insert(offs, str);
  373                   proposedResult = currentBuffer.toString();
  374               }
  375   
  376               try {
  377                   currentVal = parse(proposedResult);
  378                   super.insertString(offs, str, a);
  379               } catch (Exception e) {
  380               }
  381           }
  382   
  383           public Number parse(String proposedResult) throws NumberFormatException {
  384               Double d = new Double(0d);
  385   
  386               //   See if the proposed result matches the number format (if any)
  387               if (!proposedResult.equals(String.valueOf(symbols.getMinusSign())) &&
  388                       (proposedResult.length() != 0)) {
  389                   if (getNumberFormat() != null) {
  390                       //   Strip out everything from the proposed result other than the
  391                       //   numbers and and decimal separators
  392                       StringBuffer sB = new StringBuffer();
  393   
  394                       for (int i = 0; i < proposedResult.length(); i++) {
  395                           char ch = proposedResult.charAt(i);
  396   
  397                           if ((ch == symbols.getDecimalSeparator()) ||
  398                                   ((ch >= '0') && (ch <= '9'))) {
  399                               sB.append(ch);
  400                           }
  401                       }
  402   
  403                       String s = sB.toString();
  404   
  405                       //   Find out how many digits there are before the decimal place
  406                       int i = 0;
  407   
  408                       for (;
  409                               (i < s.length()) &&
  410                               (s.charAt(i) != symbols.getDecimalSeparator());
  411                               i++) {
  412                           ;
  413                       }
  414   
  415                       int before = i;
  416                       int after = 0;
  417   
  418                       if (before < s.length()) {
  419                           after = s.length() - i - 1;
  420                       }
  421   
  422                       if (before > getNumberFormat().getMaximumIntegerDigits()) {
  423                           throw new NumberFormatException(
  424                               "More digits BEFORE the decimal separator than allowed:" +
  425                               proposedResult);
  426                       }
  427   
  428                       if (after > getNumberFormat().getMaximumFractionDigits()) {
  429                           throw new NumberFormatException(
  430                               "More digits AFTER the decimal separator than allowed:" +
  431                               proposedResult);
  432                       }
  433   
  434                       //   Now try to parse the field against the number format
  435                       try {
  436                           d = new Double(getNumberFormat().parse(proposedResult)
  437                                              .doubleValue());
  438                       } catch (ParseException pE) {
  439                           throw new NumberFormatException("Failed to parse. " +
  440                               proposedResult + pE.getMessage());
  441                       }
  442                   }
  443                   //   Just use the default parse
  444                   else {
  445                       d = new Double(proposedResult);
  446                   }
  447               }
  448   
  449               //   Now determine if the number if within range
  450               if ((d.doubleValue() >= min.doubleValue()) &&
  451                       (d.doubleValue() <= max.doubleValue())) {
  452                   //   Now create the real type
  453                   if (min.getClass().equals(Byte.class)) {
  454                       return new Byte(d.byteValue());
  455                   } else {
  456                       if (min.getClass().equals(Short.class)) {
  457                           return new Short(d.shortValue());
  458                       } else {
  459                           if (min.getClass().equals(Integer.class)) {
  460                               return new Integer(d.intValue());
  461                           } else {
  462                               if (min.getClass().equals(Long.class)) {
  463                                   return new Long(d.longValue());
  464                               } else {
  465                                   if (min.getClass().equals(Float.class)) {
  466                                       return new Float(d.floatValue());
  467                                   } else {
  468                                       return d;
  469                                   }
  470                               }
  471                           }
  472                       }
  473                   }
  474               } else {
  475                   throw new NumberFormatException(d +
  476                       " Is out of range. Minimum is " + min.doubleValue() +
  477                       ", Maximum is " + max.doubleValue());
  478               }
  479           }
  480   
  481           public void remove(int offs, int len) throws BadLocationException {
  482               if (!checkingEnabled) {
  483                   super.remove(offs, len);
  484   
  485                   return;
  486               }
  487   
  488               String currentText = getText(0, getLength());
  489               String beforeOffset = currentText.substring(0, offs);
  490               String afterOffset = currentText.substring(len + offs,
  491                       currentText.length());
  492               String proposedResult = beforeOffset + afterOffset;
  493   
  494               try {
  495                   currentVal = parse(proposedResult);
  496                   super.remove(offs, len);
  497               } catch (Exception e) {
  498               }
  499           }
  500       }
  501   }

Save This Page
Home » j2ssh-0.2.9-src » com.sshtools.common.ui » [javadoc | source]