Java/Swing JFC/Formatted TextField

Материал из Java эксперт
Перейти к: навигация, поиск

A BigDecimal object custom formatter

   <source lang="java">
 

import java.math.BigDecimal; import java.text.DecimalFormat; import javax.swing.JFormattedTextField; import javax.swing.text.DefaultFormatter; import javax.swing.text.DefaultFormatterFactory; import javax.swing.text.NumberFormatter; public class Main {

 public static void main(String[] argv) {
   JFormattedTextField f = new JFormattedTextField(new BigDecimal("123.4567"));
   DefaultFormatter fmt = new NumberFormatter(new DecimalFormat("#.0###############"));
   fmt.setValueClass(f.getValue().getClass());
   DefaultFormatterFactory fmtFactory = new DefaultFormatterFactory(fmt, fmt, fmt);
   f.setFormatterFactory(fmtFactory);
   BigDecimal bigValue = (BigDecimal) f.getValue();
 }

}


 </source>
   
  
 
  



Accepting Formatted Input

   <source lang="java">
 

import java.awt.BorderLayout; import java.awt.Container; import java.util.Date; import javax.swing.JFormattedTextField; import javax.swing.JFrame; public class FormattedTest {

 public static void main(String args[]) {
   JFrame frame = new JFrame("Formatted");
   Container contentPane = frame.getContentPane();
   JFormattedTextField ftf1 = new JFormattedTextField(new Integer(0));
   contentPane.add(ftf1, BorderLayout.NORTH);
   JFormattedTextField ftf2 = new JFormattedTextField(new Date());
   contentPane.add(ftf2, BorderLayout.SOUTH);
   frame.setSize(200, 100);
   frame.show();
 }

}


 </source>
   
  
 
  



A decimal number with one digit following the decimal point;

   <source lang="java">
 

import java.text.DecimalFormat; import javax.swing.JFormattedTextField; public class Main {

 public static void main(String[] argv) throws Exception {
   JFormattedTextField tft2 = new JFormattedTextField(new DecimalFormat("#.0"));
   tft2.setValue(new Float(123.4F));
   // Retrieve the value from the text field
   Float floatValue = (Float) tft2.getValue();
 }

}


 </source>
   
  
 
  



A formatter for regular expressions to be used with JFormattedTextField

   <source lang="java">
 

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// RegexPatternFormatter.java //A formatter for regular expressions to be used with JFormattedTextField. // import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.text.DefaultFormatter; public class RegexPatternFormatter extends DefaultFormatter {

 protected java.util.regex.Matcher matcher;
 public RegexPatternFormatter(java.util.regex.Pattern regex) {
   setOverwriteMode(false);
   matcher = regex.matcher(""); // create a Matcher for the regular
                  // expression
 }
 public Object stringToValue(String string) throws java.text.ParseException {
   if (string == null)
     return null;
   matcher.reset(string); // set "string" as the matcher"s input
   if (!matcher.matches()) // Does "string" match the regular expression?
     throw new java.text.ParseException("does not match regex", 0);
   // If we get this far, then it did match.
   return super.stringToValue(string); // will honor the "valueClass"
                     // property
 }
 public static void main(String argv[]) {
   // a demo main() to show how RegexPatternFormatter could be used
   JLabel lab1 = new JLabel("even length strings:");
   java.util.regex.Pattern evenLength = java.util.regex.Pattern
       .rupile("(..)*");
   JFormattedTextField ftf1 = new JFormattedTextField(
       new RegexPatternFormatter(evenLength));
   JLabel lab2 = new JLabel("no vowels:");
   java.util.regex.Pattern noVowels = java.util.regex.Pattern.rupile(
       "[^aeiou]*", java.util.regex.Pattern.CASE_INSENSITIVE);
   RegexPatternFormatter noVowelFormatter = new RegexPatternFormatter(
       noVowels);
   noVowelFormatter.setAllowsInvalid(false); // don"t allow user to type
                         // vowels
   JFormattedTextField ftf2 = new JFormattedTextField(noVowelFormatter);
   JFrame f = new JFrame("RegexPatternFormatter Demo");
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   JPanel pan1 = new JPanel(new java.awt.BorderLayout());
   pan1.add(lab1, java.awt.BorderLayout.WEST);
   pan1.add(ftf1, java.awt.BorderLayout.CENTER);
   lab1.setLabelFor(ftf1);
   f.getContentPane().add(pan1, java.awt.BorderLayout.NORTH);
   JPanel pan2 = new JPanel(new java.awt.BorderLayout());
   pan2.add(lab2, java.awt.BorderLayout.WEST);
   pan2.add(ftf2, java.awt.BorderLayout.CENTER);
   lab2.setLabelFor(ftf2);
   f.getContentPane().add(pan2, java.awt.BorderLayout.SOUTH);
   f.setSize(300, 80);
   f.setVisible(true);
 }

}


 </source>
   
  
 
  



A quick demonstration of JFormattedTextField

   <source lang="java">
 

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// SimpleFTF.java //A quick demonstration of JFormattedTextField. // import javax.swing.BoxLayout; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JPanel; public class SimpleFTF extends JPanel {

 public SimpleFTF() {
   JFormattedTextField ftf[] = new JFormattedTextField[7];
   String des[] = new String[ftf.length]; // description of each field
   des[0] = "Date";
   ftf[0] = new JFormattedTextField(new java.util.Date());
   des[1] = "Integer";
   ftf[1] = new JFormattedTextField(new Integer(90032221));
   des[2] = "Float";
   ftf[2] = new JFormattedTextField(new Float(3.14));
   des[3] = "Float work-around"; // manually specify a NumberFormat
   ftf[3] = new JFormattedTextField(java.text.NumberFormat.getInstance());
   ftf[3].setValue(new Float(3.14));
   des[4] = "currency";
   ftf[4] = new JFormattedTextField(java.text.NumberFormat
       .getCurrencyInstance());
   ftf[4].setValue(new Float(5.99));
   des[5] = "percent";
   ftf[5] = new JFormattedTextField(java.text.NumberFormat
       .getPercentInstance());
   ftf[5].setValue(new Float(0.33));
   des[6] = "java.net.URL"; // works via 1-arg String constructor and
                // toString()
   java.net.URL u = null;
   try {
     u = new java.net.URL("http://www.ora.ru/");
   } catch (java.net.MalformedURLException ignored) {
   }
   ftf[6] = new JFormattedTextField(u);
   ftf[6].setColumns(24);
   // add each ftf[] to a BoxLayout
   setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
   for (int j = 0; j < ftf.length; j += 1) {
     JPanel borderPanel = new JPanel(new java.awt.BorderLayout());
     borderPanel.setBorder(new javax.swing.border.TitledBorder(des[j]));
     borderPanel.add(ftf[j], java.awt.BorderLayout.CENTER);
     add(borderPanel);
   }
 }
 public static void main(String argv[]) {
   if (argv.length > 0) { // change to command-line locale
     if (argv[0].equalsIgnoreCase("canada"))
       java.util.Locale.setDefault(java.util.Locale.CANADA);
     if (argv[0].equalsIgnoreCase("canada_french"))
       java.util.Locale.setDefault(java.util.Locale.CANADA_FRENCH);
     if (argv[0].equalsIgnoreCase("china"))
       java.util.Locale.setDefault(java.util.Locale.CHINA);
     if (argv[0].equalsIgnoreCase("france"))
       java.util.Locale.setDefault(java.util.Locale.FRANCE);
     if (argv[0].equalsIgnoreCase("germany"))
       java.util.Locale.setDefault(java.util.Locale.GERMANY);
     if (argv[0].equalsIgnoreCase("italy"))
       java.util.Locale.setDefault(java.util.Locale.ITALY);
     if (argv[0].equalsIgnoreCase("japan"))
       java.util.Locale.setDefault(java.util.Locale.JAPAN);
     if (argv[0].equalsIgnoreCase("korea"))
       java.util.Locale.setDefault(java.util.Locale.KOREA);
     if (argv[0].equalsIgnoreCase("prc"))
       java.util.Locale.setDefault(java.util.Locale.PRC);
     if (argv[0].equalsIgnoreCase("taiwan"))
       java.util.Locale.setDefault(java.util.Locale.TAIWAN);
     if (argv[0].equalsIgnoreCase("uk"))
       java.util.Locale.setDefault(java.util.Locale.UK);
     if (argv[0].equalsIgnoreCase("us"))
       java.util.Locale.setDefault(java.util.Locale.US);
   }
   String localeString = java.util.Locale.getDefault().getDisplayName();
   JFrame f = new JFrame("SimpleFTF " + localeString);
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.setContentPane(new SimpleFTF());
   f.pack();
   f.setVisible(true);
 }

}


 </source>
   
  
 
  



Creating a Text Field to Display and Edit a Date

   <source lang="java">
 

import java.text.DateFormat; import java.util.Date; import javax.swing.JFormattedTextField; public class Main {

 public static void main(String[] argv) {
   JFormattedTextField tft2 = new JFormattedTextField(DateFormat.getDateInstance(DateFormat.SHORT));
   tft2.setValue(new Date());
 }

}


 </source>
   
  
 
  



Creating a Text Field to Display and Edit a Number

   <source lang="java">
 

import java.text.NumberFormat; import javax.swing.JFormattedTextField; public class Main {

 public static void main(String[] argv) {
   JFormattedTextField tft1 = new JFormattedTextField(NumberFormat.getIntegerInstance());
   tft1.setValue(new Integer(123));
   Integer intValue = (Integer) tft1.getValue();
 }

}


 </source>
   
  
 
  



Creating a Text Field to Display and Edit a Phone Number

   <source lang="java">
 

import javax.swing.JFormattedTextField; import javax.swing.text.MaskFormatter; public class Main {

 public static void main(String[] argv) throws Exception {
   MaskFormatter fmt = new MaskFormatter("###-###-####");
   JFormattedTextField tft1 = new JFormattedTextField(fmt);
 }

}


 </source>
   
  
 
  



Creating a Text Field to Display and Edit a social security number

   <source lang="java">
 

import javax.swing.JFormattedTextField; import javax.swing.text.MaskFormatter; public class Main {

 public static void main(String[] argv) throws Exception{
   MaskFormatter fmt = new MaskFormatter("###-###-####");
   JFormattedTextField tft1 = new JFormattedTextField(fmt);
   fmt = new MaskFormatter("###-##-####");
   JFormattedTextField tft2 = new JFormattedTextField(fmt);
 }

}


 </source>
   
  
 
  



Different configurations of JFormattedTextField: Date

   <source lang="java">
 

/*

* Copyright (c) 2003-2005 JGoodies Karsten Lentzsch. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without 
* modification, are permitted provided that the following conditions are met:
* 
*  o Redistributions of source code must retain the above copyright notice, 
*    this list of conditions and the following disclaimer. 
*     
*  o Redistributions in binary form must reproduce the above copyright notice, 
*    this list of conditions and the following disclaimer in the documentation 
*    and/or other materials provided with the distribution. 
*     
*  o Neither the name of JGoodies Karsten Lentzsch nor the names of 
*    its contributors may be used to endorse or promote products derived 
*    from this software without specific prior written permission. 
*     
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
*/

package com.jgoodies.validation.tutorial.formatted; import java.text.DateFormat; import java.text.Format; import java.util.Date; import java.util.LinkedList; import java.util.List; import javax.swing.*; import javax.swing.text.DateFormatter; import javax.swing.text.DefaultFormatter; import javax.swing.text.DefaultFormatterFactory; import com.jgoodies.binding.value.ValueHolder; import com.jgoodies.binding.value.ValueModel; import com.jgoodies.forms.builder.DefaultFormBuilder; import com.jgoodies.forms.layout.FormLayout; import com.jgoodies.validation.formatter.EmptyDateFormatter; import com.jgoodies.validation.formatter.RelativeDateFormatter; import com.jgoodies.validation.tutorial.formatted.format.DisplayFormat; import com.jgoodies.validation.tutorial.formatted.format.RelativeDateFormat; import com.jgoodies.validation.tutorial.util.ExampleComponentFactory; import com.jgoodies.validation.tutorial.util.MyFocusTraversalPolicy; import com.jgoodies.validation.tutorial.util.TutorialUtils; /**

* Demonstrates different configurations of JFormattedTextField
* to display and edit numbers. Shows
    *
  • how to use a custom DateFormat *
  • how to use a custom DateFormatter *
  • how to use a custom FormatterFactory *
  • how to reset a date to null *
  • how to map the empty string to a special date *
  • how to commit values on valid texts *

* 
* To look under the hood of this component, this class exposes 
* the bound properties text, value and editValid. 
*
* @author  Karsten Lentzsch
* @version $Revision: 1.8 $
* 
* @see     JFormattedTextField
* @see     JFormattedTextField.AbstractFormatter
*/

public final class DateExample {

   public static void main(String[] args) {
       try {
           UIManager.setLookAndFeel("com.jgoodies.looks.plastic.PlasticXPLookAndFeel");
       } catch (Exception e) {
           // Likely Plastic is not in the classpath; ignore it.
       }
       JFrame frame = new JFrame();
       frame.setTitle("Formatted :: Dates");
       frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
       JComponent panel = new DateExample()
               .buildPanel();
       frame.getContentPane().add(panel);
       frame.pack();
       TutorialUtils.locateOnScreenCenter(frame);
       frame.setVisible(true);
   }
   /**
    * Builds and returns a panel with a header row and the sample rows.
    * 
    * @return the example panel with a header and the sample rows
    */
   public JComponent buildPanel() {
       FormLayout layout = new FormLayout(
               "r:max(80dlu;pref), 4dlu, 45dlu, 1dlu, pref, 4dlu, pref, 0:grow");
       DefaultFormBuilder builder = new DefaultFormBuilder(layout);
       builder.setDefaultDialogBorder();
       builder.getPanel().setFocusTraversalPolicy(
               MyFocusTraversalPolicy.INSTANCE);
               
       Utils.appendTitleRow(builder, "Description");
       List fields = appendDemoRows(builder);
       
       String validText   = DateFormat.getDateInstance().format(new Date(67, 11, 5));
       String invalidText = "aa" + validText;
       Utils.appendButtonBar(builder, fields, validText, invalidText);
       return builder.getPanel();
   }
   
   
   /**
    * Appends the demo rows to the given builder and returns the List of
    * formatted text fields.
    * 
    * @param builder  the builder used to add components to
    * @return the List of formatted text fields
    */
   private List appendDemoRows(DefaultFormBuilder builder) {
       // The Formatter is choosen by the initial value.
       JFormattedTextField defaultDateField = 
           new JFormattedTextField(new Date());
       
       // The Formatter is choosen by the given Format.
       JFormattedTextField noInitialValueField = 
           new JFormattedTextField(DateFormat.getDateInstance());
       
       // Uses a custom DateFormat.
       DateFormat customFormat = DateFormat.getDateInstance(DateFormat.SHORT);
       JFormattedTextField customFormatField =
           new JFormattedTextField(new DateFormatter(customFormat));
       
       // Uses a RelativeDateFormat.
       DateFormat relativeFormat = new RelativeDateFormat();
       JFormattedTextField relativeFormatField =
           new JFormattedTextField(new DateFormatter(relativeFormat));
       
       // Uses a custom DateFormatter that allows relative input and
       // prints natural language strings.
       JFormattedTextField relativeFormatterField =
           new JFormattedTextField(new RelativeDateFormatter());
       
       // Uses a custom FormatterFactory that used different formatters
       // for the display and while editing.
       DefaultFormatterFactory formatterFactory = 
           new DefaultFormatterFactory(new RelativeDateFormatter(false, true),
                                       new RelativeDateFormatter(true, true));
       JFormattedTextField relativeFactoryField =
           new JFormattedTextField(formatterFactory);
       
       // Wraps a DateFormatter to map empty strings to null and vice versa.
       JFormattedTextField numberOrNullField =
           new JFormattedTextField(new EmptyDateFormatter());
       
       // Wraps a DateFormatter to map empty strings to -1 and vice versa.
       Date epoch = new Date(0); // January 1, 1970
       JFormattedTextField numberOrEmptyValueField =
           new JFormattedTextField(new EmptyDateFormatter(epoch));
       numberOrEmptyValueField.setValue(epoch);
       
       // Commits value on valid edit text
       DefaultFormatter formatter = new RelativeDateFormatter();
       formatter.setCommitsOnValidEdit(true);
       JFormattedTextField commitOnValidEditField =
           new JFormattedTextField(formatter);
       
       // A date field as created by the BasicComponentFactory:
       // Uses relative date input, and maps empty strings to null.
       ValueModel dateHolder = new ValueHolder();
       JFormattedTextField componentFactoryField =
           ExampleComponentFactory.createDateField(dateHolder);
       
       Format displayFormat = new DisplayFormat(DateFormat.getDateInstance());
       List fields = new LinkedList();
       fields.add(Utils.appendRow(builder, "Default",               defaultDateField,        displayFormat));
       fields.add(Utils.appendRow(builder, "No initial value",      noInitialValueField,     displayFormat));
       fields.add(Utils.appendRow(builder, "Empty <->  null",       numberOrNullField,       displayFormat));
       fields.add(Utils.appendRow(builder, "Empty <-> epoch",       numberOrEmptyValueField, displayFormat));
       fields.add(Utils.appendRow(builder, "Short format",          customFormatField,       displayFormat));
       fields.add(Utils.appendRow(builder, "Relative format",       relativeFormatField,     displayFormat));
       fields.add(Utils.appendRow(builder, "Relative formatter",    relativeFormatterField,  displayFormat));
       fields.add(Utils.appendRow(builder, "Relative factory",      relativeFactoryField,    displayFormat));
       fields.add(Utils.appendRow(builder, "Commits on valid edit", commitOnValidEditField,  displayFormat));
       fields.add(Utils.appendRow(builder, "Relative, maps null",   componentFactoryField,   displayFormat));
       
       return fields;
   }
      

}



 </source>
   
  
 
  



different configurations of JFormattedTextField: Number

   <source lang="java">
 

/*

* Copyright (c) 2003-2005 JGoodies Karsten Lentzsch. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without 
* modification, are permitted provided that the following conditions are met:
* 
*  o Redistributions of source code must retain the above copyright notice, 
*    this list of conditions and the following disclaimer. 
*     
*  o Redistributions in binary form must reproduce the above copyright notice, 
*    this list of conditions and the following disclaimer in the documentation 
*    and/or other materials provided with the distribution. 
*     
*  o Neither the name of JGoodies Karsten Lentzsch nor the names of 
*    its contributors may be used to endorse or promote products derived 
*    from this software without specific prior written permission. 
*     
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
*/

package com.jgoodies.validation.tutorial.formatted; import java.text.Format; import java.text.NumberFormat; import java.util.LinkedList; import java.util.List; import javax.swing.*; import javax.swing.text.DefaultFormatter; import javax.swing.text.DefaultFormatterFactory; import javax.swing.text.NumberFormatter; import com.jgoodies.forms.builder.DefaultFormBuilder; import com.jgoodies.forms.layout.FormLayout; import com.jgoodies.validation.formatter.EmptyNumberFormatter; import com.jgoodies.validation.tutorial.formatted.format.DisplayFormat; import com.jgoodies.validation.tutorial.formatted.formatter.CustomNumberFormatter; import com.jgoodies.validation.tutorial.util.MyFocusTraversalPolicy; import com.jgoodies.validation.tutorial.util.TutorialUtils; /**

* Demonstrates different configurations of JFormattedTextField
* to display and edit numbers. Shows
    *
  • how to use a custom NumberFormat *
  • how to use a custom NumberFormatter *
  • how to use a custom FormatterFactory *
  • how to reset a number to null *
  • how to map the empty string to a special number *
  • how to commit values on valid texts *
  • how to set the class of the result *
<p>
* 
* To look under the hood of this component, this class exposes 
* the bound properties text, value and editValid. 
*
* @author  Karsten Lentzsch
* @version $Revision: 1.9 $
* 
* @see     JFormattedTextField
* @see     JFormattedTextField.AbstractFormatter
*/

public final class NumberExample {

   public static void main(String[] args) {
       try {
           UIManager.setLookAndFeel("com.jgoodies.looks.plastic.PlasticXPLookAndFeel");
       } catch (Exception e) {
           // Likely Plastic is not in the classpath; ignore it.
       }
       JFrame frame = new JFrame();
       frame.setTitle("Formatted :: Numbers");
       frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
       JComponent panel = new NumberExample()
               .buildPanel();
       frame.getContentPane().add(panel);
       frame.pack();
       TutorialUtils.locateOnScreenCenter(frame);
       frame.setVisible(true);
   }
   /**
    * Builds and returns a panel with a header row and the sample rows.
    * 
    * @return the example panel with a header and the sample rows
    */
   public JComponent buildPanel() {
       FormLayout layout = new FormLayout(
               "r:max(80dlu;pref), 4dlu, 45dlu, 1dlu, pref, 4dlu, pref, 0:grow");
       DefaultFormBuilder builder = new DefaultFormBuilder(layout);
       builder.setDefaultDialogBorder();
       builder.getPanel().setFocusTraversalPolicy(
               MyFocusTraversalPolicy.INSTANCE);
               
       Utils.appendTitleRow(builder, "Description");
       List fields = appendDemoRows(builder);
       Utils.appendButtonBar(builder, fields, "42", "aa42");
       return builder.getPanel();
   }
   
   
   /**
    * Appends the demo rows to the given builder and returns the List of
    * formatted text fields.
    * 
    * @param builder  the builder used to add components to
    * @return the List of formatted text fields
    */
   private List appendDemoRows(DefaultFormBuilder builder) {
       // The Formatter is choosen by the initial value.
       JFormattedTextField defaultNumberField = 
           new JFormattedTextField(new Long(42));
       
       // The Formatter is choosen by the given Format.
       JFormattedTextField noInitialValueField = 
           new JFormattedTextField(NumberFormat.getIntegerInstance());
       
       // Uses a custom NumberFormat.
       NumberFormat customFormat = NumberFormat.getIntegerInstance();
       customFormat.setMinimumIntegerDigits(3);
       JFormattedTextField customFormatField =
           new JFormattedTextField(new NumberFormatter(customFormat));
       
       // Uses a custom NumberFormatter that prints natural language strings.
       JFormattedTextField customFormatterField =
           new JFormattedTextField(new CustomNumberFormatter());
       
       // Uses a custom FormatterFactory that used different formatters
       // for the display and while editing.
       DefaultFormatterFactory formatterFactory = 
           new DefaultFormatterFactory(new NumberFormatter(),
                                       new CustomNumberFormatter());
       JFormattedTextField formatterFactoryField =
           new JFormattedTextField(formatterFactory);
       
       // Wraps a NumberFormatter to map empty strings to null and vice versa.
       JFormattedTextField numberOrNullField =
           new JFormattedTextField(new EmptyNumberFormatter());
       
       // Wraps a NumberFormatter to map empty strings to -1 and vice versa.
       Integer emptyValue = new Integer(-1);
       JFormattedTextField numberOrEmptyValueField =
           new JFormattedTextField(new EmptyNumberFormatter(emptyValue));
       numberOrEmptyValueField.setValue(emptyValue);
       
       // Commits values on valid edit texts.
       DefaultFormatter formatter = new NumberFormatter();
       formatter.setCommitsOnValidEdit(true);
       JFormattedTextField commitOnValidEditField =
           new JFormattedTextField(formatter);
       // Returns number values of type Integer
       NumberFormatter numberFormatter = new NumberFormatter();
       numberFormatter.setValueClass(Integer.class);
       JFormattedTextField integerField = 
           new JFormattedTextField(numberFormatter);
       
       Format displayFormat = new DisplayFormat(NumberFormat.getIntegerInstance());
       Format typedDisplayFormat = new DisplayFormat(NumberFormat.getIntegerInstance(), true);
       List fields = new LinkedList();
       fields.add(Utils.appendRow(builder, "Default",               defaultNumberField,      typedDisplayFormat));
       fields.add(Utils.appendRow(builder, "No initial value",      noInitialValueField,     displayFormat));
       fields.add(Utils.appendRow(builder, "Empty <-> null",        numberOrNullField,       displayFormat));
       fields.add(Utils.appendRow(builder, "Empty <->   -1",        numberOrEmptyValueField, displayFormat));
       fields.add(Utils.appendRow(builder, "Custom format",         customFormatField,       displayFormat));
       fields.add(Utils.appendRow(builder, "Custom formatter",      customFormatterField,    displayFormat));
       fields.add(Utils.appendRow(builder, "Formatter factory",     formatterFactoryField,   displayFormat));
       fields.add(Utils.appendRow(builder, "Commits on valid edit", commitOnValidEditField,  displayFormat));
       fields.add(Utils.appendRow(builder, "Integer Result",        integerField,            typedDisplayFormat));
       
       return fields;
   }
      

}


 </source>
   
  
 
  



Dynamically change the format

   <source lang="java">
 

import java.text.SimpleDateFormat; import java.util.Date; import javax.swing.JFormattedTextField; import javax.swing.text.DateFormatter; public class Main {

 public static void main(String[] argv) {
   JFormattedTextField f = new JFormattedTextField(new SimpleDateFormat("yyyy-M-d"));
   f.setValue(new Date());
   DateFormatter fmt = (DateFormatter) f.getFormatter();
   fmt.setFormat(new SimpleDateFormat("d/M/yyyy"));
   f.setValue(f.getValue());
 }

}


 </source>
   
  
 
  



Field with different formats with focus and without

   <source lang="java">
 

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// FactoryDemo.java //Demo 1: field with different formats with focus and without.
//Demo 2: Change the format of a field when the user presses a button. // import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.ParseException; import javax.swing.JButton; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.TitledBorder; import javax.swing.text.DefaultFormatterFactory; import javax.swing.text.MaskFormatter; public class FactoryDemo {

 public static JPanel demo1() {
   // Demo 1: field with different formats with focus and without
   JPanel pan = new JPanel(new BorderLayout());
   pan.setBorder(new TitledBorder("Demo 1: format toggles with focus"));
   MaskFormatter withFocus = null, withoutFocus = null;
   try {
     withFocus = new MaskFormatter("LLLL");
     withoutFocus = new MaskFormatter("UUUU");
   } catch (ParseException pe) {
   }
   DefaultFormatterFactory factory = new DefaultFormatterFactory(
       withoutFocus, null, withFocus);
   JFormattedTextField field = new JFormattedTextField(factory);
   field.setValue("Four");
   pan.add(field, BorderLayout.CENTER);
   return pan;
 }
 public static JPanel demo2() {
   // Demo 2: Change the format of a field when the user presses a button.
   // We can"t call field.setFormatter() because that"s a protected method.
   // (Plus it wouldn"t work anyway. The old factory would replace our new
   // formatter with an "old" one next time the field gains or loses
   // focus.)
   // The thing to do is send a new factory to field.setFormatterFactory().
   JPanel pan = new JPanel(new BorderLayout());
   pan.setBorder(new TitledBorder("Demo 2: change format midstream"));
   MaskFormatter lowercase = null;
   try {
     lowercase = new MaskFormatter("LLLL");
   } catch (ParseException pe) {
   }
   final JFormattedTextField field = new JFormattedTextField(lowercase);
   field.setValue("Fore");
   pan.add(field, BorderLayout.CENTER);
   final JButton change = new JButton("change format");
   JPanel changePanel = new JPanel();
   changePanel.add(change);
   pan.add(changePanel, BorderLayout.SOUTH);
   change.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent ae) {
       try {
         field.rumitEdit(); // commit current edit (if any)
         MaskFormatter uppercase = new MaskFormatter("UUUU");
         DefaultFormatterFactory factory = new DefaultFormatterFactory(
             uppercase);
         field.setFormatterFactory(factory);
         change.setEnabled(false);
       } catch (ParseException pe) {
       }
     }
   });
   return pan;
 }
 public static void main(String argv[]) {
   JFrame f = new JFrame("FactoryDemo");
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.getContentPane().add(demo1(), BorderLayout.NORTH);
   f.getContentPane().add(demo2(), BorderLayout.SOUTH);
   f.setSize(240, 160);
   f.setVisible(true);
 }

}


 </source>
   
  
 
  



Format and validate input field in Java Swing

   <source lang="java">
 

import java.awt.BorderLayout; import java.text.NumberFormat; import javax.swing.JButton; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class Main extends JFrame {

 public Main() {
   JPanel panel = new JPanel();
   JLabel label = new JLabel("Number :");
   JFormattedTextField tf = new JFormattedTextField(NumberFormat.getIntegerInstance());
   tf.setColumns(10);
   panel.add(label);
   panel.add(tf);
   JButton button = new JButton("Click Me");
   panel.add(button);
   getContentPane().add(panel, BorderLayout.SOUTH);
   pack();
 }
 public static void main(String[] args) {
   Main tfe = new Main();
   tfe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   tfe.setVisible(true);
 }

}


 </source>
   
  
 
  



Formatted TextField Demo

   <source lang="java">
 

/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistribution of source code must retain the above copyright notice, this
*  list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright notice,
*  this list of conditions and the following disclaimer in the documentation
*  and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

import java.awt.BorderLayout; import java.awt.Color; import java.awt.GridLayout; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.text.NumberFormat; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; /**

* FormattedTextFieldDemo.java is a 1.4 example that
* requires no other files.
*
* It implements a mortgage calculator that uses four
* JFormattedTextFields.
*/

public class FormattedTextFieldDemo extends JPanel

                                   implements PropertyChangeListener {
   //Values for the fields
   private double amount = 100000;
   private double rate = 7.5;  //7.5%
   private int numPeriods = 30;
   //Labels to identify the fields
   private JLabel amountLabel;
   private JLabel rateLabel;
   private JLabel numPeriodsLabel;
   private JLabel paymentLabel;
   //Strings for the labels
   private static String amountString = "Loan Amount: ";
   private static String rateString = "APR (%): ";
   private static String numPeriodsString = "Years: ";
   private static String paymentString = "Monthly Payment: ";
   //Fields for data entry
   private JFormattedTextField amountField;
   private JFormattedTextField rateField;
   private JFormattedTextField numPeriodsField;
   private JFormattedTextField paymentField;
   //Formats to format and parse numbers
   private NumberFormat amountFormat;
   private NumberFormat percentFormat;
   private NumberFormat paymentFormat;
   public FormattedTextFieldDemo() {
       super(new BorderLayout());
       setUpFormats();
       double payment = computePayment(amount,
                                       rate,
                                       numPeriods);
       //Create the labels.
       amountLabel = new JLabel(amountString);
       rateLabel = new JLabel(rateString);
       numPeriodsLabel = new JLabel(numPeriodsString);
       paymentLabel = new JLabel(paymentString);
       //Create the text fields and set them up.
       amountField = new JFormattedTextField(amountFormat);
       amountField.setValue(new Double(amount));
       amountField.setColumns(10);
       amountField.addPropertyChangeListener("value", this);
       rateField = new JFormattedTextField(percentFormat);
       rateField.setValue(new Double(rate));
       rateField.setColumns(10);
       rateField.addPropertyChangeListener("value", this);
       numPeriodsField = new JFormattedTextField();
       numPeriodsField.setValue(new Integer(numPeriods));
       numPeriodsField.setColumns(10);
       numPeriodsField.addPropertyChangeListener("value", this);
       paymentField = new JFormattedTextField(paymentFormat);
       paymentField.setValue(new Double(payment));
       paymentField.setColumns(10);
       paymentField.setEditable(false);
       paymentField.setForeground(Color.red);
       //Tell accessibility tools about label/textfield pairs.
       amountLabel.setLabelFor(amountField);
       rateLabel.setLabelFor(rateField);
       numPeriodsLabel.setLabelFor(numPeriodsField);
       paymentLabel.setLabelFor(paymentField);
       //Lay out the labels in a panel.
       JPanel labelPane = new JPanel(new GridLayout(0,1));
       labelPane.add(amountLabel);
       labelPane.add(rateLabel);
       labelPane.add(numPeriodsLabel);
       labelPane.add(paymentLabel);
       //Layout the text fields in a panel.
       JPanel fieldPane = new JPanel(new GridLayout(0,1));
       fieldPane.add(amountField);
       fieldPane.add(rateField);
       fieldPane.add(numPeriodsField);
       fieldPane.add(paymentField);
       //Put the panels in this panel, labels on left,
       //text fields on right.
       setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
       add(labelPane, BorderLayout.CENTER);
       add(fieldPane, BorderLayout.LINE_END);
   }
   /** Called when a field"s "value" property changes. */
   public void propertyChange(PropertyChangeEvent e) {
       Object source = e.getSource();
       if (source == amountField) {
           amount = ((Number)amountField.getValue()).doubleValue();
       } else if (source == rateField) {
           rate = ((Number)rateField.getValue()).doubleValue();
       } else if (source == numPeriodsField) {
           numPeriods = ((Number)numPeriodsField.getValue()).intValue();
       }
       double payment = computePayment(amount, rate, numPeriods);
       paymentField.setValue(new Double(payment));
   }
   /**
    * Create the GUI and show it.  For thread safety,
    * this method should be invoked from the
    * event-dispatching thread.
    */
   private static void createAndShowGUI() {
       //Make sure we have nice window decorations.
       JFrame.setDefaultLookAndFeelDecorated(true);
       //Create and set up the window.
       JFrame frame = new JFrame("FormattedTextFieldDemo");
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       //Create and set up the content pane.
       JComponent newContentPane = new FormattedTextFieldDemo();
       newContentPane.setOpaque(true); //content panes must be opaque
       frame.setContentPane(newContentPane);
       //Display the window.
       frame.pack();
       frame.setVisible(true);
   }
   public static void main(String[] args) {
       //Schedule a job for the event-dispatching thread:
       //creating and showing this application"s GUI.
       javax.swing.SwingUtilities.invokeLater(new Runnable() {
           public void run() {
               createAndShowGUI();
           }
       });
   }
   //Compute the monthly payment based on the loan amount,
   //APR, and length of loan.
   double computePayment(double loanAmt, double rate, int numPeriods) {
       double I, partial1, denominator, answer;
       numPeriods *= 12;        //get number of months
       if (rate > 0.01) {
           I = rate / 100.0 / 12.0;         //get monthly rate from annual
           partial1 = Math.pow((1 + I), (0.0 - numPeriods));
           denominator = (1 - partial1) / I;
       } else { //rate ~= 0
           denominator = numPeriods;
       }
       answer = (-1 * loanAmt) / denominator;
       return answer;
   }
   //Create and set up number formats. These objects also
   //parse numbers input by user.
   private void setUpFormats() {
       amountFormat = NumberFormat.getNumberInstance();
       percentFormat = NumberFormat.getNumberInstance();
       percentFormat.setMinimumFractionDigits(3);
       paymentFormat = NumberFormat.getCurrencyInstance();
   }

}



 </source>
   
  
 
  



Formatted TextField Example

   <source lang="java">
 

/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall

  • /

import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Shape; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JTextField; import javax.swing.UIManager; import javax.swing.event.DocumentEvent; import javax.swing.plaf.ruponentUI; import javax.swing.plaf.metal.MetalTextFieldUI; import javax.swing.text.AbstractDocument; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.Caret; import javax.swing.text.Document; import javax.swing.text.Element; import javax.swing.text.FieldView; import javax.swing.text.JTextComponent; import javax.swing.text.PlainDocument; import javax.swing.text.Position; import javax.swing.text.Segment; import javax.swing.text.Utilities; import javax.swing.text.View; import javax.swing.text.ViewFactory; public class FormattedTextFieldExample {

 public static void main(String[] args) {
   try {
       UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
   } catch (Exception evt) {}
 
   JFrame f = new JFrame("Formatted Text Field");
   final FormattedTextField tf = new FormattedTextField();
   FormattedTextField.FormatSpec formatSpec = new FormattedTextField.FormatSpec(
       "(...)-...-....", "(***)-***-****");
   tf.setFormatSpec(formatSpec);
   f.getContentPane().add(tf, "Center");
   f.getContentPane().add(new JLabel("Phone Number: ", JLabel.RIGHT),
       "West");
   tf.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent evt) {
       System.out.println("Field content is <" + tf.getText() + ">");
     }
   });
   f.pack();
   f.setVisible(true);
 }

} class FormattedTextField extends JTextField {

 public FormattedTextField() {
   this(null, null, 0, null);
 }
 public FormattedTextField(String text, FormatSpec spec) {
   this(null, text, 0, spec);
 }
 public FormattedTextField(int columns, FormatSpec spec) {
   this(null, null, columns, spec);
 }
 public FormattedTextField(String text, int columns, FormatSpec spec) {
   this(null, text, columns, spec);
 }
 public FormattedTextField(Document doc, String text, int columns,
     FormatSpec spec) {
   super(doc, text, columns);
   setFont(new Font("monospaced", Font.PLAIN, 14));
   if (spec != null) {
     setFormatSpec(spec);
   }
 }
 public void updateUI() {
   setUI(new FormattedTextFieldUI());
 }
 public FormatSpec getFormatSpec() {
   return formatSpec;
 }
 public void setFormatSpec(FormattedTextField.FormatSpec formatSpec) {
   FormatSpec oldFormatSpec = this.formatSpec;
   // Do nothing if no change to the format specification
   if (formatSpec.equals(oldFormatSpec) == false) {
     this.formatSpec = formatSpec;
     // Limit the input to the number of markers.
     Document doc = getDocument();
     if (doc instanceof BoundedPlainDocument) {
       ((BoundedPlainDocument) doc).setMaxLength(formatSpec
           .getMarkerCount());
     }
     // Notify a change in the format spec
     firePropertyChange(FORMAT_PROPERTY, oldFormatSpec, formatSpec);
   }
 }
 // Use a model that bounds the input length
 protected Document createDefaultModel() {
   BoundedPlainDocument doc = new BoundedPlainDocument();
   doc
       .addInsertErrorListener(new BoundedPlainDocument.InsertErrorListener() {
         public void insertFailed(BoundedPlainDocument doc,
             int offset, String str, AttributeSet a) {
           // Beep when the field is full
           Toolkit.getDefaultToolkit().beep();
         }
       });
   return doc;
 }
 public static class FormatSpec {
   public FormatSpec(String format, String mask) {
     this.format = format;
     this.mask = mask;
     this.formatSize = format.length();
     if (formatSize != mask.length()) {
       throw new IllegalArgumentException(
           "Format and mask must be the same size");
     }
     for (int i = 0; i < formatSize; i++) {
       if (mask.charAt(i) == MARKER_CHAR) {
         markerCount++;
       }
     }
   }
   public String getFormat() {
     return format;
   }
   public String getMask() {
     return mask;
   }
   public int getFormatSize() {
     return formatSize;
   }
   public int getMarkerCount() {
     return markerCount;
   }
   public boolean equals(Object fmt) {
     return fmt != null && (fmt instanceof FormatSpec)
         && ((FormatSpec) fmt).getFormat().equals(format)
         && ((FormatSpec) fmt).getMask().equals(mask);
   }
   public String toString() {
     return "FormatSpec with format <" + format + ">, mask <" + mask
         + ">";
   }
   private String format;
   private String mask;
   private int formatSize;
   private int markerCount;
   public static final char MARKER_CHAR = "*";
 }
 protected FormatSpec formatSpec;
 public static final String FORMAT_PROPERTY = "format";

} class BoundedPlainDocument extends PlainDocument {

 public BoundedPlainDocument() {
   // Default constructor - must use setMaxLength later
   this.maxLength = 0;
 }
 public BoundedPlainDocument(int maxLength) {
   this.maxLength = maxLength;
 }
 public BoundedPlainDocument(AbstractDocument.Content content, int maxLength) {
   super(content);
   if (content.length() > maxLength) {
     throw new IllegalArgumentException(
         "Initial content larger than maximum size");
   }
   this.maxLength = maxLength;
 }
 public void setMaxLength(int maxLength) {
   if (getLength() > maxLength) {
     throw new IllegalArgumentException(
         "Current content larger than new maximum size");
   }
   this.maxLength = maxLength;
 }
 public int getMaxLength() {
   return maxLength;
 }
 public void insertString(int offset, String str, AttributeSet a)
     throws BadLocationException {
   if (str == null) {
     return;
   }
   // Note: be careful here - the content always has a
   // trailing newline, which should not be counted!
   int capacity = maxLength + 1 - getContent().length();
   if (capacity >= str.length()) {
     // It all fits
     super.insertString(offset, str, a);
   } else {
     // It doesn"t all fit. Add as much as we can.
     if (capacity > 0) {
       super.insertString(offset, str.substring(0, capacity), a);
     }
     // Finally, signal an error.
     if (errorListener != null) {
       errorListener.insertFailed(this, offset, str, a);
     }
   }
 }
 public void addInsertErrorListener(InsertErrorListener l) {
   if (errorListener == null) {
     errorListener = l;
     return;
   }
   throw new IllegalArgumentException(
       "InsertErrorListener already registered");
 }
 public void removeInsertErrorListener(InsertErrorListener l) {
   if (errorListener == l) {
     errorListener = null;
   }
 }
 public interface InsertErrorListener {
   public abstract void insertFailed(BoundedPlainDocument doc, int offset,
       String str, AttributeSet a);
 }
 protected InsertErrorListener errorListener; // Unicast listener
 protected int maxLength;

} class FormattedTextFieldUI extends MetalTextFieldUI implements

   PropertyChangeListener {
 public static ComponentUI createUI(JComponent c) {
   return new FormattedTextFieldUI();
 }
 public FormattedTextFieldUI() {
   super();
 }
 public void installUI(JComponent c) {
   super.installUI(c);
   if (c instanceof FormattedTextField) {
     c.addPropertyChangeListener(this);
     editor = (FormattedTextField) c;
     formatSpec = editor.getFormatSpec();
   }
 }
 public void uninstallUI(JComponent c) {
   super.uninstallUI(c);
   c.removePropertyChangeListener(this);
 }
 public void propertyChange(PropertyChangeEvent evt) {
   if (evt.getPropertyName().equals(FormattedTextField.FORMAT_PROPERTY)) {
     // Install the new format specification
     formatSpec = editor.getFormatSpec();
     // Recreate the View hierarchy
     modelChanged();
   }
 }
 // ViewFactory method - creates a view
 public View create(Element elem) {
   return new FormattedFieldView(elem, formatSpec);
 }
 protected FormattedTextField.FormatSpec formatSpec;
 protected FormattedTextField editor;

} class FormattedFieldView extends FieldView {

 public FormattedFieldView(Element elem,
     FormattedTextField.FormatSpec formatSpec) {
   super(elem);
   this.contentBuff = new Segment();
   this.measureBuff = new Segment();
   this.workBuff = new Segment();
   this.element = elem;
   buildMapping(formatSpec); // Build the model -> view map
   createContent(); // Update content string
 }
 // View methods start here
 public float getPreferredSpan(int axis) {
   int widthFormat;
   int widthContent;
   if (formatSize == 0 || axis == View.Y_AXIS) {
     return super.getPreferredSpan(axis);
   }
   widthFormat = Utilities.getTabbedTextWidth(measureBuff,
       getFontMetrics(), 0, this, 0);
   widthContent = Utilities.getTabbedTextWidth(contentBuff,
       getFontMetrics(), 0, this, 0);
   return Math.max(widthFormat, widthContent);
 }
 public Shape modelToView(int pos, Shape a, Position.Bias b)
     throws BadLocationException {
   a = adjustAllocation(a);
   Rectangle r = new Rectangle(a.getBounds());
   FontMetrics fm = getFontMetrics();
   r.height = fm.getHeight();
   int oldCount = contentBuff.count;
   if (pos < offsets.length) {
     contentBuff.count = offsets[pos];
   } else {
     // Beyond the end: point to the location
     // after the last model position.
     contentBuff.count = offsets[offsets.length - 1] + 1;
   }
   int offset = Utilities.getTabbedTextWidth(contentBuff, metrics, 0,
       this, element.getStartOffset());
   contentBuff.count = oldCount;
   r.x += offset;
   r.width = 1;
   return r;
 }
 public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias) {
   a = adjustAllocation(a);
   bias[0] = Position.Bias.Forward;
   int x = (int) fx;
   int y = (int) fy;
   Rectangle r = a.getBounds();
   int startOffset = element.getStartOffset();
   int endOffset = element.getEndOffset();
   if (y < r.y || x < r.x) {
     return startOffset;
   } else if (y > r.y + r.height || x > r.x + r.width) {
     return endOffset - 1;
   }
   // The given position is within the bounds of the view.
   int offset = Utilities.getTabbedTextOffset(contentBuff,
       getFontMetrics(), r.x, x, this, startOffset);
   // The offset includes characters not in the model,
   // so get rid of them to return a true model offset.
   for (int i = 0; i < offsets.length; i++) {
     if (offset <= offsets[i]) {
       offset = i;
       break;
     }
   }
   // Don"t return an offset beyond the data
   // actually in the model.
   if (offset > endOffset - 1) {
     offset = endOffset - 1;
   }
   return offset;
 }
 public void insertUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
   super.insertUpdate(changes, adjustAllocation(a), f);
   createContent(); // Update content string
 }
 public void removeUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
   super.removeUpdate(changes, adjustAllocation(a), f);
   createContent(); // Update content string
 }
 // End of View methods
 // View drawing methods: overridden from PlainView
 protected void drawLine(int line, Graphics g, int x, int y) {
   // Set the colors
   JTextComponent host = (JTextComponent) getContainer();
   unselected = (host.isEnabled()) ? host.getForeground() : host
       .getDisabledTextColor();
   Caret c = host.getCaret();
   selected = c.isSelectionVisible() ? host.getSelectedTextColor()
       : unselected;
   int p0 = element.getStartOffset();
   int p1 = element.getEndOffset() - 1;
   int sel0 = ((JTextComponent) getContainer()).getSelectionStart();
   int sel1 = ((JTextComponent) getContainer()).getSelectionEnd();
   try {
     // If the element is empty or there is no selection
     // in this view, just draw the whole thing in one go.
     if (p0 == p1 || sel0 == sel1 || inView(p0, p1, sel0, sel1) == false) {
       drawUnselectedText(g, x, y, 0, contentBuff.count);
       return;
     }
     // There is a selection in this view. Draw up to three regions:
     //  (a) The unselected region before the selection.
     //  (b) The selected region.
     //  (c) The unselected region after the selection.
     // First, map the selected region offsets to be relative
     // to the start of the region and then map them to view
     // offsets so that they take into account characters not
     // present in the model.
     int mappedSel0 = mapOffset(Math.max(sel0 - p0, 0));
     int mappedSel1 = mapOffset(Math.min(sel1 - p0, p1 - p0));
     if (mappedSel0 > 0) {
       // Draw an initial unselected region
       x = drawUnselectedText(g, x, y, 0, mappedSel0);
     }
     x = drawSelectedText(g, x, y, mappedSel0, mappedSel1);
     if (mappedSel1 < contentBuff.count) {
       drawUnselectedText(g, x, y, mappedSel1, contentBuff.count);
     }
   } catch (BadLocationException e) {
     // Should not happen!
   }
 }
 protected int drawUnselectedText(Graphics g, int x, int y, int p0, int p1)
     throws BadLocationException {
   g.setColor(unselected);
   workBuff.array = contentBuff.array;
   workBuff.offset = p0;
   workBuff.count = p1 - p0;
   return Utilities.drawTabbedText(workBuff, x, y, g, this, p0);
 }
 protected int drawSelectedText(Graphics g, int x, int y, int p0, int p1)
     throws BadLocationException {
   workBuff.array = contentBuff.array;
   workBuff.offset = p0;
   workBuff.count = p1 - p0;
   g.setColor(selected);
   return Utilities.drawTabbedText(workBuff, x, y, g, this, p0);
 }
 // End of View drawing methods
 // Build the model-to-view mapping
 protected void buildMapping(FormattedTextField.FormatSpec formatSpec) {
   formatSize = formatSpec != null ? formatSpec.getFormatSize() : 0;
   if (formatSize != 0) {
     // Save the format string as a character array
     formatChars = formatSpec.getFormat().toCharArray();
     // Allocate a buffer to store the formatted string
     formattedContent = new char[formatSize];
     contentBuff.offset = 0;
     contentBuff.count = formatSize;
     contentBuff.array = formattedContent;
     // Keep the mask for computing
     // the preferred horizontal span, but use
     // a wide character for measurement
     char[] maskChars = formatSpec.getMask().toCharArray();
     measureBuff.offset = 0;
     measureBuff.array = maskChars;
     measureBuff.count = formatSize;
     // Get the number of markers
     markerCount = formatSpec.getMarkerCount();
     // Allocate an array to hold the offsets
     offsets = new int[markerCount];
     // Create the offset array
     markerCount = 0;
     for (int i = 0; i < formatSize; i++) {
       if (maskChars[i] == FormattedTextField.FormatSpec.MARKER_CHAR) {
         offsets[markerCount++] = i;
         // Replace marker with a wide character
         // in the array used for measurement.
         maskChars[i] = WIDE_CHARACTER;
       }
     }
   }
 }
 // Use the document content and the format
 // string to build the display content
 protected void createContent() {
   try {
     Document doc = getDocument();
     int startOffset = element.getStartOffset();
     int endOffset = element.getEndOffset();
     int length = endOffset - startOffset - 1;
     // If there is no format, use the raw data.
     if (formatSize != 0) {
       // Get the document content
       doc.getText(startOffset, length, workBuff);
       // Initialize the output buffer with the
       // format string.
       System.arraycopy(formatChars, 0, formattedContent, 0,
           formatSize);
       // Insert the model content into
       // the target string.
       int count = Math.min(length, markerCount);
       int firstOffset = workBuff.offset;
       // Place the model data into the output array
       for (int i = 0; i < count; i++) {
         formattedContent[offsets[i]] = workBuff.array[i
             + firstOffset];
       }
     } else {
       doc.getText(startOffset, length, contentBuff);
     }
   } catch (BadLocationException bl) {
     contentBuff.count = 0;
   }
 }
 // Map a document offset to a view offset.
 protected int mapOffset(int pos) {
   pos -= element.getStartOffset();
   if (pos >= offsets.length) {
     return contentBuff.count;
   } else {
     return offsets[pos];
   }
 }
 // Determines whether the selection intersects
 // a given range of model offsets.
 protected boolean inView(int p0, int p1, int sel0, int sel1) {
   if (sel0 >= p0 && sel0 < p1) {
     return true;
   }
   if (sel0 < p0 && sel1 >= p0) {
     return true;
   }
   return false;
 }
 protected char[] formattedContent; // The formatted content for display
 protected char[] formatChars; // The format string as characters
 protected Segment contentBuff; // Segment pointing to formatted content
 protected Segment measureBuff; // Segment pointing to mask string
 protected Segment workBuff; // Segment used for scratch purposes
 protected Element element; // The mapped element
 protected int[] offsets; // Model-to-view offsets
 protected Color selected; // Selected text color
 protected Color unselected; // Unselected text color
 protected int formatSize; // Length of the formatting string
 protected int markerCount; // Number of markers in the format
 protected static final char WIDE_CHARACTER = "m";

}


 </source>
   
  
 
  



Formatter Factory Demo

   <source lang="java">
 

/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistribution of source code must retain the above copyright notice, this
*  list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright notice,
*  this list of conditions and the following disclaimer in the documentation
*  and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

import java.awt.BorderLayout; import java.awt.Color; import java.awt.GridLayout; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.text.NumberFormat; import java.text.ParseException; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.text.DefaultFormatterFactory; import javax.swing.text.NumberFormatter; /**

* FormatterFactoryDemo.java is a 1.4 example that
* requires no other files.
*/

public class FormatterFactoryDemo extends JPanel

                                 implements PropertyChangeListener {
   //Values for the text fields
   private double amount = 100000;
   private double rate = .075;  //7.5 %
   private int numPeriods = 30;
   //Labels to identify the fields
   private JLabel amountLabel;
   private JLabel rateLabel;
   private JLabel numPeriodsLabel;
   private JLabel paymentLabel;
   //Strings for the labels
   private static String amountString = "Loan Amount: ";
   private static String rateString = "APR (%): ";
   private static String numPeriodsString = "Years: ";
   private static String paymentString = "Monthly Payment: ";
   //Fields for data entry
   private JFormattedTextField amountField;
   private JFormattedTextField rateField;
   private JFormattedTextField numPeriodsField;
   private JFormattedTextField paymentField;
   //Formats to format and parse numbers
   private NumberFormat amountDisplayFormat;
   private NumberFormat amountEditFormat;
   private NumberFormat percentDisplayFormat;
   private NumberFormat percentEditFormat;
   private NumberFormat paymentFormat;
   public FormatterFactoryDemo() {
       super(new BorderLayout());
       setUpFormats();
       double payment = computePayment(amount,
                                       rate,
                                       numPeriods);
       //Create the labels.
       amountLabel = new JLabel(amountString);
       rateLabel = new JLabel(rateString);
       numPeriodsLabel = new JLabel(numPeriodsString);
       paymentLabel = new JLabel(paymentString);
       //Create the text fields and set them up.
       amountField = new JFormattedTextField(
                           new DefaultFormatterFactory(
                               new NumberFormatter(amountDisplayFormat),
                               new NumberFormatter(amountDisplayFormat),
                               new NumberFormatter(amountEditFormat)));
       amountField.setValue(new Double(amount));
       amountField.setColumns(10);
       amountField.addPropertyChangeListener("value", this);
       NumberFormatter percentEditFormatter =
               new NumberFormatter(percentEditFormat) {
           public String valueToString(Object o)
                 throws ParseException {
               Number number = (Number)o;
               if (number != null) {
                   double d = number.doubleValue() * 100.0;
                   number = new Double(d);
               }
               return super.valueToString(number);
           }
           public Object stringToValue(String s)
                  throws ParseException {
               Number number = (Number)super.stringToValue(s);
               if (number != null) {
                   double d = number.doubleValue() / 100.0;
                   number = new Double(d);
               }
               return number;
           }
       };
       rateField = new JFormattedTextField(
                            new DefaultFormatterFactory(
                               new NumberFormatter(percentDisplayFormat),
                               new NumberFormatter(percentDisplayFormat),
                               percentEditFormatter));
       rateField.setValue(new Double(rate));
       rateField.setColumns(10);
       rateField.addPropertyChangeListener("value", this);
       numPeriodsField = new JFormattedTextField();
       numPeriodsField.setValue(new Integer(numPeriods));
       numPeriodsField.setColumns(10);
       numPeriodsField.addPropertyChangeListener("value", this);
       paymentField = new JFormattedTextField(paymentFormat);
       paymentField.setValue(new Double(payment));
       paymentField.setColumns(10);
       paymentField.setEditable(false);
       paymentField.setForeground(Color.red);
       //Tell accessibility tools about label/textfield pairs.
       amountLabel.setLabelFor(amountField);
       rateLabel.setLabelFor(rateField);
       numPeriodsLabel.setLabelFor(numPeriodsField);
       paymentLabel.setLabelFor(paymentField);
       //Lay out the labels in a panel.
       JPanel labelPane = new JPanel(new GridLayout(0,1));
       labelPane.add(amountLabel);
       labelPane.add(rateLabel);
       labelPane.add(numPeriodsLabel);
       labelPane.add(paymentLabel);
       //Layout the text fields in a panel.
       JPanel fieldPane = new JPanel(new GridLayout(0,1));
       fieldPane.add(amountField);
       fieldPane.add(rateField);
       fieldPane.add(numPeriodsField);
       fieldPane.add(paymentField);
       //Put the panels in this panel, labels on left,
       //text fields on right.
       setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
       add(labelPane, BorderLayout.CENTER);
       add(fieldPane, BorderLayout.LINE_END);
   }
   /** Called when a field"s "value" property changes. */
   public void propertyChange(PropertyChangeEvent e) {
       Object source = e.getSource();
       if (source == amountField) {
           amount = ((Number)amountField.getValue()).doubleValue();
       } else if (source == rateField) {
           rate = ((Number)rateField.getValue()).doubleValue();
       } else if (source == numPeriodsField) {
           numPeriods = ((Number)numPeriodsField.getValue()).intValue();
       }
       double payment = computePayment(amount, rate, numPeriods);
       paymentField.setValue(new Double(payment));
   }
   /**
    * Create the GUI and show it.  For thread safety,
    * this method should be invoked from the
    * event-dispatching thread.
    */
   private static void createAndShowGUI() {
       //Make sure we have nice window decorations.
       JFrame.setDefaultLookAndFeelDecorated(true);
       //Create and set up the window.
       JFrame frame = new JFrame("FormatterFactoryDemo");
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       //Create and set up the content pane.
       JComponent newContentPane = new FormatterFactoryDemo();
       newContentPane.setOpaque(true); //content panes must be opaque
       frame.setContentPane(newContentPane);
       //Display the window.
       frame.pack();
       frame.setVisible(true);
   }
   public static void main(String[] args) {
       //Schedule a job for the event-dispatching thread:
       //creating and showing this application"s GUI.
       javax.swing.SwingUtilities.invokeLater(new Runnable() {
           public void run() {
               createAndShowGUI();
           }
       });
   }
   //Compute the monthly payment based on the loan amount,
   //APR, and length of loan.
   double computePayment(double loanAmt, double rate, int numPeriods) {
       double I, partial1, denominator, answer;
       numPeriods *= 12;        //get number of months
       if (rate > 0.001) {
           I = rate / 12.0;         //get monthly rate from annual
           partial1 = Math.pow((1 + I), (0.0 - numPeriods));
           denominator = (1 - partial1) / I;
       } else { //rate ~= 0
           denominator = numPeriods;
       }
       answer = (-1 * loanAmt) / denominator;
       return answer;
   }
   //Create and set up number formats. These objects also
   //parse numbers input by user.
   private void setUpFormats() {
       amountDisplayFormat = NumberFormat.getCurrencyInstance();
       amountDisplayFormat.setMinimumFractionDigits(0);
       amountEditFormat = NumberFormat.getNumberInstance();
       percentDisplayFormat = NumberFormat.getPercentInstance();
       percentDisplayFormat.setMinimumFractionDigits(2);
       percentEditFormat = NumberFormat.getNumberInstance();
       percentEditFormat.setMinimumFractionDigits(2);
       paymentFormat = NumberFormat.getCurrencyInstance();
   }

}



 </source>
   
  
 
  



Input: any number of hyphen-delimeted numbers. Output: int array

   <source lang="java">
 

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// CombinationFormatter.java //Input: string of form "15-45-22" (any number of hyphen-delimeted numbers) //
Output: int array // import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JButton; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.text.DefaultFormatter; public class CombinationFormatter extends DefaultFormatter {

 public CombinationFormatter() {
   setOverwriteMode(false);
 }
 public Object stringToValue(String string) throws java.text.ParseException {
   // input: string of form "15-45-22" (any number of hyphen-delimeted
   // numbers)
   // output: int array
   String s[] = string.split("-");
   int a[] = new int[s.length];
   for (int j = 0; j < a.length; j += 1)
     try {
       a[j] = Integer.parseInt(s[j]);
     } catch (NumberFormatException nfe) {
       throw new java.text.ParseException(s[j] + " is not an int", 0);
     }
   return a;
 }
 public String valueToString(Object value) throws java.text.ParseException {
   //  input: int array
   // output: string of numerals separated by hyphens
   if (value == null)
     return null;
   if (!(value instanceof int[]))
     throw new java.text.ParseException("expected int[]", 0);
   int a[] = (int[]) value;
   StringBuffer sb = new StringBuffer();
   for (int j = 0; j < a.length; j += 1) {
     if (j > 0)
       sb.append("-");
     sb.append(a[j]);
   }
   return sb.toString();
 }
 protected Action[] getActions() {
   Action[] actions = { new CombinationIncrementer("increment", 1),
       new CombinationIncrementer("decrement", -1) };
   return actions;
 }
 // begin inner class ----------------------------------------
 public class CombinationIncrementer extends AbstractAction {
   protected int delta;
   public CombinationIncrementer(String name, int delta) { // constructor
     super(name); // "name" must match something in the component"s
            // InputMap
     // or else this Action will not get invoked automatically.
     // Valid names include: "reset-field-edit", "increment",
     // "decrement", and "unselect" (see appendix B)
     this.delta = delta;
   }
   public void actionPerformed(java.awt.event.ActionEvent ae) {
     JFormattedTextField ftf = getFormattedTextField(); // from
                                // AbstractFormtter
     if (ftf == null)
       return;
     String text = ftf.getText();
     if (text == null)
       return;
     int pos = ftf.getCaretPosition();
     int hyphenCount = 0;
     for (int j = 0; j < pos; j += 1)
       // how many hyphens precede the caret?
       if (text.charAt(j) == "-")
         hyphenCount += 1;
     try {
       int a[] = (int[]) stringToValue(text);
       a[hyphenCount] += delta; // change the number at caret position
       if (a[hyphenCount] < 0)
         a[hyphenCount] = 0;
       String newText = valueToString(a);
       ftf.setText(newText); // does not retain caret position
       if ((text.charAt(pos) == "-")
           && (newText.length() < text.length()))
         pos -= 1; // don"t let caret move past "-" when "10" changes
               // to "9"
       ftf.setCaretPosition(pos);
     } catch (Exception e) {
       return;
     }
   }
 }
 // end inner class ----------------------------------------
 public static void main(String argv[]) {
   // a demo main() to show how CombinationFormatter could be used
   int comb1[] = { 35, 11, 19 };
   int comb2[] = { 10, 20, 30 };
   final JFormattedTextField field1 = new JFormattedTextField(
       new CombinationFormatter());
   field1.setValue(comb1);
   final JFormattedTextField field2 = new JFormattedTextField(
       new CombinationFormatter());
   field2.setValue(comb2);
   JPanel pan = new JPanel();
   pan.add(new JLabel("Change the combination from"));
   pan.add(field1);
   pan.add(new JLabel("to"));
   pan.add(field2);
   JButton b = new JButton("Submit");
   b.addActionListener(new java.awt.event.ActionListener() {
     public void actionPerformed(java.awt.event.ActionEvent ae) {
       try {
         field1.rumitEdit(); // make sure current edit (if any) gets
                    // committed
         field2.rumitEdit();
       } catch (java.text.ParseException pe) {
       }
       int oldc[] = (int[]) field1.getValue();
       int newc[] = (int[]) field2.getValue();
       //
       // code to validate oldc[] and change to newc[] goes here
       //
     }
   });
   pan.add(b);
   JFrame f = new JFrame("CombinationFormatter Demo");
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.setContentPane(pan);
   f.setSize(360, 100);
   f.setVisible(true);
 }

}


 </source>
   
  
 
  



Input Verification Demo

   <source lang="java">
 

/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistribution of source code must retain the above copyright notice, this
*  list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright notice,
*  this list of conditions and the following disclaimer in the documentation
*  and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

/*

* InputVerificationDemo.java is a 1.4 example that
* requires no other files.
*/

import java.awt.BorderLayout; import java.awt.Color; import java.awt.GridLayout; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.ParseException; import javax.swing.BorderFactory; import javax.swing.InputVerifier; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; /**

* InputVerificationDemo.java is a 1.4 example that requires no other files.
* 
* Yet another mortgage calculator. However, instead of using a formatted text
* field, as shown in FormattedTextFieldDemo, this example uses input
* verification to validate user input.
*/

public class InputVerificationDemo extends JPanel {

 //Default values
 private static double DEFAULT_AMOUNT = 100000;
 private static double DEFAULT_RATE = 7.5; //7.5%
 private static int DEFAULT_PERIOD = 30;
 //Labels to identify the text fields
 private JLabel amountLabel;
 private JLabel rateLabel;
 private JLabel numPeriodsLabel;
 private JLabel paymentLabel;
 //Strings for the labels
 private static String amountString = "Loan Amount (10,000-10,000,000): ";
 private static String rateString = "APR (>= 0%): ";
 private static String numPeriodsString = "Years (1-40): ";
 private static String paymentString = "Monthly Payment: ";
 //Text fields for data entry
 private JTextField amountField;
 private JTextField rateField;
 private JTextField numPeriodsField;
 private JTextField paymentField;
 //Formats to format and parse numbers
 private NumberFormat moneyFormat;
 private NumberFormat percentFormat;
 private DecimalFormat decimalFormat;
 private DecimalFormat paymentFormat;
 private MyVerifier verifier = new MyVerifier();
 public InputVerificationDemo() {
   super(new BorderLayout());
   setUpFormats();
   double payment = computePayment(DEFAULT_AMOUNT, DEFAULT_RATE,
       DEFAULT_PERIOD);
   //Create the labels.
   amountLabel = new JLabel(amountString);
   rateLabel = new JLabel(rateString);
   numPeriodsLabel = new JLabel(numPeriodsString);
   paymentLabel = new JLabel(paymentString);
   //Create the text fields and set them up.
   amountField = new JTextField(moneyFormat.format(DEFAULT_AMOUNT), 10);
   amountField.setInputVerifier(verifier);
   rateField = new JTextField(percentFormat.format(DEFAULT_RATE), 10);
   rateField.setInputVerifier(verifier);
   numPeriodsField = new JTextField(decimalFormat.format(DEFAULT_PERIOD),
       10);
   numPeriodsField.setInputVerifier(verifier);
   paymentField = new JTextField(paymentFormat.format(payment), 10);
   paymentField.setInputVerifier(verifier);
   paymentField.setEditable(false);
   //Remove this component from the focus cycle.
   paymentField.setFocusable(false);
   paymentField.setForeground(Color.red);
   //Register an action listener to handle Return.
   amountField.addActionListener(verifier);
   rateField.addActionListener(verifier);
   numPeriodsField.addActionListener(verifier);
   //Tell accessibility tools about label/textfield pairs.
   amountLabel.setLabelFor(amountField);
   rateLabel.setLabelFor(rateField);
   numPeriodsLabel.setLabelFor(numPeriodsField);
   paymentLabel.setLabelFor(paymentField);
   //Lay out the labels in a panel.
   JPanel labelPane = new JPanel(new GridLayout(0, 1));
   labelPane.add(amountLabel);
   labelPane.add(rateLabel);
   labelPane.add(numPeriodsLabel);
   labelPane.add(paymentLabel);
   //Layout the text fields in a panel.
   JPanel fieldPane = new JPanel(new GridLayout(0, 1));
   fieldPane.add(amountField);
   fieldPane.add(rateField);
   fieldPane.add(numPeriodsField);
   fieldPane.add(paymentField);
   //Put the panels in this panel, labels on left,
   //text fields on right.
   setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
   add(labelPane, BorderLayout.CENTER);
   add(fieldPane, BorderLayout.LINE_END);
 }
 class MyVerifier extends InputVerifier implements ActionListener {
   double MIN_AMOUNT = 10000.0;
   double MAX_AMOUNT = 10000000.0;
   double MIN_RATE = 0.0;
   int MIN_PERIOD = 1;
   int MAX_PERIOD = 40;
   public boolean shouldYieldFocus(JComponent input) {
     boolean inputOK = verify(input);
     makeItPretty(input);
     updatePayment();
     if (inputOK) {
       return true;
     } else {
       Toolkit.getDefaultToolkit().beep();
       return false;
     }
   }
   protected void updatePayment() {
     double amount = DEFAULT_AMOUNT;
     double rate = DEFAULT_RATE;
     int numPeriods = DEFAULT_PERIOD;
     double payment = 0.0;
     //Parse the values.
     try {
       amount = moneyFormat.parse(amountField.getText()).doubleValue();
     } catch (ParseException pe) {
     }
     try {
       rate = percentFormat.parse(rateField.getText()).doubleValue();
     } catch (ParseException pe) {
     }
     try {
       numPeriods = decimalFormat.parse(numPeriodsField.getText())
           .intValue();
     } catch (ParseException pe) {
     }
     //Calculate the result and update the GUI.
     payment = computePayment(amount, rate, numPeriods);
     paymentField.setText(paymentFormat.format(payment));
   }
   //This method checks input, but should cause no side effects.
   public boolean verify(JComponent input) {
     return checkField(input, false);
   }
   protected void makeItPretty(JComponent input) {
     checkField(input, true);
   }
   protected boolean checkField(JComponent input, boolean changeIt) {
     if (input == amountField) {
       return checkAmountField(changeIt);
     } else if (input == rateField) {
       return checkRateField(changeIt);
     } else if (input == numPeriodsField) {
       return checkNumPeriodsField(changeIt);
     } else {
       return true; //shouldn"t happen
     }
   }
   //Checks that the amount field is valid. If it is valid,
   //it returns true; otherwise, returns false. If the
   //change argument is true, this method reigns in the
   //value if necessary and (even if not) sets it to the
   //parsed number so that it looks good -- no letters,
   //for example.
   protected boolean checkAmountField(boolean change) {
     boolean wasValid = true;
     double amount = DEFAULT_AMOUNT;
     //Parse the value.
     try {
       amount = moneyFormat.parse(amountField.getText()).doubleValue();
     } catch (ParseException pe) {
       wasValid = false;
     }
     //Value was invalid.
     if ((amount < MIN_AMOUNT) || (amount > MAX_AMOUNT)) {
       wasValid = false;
       if (change) {
         if (amount < MIN_AMOUNT) {
           amount = MIN_AMOUNT;
         } else { // amount is greater than MAX_AMOUNT
           amount = MAX_AMOUNT;
         }
       }
     }
     //Whether value was valid or not, format it nicely.
     if (change) {
       amountField.setText(moneyFormat.format(amount));
       amountField.selectAll();
     }
     return wasValid;
   }
   //Checks that the rate field is valid. If it is valid,
   //it returns true; otherwise, returns false. If the
   //change argument is true, this method reigns in the
   //value if necessary and (even if not) sets it to the
   //parsed number so that it looks good -- no letters,
   //for example.
   protected boolean checkRateField(boolean change) {
     boolean wasValid = true;
     double rate = DEFAULT_RATE;
     //Parse the value.
     try {
       rate = percentFormat.parse(rateField.getText()).doubleValue();
     } catch (ParseException pe) {
       wasValid = false;
     }
     //Value was invalid.
     if (rate < MIN_RATE) {
       wasValid = false;
       if (change) {
         rate = MIN_RATE;
       }
     }
     //Whether value was valid or not, format it nicely.
     if (change) {
       rateField.setText(percentFormat.format(rate));
       rateField.selectAll();
     }
     return wasValid;
   }
   //Checks that the numPeriods field is valid. If it is valid,
   //it returns true; otherwise, returns false. If the
   //change argument is true, this method reigns in the
   //value if necessary and (even if not) sets it to the
   //parsed number so that it looks good -- no letters,
   //for example.
   protected boolean checkNumPeriodsField(boolean change) {
     boolean wasValid = true;
     int numPeriods = DEFAULT_PERIOD;
     //Parse the value.
     try {
       numPeriods = decimalFormat.parse(numPeriodsField.getText())
           .intValue();
     } catch (ParseException pe) {
       wasValid = false;
     }
     //Value was invalid.
     if ((numPeriods < MIN_PERIOD) || (numPeriods > MAX_PERIOD)) {
       wasValid = false;
       if (change) {
         if (numPeriods < MIN_PERIOD) {
           numPeriods = MIN_PERIOD;
         } else { // numPeriods is greater than MAX_PERIOD
           numPeriods = MAX_PERIOD;
         }
       }
     }
     //Whether value was valid or not, format it nicely.
     if (change) {
       numPeriodsField.setText(decimalFormat.format(numPeriods));
       numPeriodsField.selectAll();
     }
     return wasValid;
   }
   public void actionPerformed(ActionEvent e) {
     JTextField source = (JTextField) e.getSource();
     shouldYieldFocus(source); //ignore return value
     source.selectAll();
   }
 }
 /**
  * Create the GUI and show it. For thread safety, this method should be
  * invoked from the event-dispatching thread.
  */
 private static void createAndShowGUI() {
   //Make sure we have nice window decorations.
   JFrame.setDefaultLookAndFeelDecorated(true);
   //Create and set up the window.
   JFrame frame = new JFrame("InputVerificationDemo");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   //Create and set up the content pane.
   JComponent newContentPane = new InputVerificationDemo();
   newContentPane.setOpaque(true); //content panes must be opaque
   frame.setContentPane(newContentPane);
   //Display the window.
   frame.pack();
   frame.setVisible(true);
 }
 public static void main(String[] args) {
   //Schedule a job for the event-dispatching thread:
   //creating and showing this application"s GUI.
   javax.swing.SwingUtilities.invokeLater(new Runnable() {
     public void run() {
       createAndShowGUI();
     }
   });
 }
 //Compute the monthly payment based on the loan amount,
 //APR, and length of loan.
 double computePayment(double loanAmt, double rate, int numPeriods) {
   double I, partial1, denominator, answer;
   numPeriods *= 12; //get number of months
   if (rate > 0.01) {
     I = rate / 100.0 / 12.0; //get monthly rate from annual
     partial1 = Math.pow((1 + I), (0.0 - numPeriods));
     denominator = (1 - partial1) / I;
   } else { //rate ~= 0
     denominator = numPeriods;
   }
   answer = (-1 * loanAmt) / denominator;
   return answer;
 }
 //Create and set up number formats. These objects are used
 //for both parsing input and formatting output.
 private void setUpFormats() {
   moneyFormat = (NumberFormat) NumberFormat.getNumberInstance();
   percentFormat = NumberFormat.getNumberInstance();
   percentFormat.setMinimumFractionDigits(3);
   decimalFormat = (DecimalFormat) NumberFormat.getNumberInstance();
   decimalFormat.setParseIntegerOnly(true);
   paymentFormat = (DecimalFormat) NumberFormat.getNumberInstance();
   paymentFormat.setMaximumFractionDigits(2);
   paymentFormat.setNegativePrefix("(");
   paymentFormat.setNegativeSuffix(")");
 }

}


 </source>
   
  
 
  



Input Verification Dialog Demo

   <source lang="java">
 

/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistribution of source code must retain the above copyright notice, this
*  list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright notice,
*  this list of conditions and the following disclaimer in the documentation
*  and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

/*

* InputVerificationDialogDemo.java is a 1.4 example that
* requires no other files.
*/

import java.awt.BorderLayout; import java.awt.Color; import java.awt.GridLayout; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.ParseException; import javax.swing.BorderFactory; import javax.swing.InputVerifier; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; /**

* InputVerificationDialogDemo.java is a 1.4 example that requires no other
* files.
* 
* Yet another mortgage calculator. However, instead of using a formatted text
* field, as shown in FormattedTextFieldDemo, this example uses input
* verification to validate user input. This one uses a dialog to warn people
* when their input is bad.
*/

public class InputVerificationDialogDemo extends JPanel {

 //Default values
 private static double DEFAULT_AMOUNT = 100000;
 private static double DEFAULT_RATE = 7.5; //7.5 %
 private static int DEFAULT_PERIOD = 30;
 //Labels to identify the text fields
 private JLabel amountLabel;
 private JLabel rateLabel;
 private JLabel numPeriodsLabel;
 private JLabel paymentLabel;
 //Strings for the labels
 private static String amountString = "Loan Amount (10,000 - 10,000,000): ";
 private static String rateString = "APR (>= 0%): ";
 private static String numPeriodsString = "Years (1-40): ";
 private static String paymentString = "Monthly Payment: ";
 //Text fields for data entry
 private JTextField amountField;
 private JTextField rateField;
 private JTextField numPeriodsField;
 private JTextField paymentField;
 //Formats to format and parse numbers
 private NumberFormat moneyFormat;
 private NumberFormat percentFormat;
 private DecimalFormat decimalFormat;
 private DecimalFormat paymentFormat;
 private NumberFormat integerFormat;
 private MyVerifier verifier = new MyVerifier();
 public InputVerificationDialogDemo() {
   super(new BorderLayout());
   setUpFormats();
   double payment = computePayment(DEFAULT_AMOUNT, DEFAULT_RATE,
       DEFAULT_PERIOD);
   //Create the labels.
   amountLabel = new JLabel(amountString);
   rateLabel = new JLabel(rateString);
   numPeriodsLabel = new JLabel(numPeriodsString);
   paymentLabel = new JLabel(paymentString);
   //Create the text fields and set them up.
   amountField = new JTextField(moneyFormat.format(DEFAULT_AMOUNT), 10);
   amountField.setInputVerifier(verifier);
   rateField = new JTextField(percentFormat.format(DEFAULT_RATE), 10);
   rateField.setInputVerifier(verifier);
   numPeriodsField = new JTextField(decimalFormat.format(DEFAULT_PERIOD),
       10);
   numPeriodsField.setInputVerifier(verifier);
   paymentField = new JTextField(paymentFormat.format(payment), 10);
   paymentField.setInputVerifier(verifier);
   paymentField.setEditable(false);
   //Remove this component from the focus cycle.
   paymentField.setFocusable(false);
   paymentField.setForeground(Color.red);
   //Register an action listener to handle Return.
   amountField.addActionListener(verifier);
   rateField.addActionListener(verifier);
   numPeriodsField.addActionListener(verifier);
   //Tell accessibility tools about label/textfield pairs.
   amountLabel.setLabelFor(amountField);
   rateLabel.setLabelFor(rateField);
   numPeriodsLabel.setLabelFor(numPeriodsField);
   paymentLabel.setLabelFor(paymentField);
   //Lay out the labels in a panel.
   JPanel labelPane = new JPanel(new GridLayout(0, 1));
   labelPane.add(amountLabel);
   labelPane.add(rateLabel);
   labelPane.add(numPeriodsLabel);
   labelPane.add(paymentLabel);
   //Layout the text fields in a panel.
   JPanel fieldPane = new JPanel(new GridLayout(0, 1));
   fieldPane.add(amountField);
   fieldPane.add(rateField);
   fieldPane.add(numPeriodsField);
   fieldPane.add(paymentField);
   //Put the panels in this panel, labels on left,
   //text fields on right.
   setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
   add(labelPane, BorderLayout.CENTER);
   add(fieldPane, BorderLayout.LINE_END);
 }
 class MyVerifier extends InputVerifier implements ActionListener {
   double MIN_AMOUNT = 10000.0;
   double MAX_AMOUNT = 10000000.0;
   double MIN_RATE = 0.0;
   int MIN_PERIOD = 1;
   int MAX_PERIOD = 40;
   String message = null;
   public boolean shouldYieldFocus(JComponent input) {
     boolean inputOK = verify(input);
     makeItPretty(input);
     updatePayment();
     if (inputOK) {
       return true;
     }
     //Avoid possible focus-transfer problems when bringing up
     //the dialog by temporarily removing the input verifier.
     //This is a workaround for bug #4532517.
     input.setInputVerifier(null);
     //Pop up the message dialog.
     message += ".\nPlease try again.";
     JOptionPane.showMessageDialog(null, //no owner frame
         message, //text to display
         "Invalid Value", //title
         JOptionPane.WARNING_MESSAGE);
     //Reinstall the input verifier.
     input.setInputVerifier(this);
     //Beep and then tell whoever called us that we don"t
     //want to yield focus.
     Toolkit.getDefaultToolkit().beep();
     return false;
   }
   protected void updatePayment() {
     double amount = DEFAULT_AMOUNT;
     double rate = DEFAULT_RATE;
     int numPeriods = DEFAULT_PERIOD;
     double payment = 0.0;
     //Parse the values.
     try {
       amount = moneyFormat.parse(amountField.getText()).doubleValue();
     } catch (ParseException pe) {
     }
     try {
       rate = percentFormat.parse(rateField.getText()).doubleValue();
     } catch (ParseException pe) {
     }
     try {
       numPeriods = decimalFormat.parse(numPeriodsField.getText())
           .intValue();
     } catch (ParseException pe) {
     }
     //Calculate the result and update the GUI.
     payment = computePayment(amount, rate, numPeriods);
     paymentField.setText(paymentFormat.format(payment));
   }
   //This method checks input, but should cause no side effects.
   public boolean verify(JComponent input) {
     return checkField(input, false);
   }
   protected void makeItPretty(JComponent input) {
     checkField(input, true);
   }
   protected boolean checkField(JComponent input, boolean changeIt) {
     if (input == amountField) {
       return checkAmountField(changeIt);
     } else if (input == rateField) {
       return checkRateField(changeIt);
     } else if (input == numPeriodsField) {
       return checkNumPeriodsField(changeIt);
     } else {
       return true; //shouldn"t happen
     }
   }
   //Checks that the amount field is valid. If it is valid,
   //it returns true, otherwise it sets the message field and
   //returns false. If the change argument is true, set
   //the textfield to the parsed number so that it looks
   //good -- no letters, for example.
   public boolean checkAmountField(boolean change) {
     boolean wasValid = true;
     double amount = DEFAULT_AMOUNT;
     //Parse the value.
     try {
       amount = moneyFormat.parse(amountField.getText()).doubleValue();
     } catch (ParseException pe) {
       message = "Invalid money format in Loan Amount field";
       return false;
     }
     //Value was invalid.
     if ((amount < MIN_AMOUNT) || (amount > MAX_AMOUNT)) {
       wasValid = false;
       if (amount < MIN_AMOUNT) {
         message = "Loan Amount was < "
             + integerFormat.format(MIN_AMOUNT);
       } else { //amount is greater than MAX_AMOUNT
         message = "Loan Amount was > "
             + integerFormat.format(MAX_AMOUNT);
       }
     }
     //Whether value was valid or not, format it nicely.
     if (change) {
       amountField.setText(moneyFormat.format(amount));
       amountField.selectAll();
     }
     return wasValid;
   }
   //Checks that the rate field is valid. If it is valid,
   //it returns true, otherwise it sets the message field and
   //returns false. If the change argument is true, set the
   //textfield to the parsed number so that it looks good -- no
   //letters, for example.
   public boolean checkRateField(boolean change) {
     boolean wasValid = true;
     double rate = DEFAULT_RATE;
     //Parse the value.
     try {
       rate = percentFormat.parse(rateField.getText()).doubleValue();
     } catch (ParseException pe) {
       message = "Invalid percent format in APR field";
       return false;
     }
     //Value was invalid.
     if (rate < MIN_RATE) {
       wasValid = false;
       message = "Bad value: APR was < " + MIN_RATE;
     }
     //Whether value was valid or not, format it nicely.
     if (change) {
       rateField.setText(percentFormat.format(rate));
       rateField.selectAll();
     }
     return wasValid;
   }
   //Checks that the numPeriods field is valid. If it is valid,
   //it returns true, otherwise it sets the message field and
   //returns false. If the change argument is true, set the
   //textfield to the parsed number so that it looks good -- no
   //letters, for example.
   public boolean checkNumPeriodsField(boolean change) {
     boolean wasValid = true;
     int numPeriods = DEFAULT_PERIOD;
     //Parse the value.
     try {
       numPeriods = decimalFormat.parse(numPeriodsField.getText())
           .intValue();
     } catch (ParseException pe) {
       message = "Invalid decimal format in Years field";
       return false;
     }
     //Value was invalid.
     if (numPeriods < MIN_PERIOD) {
       wasValid = false;
       message = "Bad value: Number of years was < "
           + integerFormat.format(MIN_PERIOD);
     } else if (numPeriods > MAX_PERIOD) {
       wasValid = false;
       message = "Bad value: Number of years was > "
           + integerFormat.format(MAX_PERIOD);
     }
     //Whether value was valid or not, format it nicely.
     if (change) {
       numPeriodsField.setText(decimalFormat.format(numPeriods));
       numPeriodsField.selectAll();
     }
     return wasValid;
   }
   public void actionPerformed(ActionEvent e) {
     JTextField source = (JTextField) e.getSource();
     shouldYieldFocus(source); //ignore return value
     source.selectAll();
   }
 }
 /**
  * Create the GUI and show it. For thread safety, this method should be
  * invoked from the event-dispatching thread.
  */
 private static void createAndShowGUI() {
   //We can"t set this due to bug #4819813.
   //This bug causes the Java look and feel window
   //decorations to be focusable.
   //JFrame.setDefaultLookAndFeelDecorated(true);
   //Create and set up the window.
   JFrame frame = new JFrame("InputVerificationDialogDemo");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   JComponent newContentPane = new InputVerificationDialogDemo();
   newContentPane.setOpaque(true); //content panes must be opaque
   frame.setContentPane(newContentPane);
   //Display the window.
   frame.pack();
   frame.setVisible(true);
 }
 public static void main(String[] args) {
   //Schedule a job for the event-dispatching thread:
   //creating and showing this application"s GUI.
   javax.swing.SwingUtilities.invokeLater(new Runnable() {
     public void run() {
       createAndShowGUI();
     }
   });
 }
 //Compute the monthly payment based on the loan amount,
 //APR, and length of loan.
 double computePayment(double loanAmt, double rate, int numPeriods) {
   double I, partial1, denominator, answer;
   numPeriods *= 12; //get number of months
   if (rate > 0.01) {
     I = rate / 100.0 / 12.0; //get monthly rate from annual
     partial1 = Math.pow((1 + I), (0.0 - numPeriods));
     denominator = (1 - partial1) / I;
   } else { //rate ~= 0
     denominator = numPeriods;
   }
   answer = (-1 * loanAmt) / denominator;
   return answer;
 }
 //Create and set up number formats. These objects also
 //parse numbers input by user.
 private void setUpFormats() {
   moneyFormat = (NumberFormat) NumberFormat.getNumberInstance();
   percentFormat = NumberFormat.getNumberInstance();
   percentFormat.setMinimumFractionDigits(3);
   decimalFormat = (DecimalFormat) NumberFormat.getNumberInstance();
   decimalFormat.setParseIntegerOnly(true);
   paymentFormat = (DecimalFormat) NumberFormat.getNumberInstance();
   paymentFormat.setMaximumFractionDigits(2);
   paymentFormat.setNegativePrefix("(");
   paymentFormat.setNegativeSuffix(")");
   integerFormat = NumberFormat.getIntegerInstance();
 }

}



 </source>
   
  
 
  



JFormattedTextField: an input mask (###) ###-#### for a telephone number

   <source lang="java">
 

import java.awt.Container; import java.text.ParseException; import javax.swing.BoxLayout; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.text.MaskFormatter; public class Main {

 public static void main(String args[]) throws ParseException {
   JFrame f = new JFrame();
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   Container content = f.getContentPane();
   content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS));
   MaskFormatter mf1 = new MaskFormatter("###-###-###");
   mf1.setPlaceholderCharacter("_");
   JFormattedTextField ftf1 = new JFormattedTextField(mf1);
   content.add(ftf1);
   MaskFormatter mf2 = new MaskFormatter("(###) ###-####");
   JFormattedTextField ftf2 = new JFormattedTextField(mf2);
   content.add(ftf2);
   f.setSize(300, 100);
   f.setVisible(true);
 }

}


 </source>
   
  
 
  



Make custom Input Text Formatter in Java

   <source lang="java">
 

import java.awt.BorderLayout; import java.text.ParseException; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.text.DefaultFormatter; class MyFormatter extends DefaultFormatter {

 public MyFormatter() {
   super();
 }
 public String valueToString(Object arg0) throws ParseException {
   return super.valueToString(arg0);
 }
 public Object stringToValue(String arg0) throws ParseException {
   try {
     int value = Integer.parseInt(arg0);
     if (value >= 1 && value <= 10) {
       return "" + value;
     } else {
       return "Invalid";
     }
   } catch (Exception e) {
     return "Invalid";
   }
 }

} public class Main extends JFrame {

 public Main() {
   JPanel panel = new JPanel();
   JLabel label = new JLabel("Number :");
   JFormattedTextField tf = new JFormattedTextField(new MyFormatter());
   tf.setColumns(10);
   panel.add(label);
   panel.add(tf);
   getContentPane().add(panel, BorderLayout.SOUTH);
   pack();
 }
 public static void main(String[] args) {
   Main mfe = new Main();
   mfe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   mfe.setVisible(true);
 }

}


 </source>
   
  
 
  



Support a date with the custom format: 2009-1-1

   <source lang="java">
 

import java.text.SimpleDateFormat; import java.util.Date; import javax.swing.JFormattedTextField; public class Main {

 public static void main(String[] argv) throws Exception {
   JFormattedTextField tft3 = new JFormattedTextField(new SimpleDateFormat("yyyy-M-d"));
   tft3.setValue(new Date());
 
   Date date = (Date) tft3.getValue();
 }

}


 </source>
   
  
 
  



Using an InputVerifier with a formatted textfield

   <source lang="java">
 

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// FtfInputVerifier.java //An example of using an InputVerifier with a formatted textfield. // import javax.swing.BorderFactory; import javax.swing.InputVerifier; import javax.swing.JComponent; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; public class FtfInputVerifier {

 public static void main(String argv[]) {
   java.net.URL u = null;
   try {
     u = new java.net.URL("http://www.ora.ru/");
   } catch (java.net.MalformedURLException ignored) {
   }
   // create two identical JFormattedTextFields
   JFormattedTextField ftf1 = new JFormattedTextField(u);
   JFormattedTextField ftf2 = new JFormattedTextField(u);
   // and set an InputVerifier on one of them
   ftf2.setInputVerifier(new InputVerifier() {
     public boolean verify(JComponent input) {
       if (!(input instanceof JFormattedTextField))
         return true; // give up focus
       return ((JFormattedTextField) input).isEditValid();
     }
   });
   JPanel p = new JPanel(new java.awt.GridLayout(0, 2, 3, 8));
   p.add(new JLabel("plain JFormattedTextField:", JLabel.RIGHT));
   p.add(ftf1);
   p.add(new JLabel("FTF with InputVerifier:", JLabel.RIGHT));
   p.add(ftf2);
   p.add(new JLabel("plain JTextField:", JLabel.RIGHT));
   p.add(new JTextField(u.toString()));
   p.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
   JFrame f = new JFrame("FtfInputVerifier");
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.getContentPane().add(
       new JLabel("Try to delete the colon in each field.",
           JLabel.CENTER), java.awt.BorderLayout.NORTH);
   f.getContentPane().add(p, java.awt.BorderLayout.CENTER);
   f.pack();
   f.setVisible(true);
 }

}


 </source>