Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / November 2004

Tip: Looking for answers? Try searching our database.

Percent JFormattedField

Thread view: 
Dmitri - 22 Nov 2004 19:19 GMT
Hello, guys

I'm trying to create a text field where I could enter any valid
digits for percents (let's say -900 .. 900) and have it displayed
with '%' sign, when the field looses focus or ENTER is pressed.
I am using NumberFormat.getPercentInstance() to get formatter and
it displays the initial value fine (with '%' sign). I limit my
input to digits with PercentInputFilter. The problem is, when I
delete the current contents of the field, enter my new value
(let's say 50) and click the button the value is not accepted
and reverted to the previous one. As far as I understand, with
getPercentInstance() it requires '%' char to be present. But
what I'm trying to achieve is to enter digits and have '%' to
be automatically displayed (if it's not there yet).

I am browsing doc on JFormattedText field, but could come up
with a good solution to meed my above mentioned needs.

Any suggestions, help, sample code are appreciated.
See sample code below. You can actually compile and run it
to see the problem.

Thanks
-Dmitri

<sample_code>

import javax.swing.JFormattedTextField;
import java.text.NumberFormat;
import javax.swing.text.DocumentFilter;
import javax.swing.text.BadLocationException;
import javax.swing.text.AttributeSet;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.NumberFormatter;

public class SpeedField extends JFormattedTextField {

   public static final int    DEFAULT_COLUMNS = 11;    
   public static final double DEFAULT_VALUE   = 1.00;  // 100%

   public SpeedField() {
    //super(NumberFormat.getPercentInstance());
    super();   
    setColumns(DEFAULT_COLUMNS);
    setHorizontalAlignment(javax.swing.JTextField.RIGHT);
   
    NumberFormatter formatter =
       new NumberFormatter (NumberFormat.getPercentInstance()) {
        protected DocumentFilter getDocumentFilter() {
           return filter;
        }
        private DocumentFilter filter = new PercentInputFilter();
       };

    DefaultFormatterFactory dff = new DefaultFormatterFactory();
    dff.setDefaultFormatter(formatter);
    dff.setDisplayFormatter(formatter);
    dff.setEditFormatter(formatter);
    setFormatterFactory(dff);
   
    setValue(new Double(DEFAULT_VALUE));   
   }
   
   protected int getColumnWidth() {
    return getFontMetrics(getFont()).charWidth('0');
   }

   private class PercentInputFilter extends DocumentFilter {

    public void insertString(FilterBypass fb,
                int offset,
                String string,
                AttributeSet attr) throws BadLocationException {
       
       StringBuffer buffer = new StringBuffer(string);
       for (int i = buffer.length() - 1; i >= 0; i--) {
        char ch = buffer.charAt(i);
        if (!Character.isDigit(ch) && ch != '-')
           buffer.deleteCharAt(i);
       }
       super.insertString(fb, offset, buffer.toStri343ng(), attr);       
    }

    public void replace(FilterBypass fb,
               int offset,
               int length,
               String string,
               AttributeSet attr) throws BadLocationException {
       
       if (string != null) {
        StringBuffer buffer = new StringBuffer(string);
        for (int i = buffer.length() - 1; i >= 0; i--) {
           char ch = buffer.charAt(i);
           if (!Character.isDigit(ch) && ch != '-')
            buffer.deleteCharAt(i);
        }
        string = buffer.toString();
       }
       super.replace(fb, offset, length, string, attr);
    }

   } // class PercentInputField
   
   /** -----------------------------------------------------------------------
    * TEST UNIT
    */
   public static void main(String[] argv) {

    javax.swing.JFrame frame = new javax.swing.JFrame("SpeedField Test");
    frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);

    final SpeedField speed = new SpeedField();
    javax.swing.JPanel p = new javax.swing.JPanel();
    p.add(speed);

    javax.swing.JButton btValue = new javax.swing.JButton("Value");
    btValue.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent e) {
           System.err.println("value = " + speed.getValue());
        }
       });
   
    p.add(btValue);
    frame.getContentPane().add(p, java.awt.BorderLayout.NORTH);

    frame.pack();
    frame.setSize(new java.awt.Dimension(200, 80));
    frame.setLocation(100,100);
    frame.setVisible(true);   

   }
   
} // class SpeedField

</sample_code
Andrew Thompson - 22 Nov 2004 19:38 GMT
I'm not so experienced with JFormattedTextField to solve your
problem, though I played with your code out of interest.

> See sample code below. You can actually compile and run it
> to see the problem.

Good example!  Except for one (late I assume) typo.

> <sample_code>
....
>        for (int i = buffer.length() - 1; i >= 0; i--) {
>         char ch = buffer.charAt(i);
>         if (!Character.isDigit(ch) && ch != '-')
>            buffer.deleteCharAt(i);
>        }
>        super.insertString(fb, offset, buffer.toStri343ng(), attr);       
....

Where did the '343' come from?  

BTW - Please do not x-post so widely, I recommend you set the
Follow-Ups to c.l.j.gui *only* (as I have done).
The people that can answer this are on c.l.j.gui, if anywhere.

Signature

Andrew Thompson
http://www.PhySci.org/codes/  Web & IT Help
http://www.PhySci.org/  Open-source software suite
http://www.1point1C.org/  Science & Technology
http://www.LensEscapes.com/  Images that escape the mundane

Dmitri - 23 Nov 2004 14:42 GMT
> I'm not so experienced with JFormattedTextField to solve your
> problem, though I played with your code out of interest.
[quoted text clipped - 15 lines]
>
> Where did the '343' come from?  

Sure, it's a typo... probably my emacs editing window had focus
when I was typing line number for debugging...
Thanks for reply anyway!
Shane Mingins - 29 Nov 2004 03:39 GMT
> Any suggestions, help, sample code are appreciated.
> See sample code below. You can actually compile and run it
> to see the problem.

Did not have time to compile and run, sorry.  Here's ours ... have fun ;-)

Cheers
Shane

Signature

"there's a lot of bad code out there, and someone must be writing it" - Ron
Jeffries

public class PercentField extends JFormattedTextField
{

   /**
    * A formatter to check the format of percent fields.
    * It provides additional functionality by adding a DocumentFilter.
    */
   private static class PercentFormatter extends NumberFormatter
   {

       private DocumentFilter documentFilter;

       public PercentFormatter(int noDecimals)
       {
           super(getPercentEditFormat(noDecimals));
       }

       public DocumentFilter getDocumentFilter()
       {
           if (documentFilter == null)
           {
               documentFilter = new BasicDocumentFilter(new char[]{'0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', ',', '.', '+', '-', '%'});
           }
           return documentFilter;
       }
   }

   /**
    * Get the appropriate NumberFormat for editing this component.
    *
    * @return
    */
   private static NumberFormat getPercentEditFormat(int noDecimals)
   {
       NumberFormat nf = NumberFormat.getNumberInstance();
       nf.setMinimumFractionDigits(noDecimals);
       nf.setMaximumFractionDigits(noDecimals);
       return nf;
   }

   /**
    * Create a PercentField that will use a PercentFormatter and a
BasicInputVerifier.
    */
   public PercentField(int noDecimals)
   {
       super(new DefaultFormatterFactory(new
NumberFormatter(NumberFormatUtils.getPercentDisplayFormat(noDecimals)),
               new
NumberFormatter(NumberFormatUtils.getPercentDisplayFormat(noDecimals)),
               new PercentFormatter(noDecimals)));
       super.setInputVerifier(new BasicInputVerifier());
   }

   // default 'null' constructor for 4 decimal places.
   public PercentField()
   {
       this(4);
   }

   /**
    * Returns value as a BigDecimal
    *
    * @return the last valid value as a BigDecimal
    * @see java.math.BigDecimal
    * @see javax.swing.JFormattedTextField
    */
   public BigDecimal getBigDecimalValue()
   {
//        return new BigDecimal(((Number) getValue()).doubleValue());
       return ((getValue() == null) ? null : new BigDecimal(((Number)
getValue()).doubleValue()));
   }
}



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.