9 Replies Latest reply on May 29, 2008 12:57 AM by 843806

    JFormattedTextField - formatter returning Long ??

    843806
      I was using the default formatters for the following field and this worked fine.
      {
            jOpNumTxtFld = new JFormattedTextField();                    
            jOpNumTxtFld.setValue( new Integer(0) );
            jOpNumTxtFld.addPropertyChangeListener("value", 
                    new PropertyChangeListener()  {
                        public void propertyChange( PropertyChangeEvent evt ) {
                            int old = ((Integer)evt.getOldValue()).intValue();
                            int nwV = ((Integer)evt.getNewValue()).intValue();
                            if( old != nwV )  {  
                                opNum = nwV;
                            }
      }
      But I didn't like the group separator that the default formatters use so, on the suggestion of the
      [How to Use Formatted Text Fields|http://java.sun.com/docs/books/tutorial/uiswing/components/formattedtextfield.html#factory] tutorial, I defined my own DefaultFormatterFactory:
      {
                NumberFormat opnDisplayFormat = NumberFormat.getIntegerInstance();
                opnDisplayFormat.setGroupingUsed( false );
                NumberFormat opnEditFormat = NumberFormat.getIntegerInstance();
                opnEditFormat.setGroupingUsed( false );
                jOpNumTxtFld = new JFormattedTextField(
                          new DefaultFormatterFactory(
                              new NumberFormatter( opnDisplayFormat ),
                              new NumberFormatter( opnDisplayFormat ),
                              new NumberFormatter( opnEditFormat )));    
                jOpNumTxtFld.setValue( new Integer(0) );
                jOpNumTxtFld.addPropertyChangeListener("value", 
                          new PropertyChangeListener()  {
                              public void propertyChange( PropertyChangeEvent evt ) {
                                  int old = ((Integer)evt.getOldValue()).intValue();
                                  int nwV = ((Integer)evt.getNewValue()).intValue();
                                  if( old != nwV )  {  
                                      opNum = nwV;
                                  }
      }
      Formats are now just how I like them. BUT now the control insists on translating an entered string into a Long. For instance, the first time the field loses focus I get a ClassCastException on +(Integer)evt.getNewValue()+. Only four digits are allowed in the field so a Long is pointless as well as being a pain in the butt to deal with.

      What the heck is going on? And if there's a batter way to accomplish this please inform.
        • 1. Re: JFormattedTextField - formatter returning Long ??
          843806
          Hi DMF,
          /**
                * @param s string input
                * @return maskformatter
                */
               public MaskFormatter createFormatter(String s) {
                   MaskFormatter formatter = null;
                   try {
                       formatter = new MaskFormatter(s);
                   } catch (java.text.ParseException exc) {
                       System.err.println("formatter is bad: " + exc.getMessage());
                   }
                   return formatter;
               }
          //Use this function as follows 
          
          JFormattedTextField tf =new JFormattedTextField(createFormatter("HH HH HH HH"));
          //creates a formatted text field for entering 4 hex values
          For MaskFormatter documentation (where you can find several formatting tags), refer the following link

          MaskFormatter

          Sunil
          • 2. Re: JFormattedTextField - formatter returning Long ??
            843806
            Interesting, but not on point. I'm not doing a masked field. I just want to be able to enter a 1-4 digit numeric value and get back an Integer (or int). NumberFormatter insists on creating a Long as the result of any edit when I supply my own DefaultFormatterFactory.
            .
            • 3. Re: JFormattedTextField - formatter returning Long ??
              3004
                      NumberFormat opnDisplayFormat = NumberFormat.getIntegerInstance();
                      opnDisplayFormat.setGroupingUsed( false );
                      NumberFormat opnEditFormat = NumberFormat.getIntegerInstance();
                      opnEditFormat.setGroupingUsed( false );
                      NumberFormatter editFormatter = new NumberFormatter( opnEditFormat );
                      // Set class of object returned from formatter
                      editFormatter.setValueClass( Integer.class );
                      final JFormattedTextField jOpNumTxtFld = new JFormattedTextField(
                                new DefaultFormatterFactory(
                                    new NumberFormatter( opnDisplayFormat ),
                                    new NumberFormatter( opnDisplayFormat ),
                                    editFormatter ));
              • 4. Re: JFormattedTextField - formatter returning Long ??
                843806
                Thanks! That seems to do the trick.

                Here's my class in case anyone's interested.
                public class PartNumberFormatFactory extends DefaultFormatterFactory {
                    private static final long serialVersionUID = 123L;
                
                    public PartNumberFormatFactory() {
                        super();
                        NumberFormat pnDisplayFormat = NumberFormat.getIntegerInstance();
                        pnDisplayFormat.setMinimumIntegerDigits( 1 );
                        pnDisplayFormat.setMaximumIntegerDigits( 4 );
                        pnDisplayFormat.setGroupingUsed( false );
                        NumberFormatter displayFormatter = new NumberFormatter( pnDisplayFormat); 
                
                        NumberFormat pnEditFormat = NumberFormat.getIntegerInstance();
                        pnEditFormat.setMinimumIntegerDigits( 1 );
                        pnEditFormat.setMaximumIntegerDigits( 4 );
                        pnEditFormat.setGroupingUsed( false );
                        NumberFormatter editFormatter = new NumberFormatter( pnEditFormat ); 
                        editFormatter.setValueClass( Integer.class );
                        
                        this.setDefaultFormatter( displayFormatter );
                        this.setDisplayFormatter( displayFormatter ) );
                        this.setEditFormatter( editFormatter );
                    }
                }
                A small question:

                Will one instance of this class serve for several fields? Some fields change the contents of others so the Format is potentially re-rentrant.
                • 5. Re: JFormattedTextField - formatter returning Long ??
                  843806
                  Further testing revealed a problem with the answer.
                  • 6. Re: JFormattedTextField - formatter returning Long ??
                    843806
                    Using the class posted above (calling setValueClass), here is the code for a JFormattedTextField :
                        private PartNumberFormatFactory pnFormatFactory 
                            = new PartNumberFormatFactory();
                    
                        private JFormattedTextField getSpSq() {
                            if( jSpSq == null) {
                                jSpSq = new JFormattedTextField( pnFormatFactory );
                                jSpSq.setColumns( 4 );
                                jSpSq.setValue( new Integer( 0 ) ); // redundant but hey... 
                                ...
                            }
                            return jSpSq;
                        }
                    
                    void preLoadFields {
                            getSpSq().setValue( new Integer(0) );
                            getSpSq().setText("");
                    }
                    
                    void readFields  {
                            int spsq = ((Integer)getSpSq().getValue()).intValue();
                    **boom**
                    }
                    The first time I enter a value, getValue() returns a Long causing a ClassCastException.

                    The second time I enter a value, getValue() returns a Integer and all is well.

                    What in the H is going on here ??
                    • 7. Re: JFormattedTextField - formatter returning Long ??
                      843806
                      Arr!! It's the %^&( getSpSq().setText(""); that's doing it.

                      All I want is to present a panel with empty fields for the user to fill in. Is that so much to ask?

                      --------------------------

                      JayDS, you answered my question. Thanks.

                      Maybe I should have asked if JFormattedTextField is usable without jumping through invisible hoops... (This was an easy one; I haven't yet related my adventures in InputVerifier land...)
                      • 8. Re: JFormattedTextField - formatter returning Long ??
                        3004
                        DMF. wrote:
                        Arr!! It's the %^&( getSpSq().setText(""); that's doing it.

                        All I want is to present a panel with empty fields for the user to fill in. Is that so much to ask?
                        Once you start using using the setValue() and getValue(), I think you need to stop using setText().
                        Did you try doing a setValue( null ) to clear the field?
                        • 9. Re: JFormattedTextField - formatter returning Long ??
                          843806
                          I started off that way; it has it's own problems when setting that as the initial value. But I haven't tried it since discovering the setValueClass() method. I'll give it a whirl.

                          For the panel I'm working on now I went back to JTextField. I'd forgotten what a PITA JTextField can be (+how+ many different Listeners do I need to cover all modes of traversal??). Maybe JFormattedTextField isn't so bad after all...