Class TextFieldLinker


  • public class TextFieldLinker
    extends java.lang.Object
    A class that links text fields into a "formatted text field", separated by expressions. This fulfills a similar purpose to formatted text fields, except the individual parts may be placed independent of the other components. Granted, they ought to appear in an intuitive order. The input string is split among a collection of JTextFields each according to a given pattern -- excluding the final field. Cursor navigation, insertion, deletion, etc. are all applied as if the linked text fields were part of a single composite text field. The individual text fields must be constructed and added by the user, as in the example:
     
     Box hbox = Box.createHorizontalBox();
     TextFieldLinker linker = new TextFieldLinker();
     
     JTextField first = new JTextField();
     hbox.add(first);
     hbox.add(Box.createHorizontalStrut(10));
     linker.linkField(first, "\\s+", " ");
     
     JTextField second = new JTextField();
     hbox.add(second);
     hbox.add(new GLabel("-"));
     linker.linkField(second, "-", "-");
     
     JTextField third = new JTextField();
     hbox.add(third);
     linker.linkLastField(third);
     
     linker.setVisible(true);
     
     
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      protected class  TextFieldLinker.FieldState
      The current state of a linked field, stored separately from the actual component
      protected class  TextFieldLinker.LinkedField
      A field that has been added with its corresponding separator expression and replacement
      protected class  TextFieldLinker.LinkerState
      A class to track the internal state gathered from the text fields
    • Constructor Summary

      Constructors 
      Constructor Description
      TextFieldLinker()  
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void addFocusListener​(java.awt.event.FocusListener listener)
      Add a focus listener The focus listener will receive a callback only when focus is passed completely outside the composite text field.
      protected javax.swing.JTextField buildField​(int i)
      Provides an opportunity to compose the field from an extension of JTextField
      protected void checkLast()
      Check if this linker is mutable
      void clear()
      Clear the composite field, i.e., clear all the linked fields
      protected void dispose()
      Unregister all the listeners, effectively unlinking the fields
      protected int findField​(java.awt.Component field)
      Get the index of a field.
      protected void fireFocusListeners​(java.awt.event.FocusEvent ev)
      Fire the given event on all registered focus listeners
      javax.swing.JTextField getField​(int i)
      Get an individual field in the composite
      javax.swing.JTextField getFocusedField()
      Get the individual field last having focus Effectively, this gives the field containing the composite caret
      int getNumFields()
      Get the number of fields in this composite
      java.lang.String getText()
      Get the full composite text
      java.lang.String getTextBeforeCursor​(javax.swing.JTextField where)
      Get the text preceding the caret in the given field
      protected void instrument()
      Once all fields are added, register all the listeners
      void linkField​(javax.swing.JTextField field, java.lang.String exp, java.lang.String sep)
      Add a new text field to this linker Links the given field with the others present in this linker, if any.
      void linkField​(javax.swing.JTextField field, java.util.regex.Pattern pat, java.lang.String sep)  
      void linkLastField​(javax.swing.JTextField field)
      Add the final field, and actually link the fields The fields are not effectively linked until this method is called.
      void removeFocusListener​(java.awt.event.FocusListener listener)
      Remove a focus listener
      void setCaretPosition​(int pos)
      Set the location of the caret among the composite text
      void setText​(java.lang.String text)
      Set the full composite text
      void setVisible​(boolean visible)
      Set the visibility of all the component fields
      protected void syncStateLater()
      Schedule a state synchronization.
      static TextFieldLinker twoSpacedFields()
      A convenient factory to build two fields separated by spaces
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • lastField

        protected javax.swing.JTextField lastField
      • mute

        protected java.util.concurrent.atomic.AtomicInteger mute
      • focusListeners

        protected final java.util.List<java.awt.event.FocusListener> focusListeners
    • Constructor Detail

      • TextFieldLinker

        public TextFieldLinker()
    • Method Detail

      • instrument

        protected void instrument()
        Once all fields are added, register all the listeners
      • dispose

        protected void dispose()
        Unregister all the listeners, effectively unlinking the fields
      • linkField

        public void linkField​(javax.swing.JTextField field,
                              java.lang.String exp,
                              java.lang.String sep)
        Add a new text field to this linker Links the given field with the others present in this linker, if any. exp is a regular expression that dictates where the given field ends, and the next field begins. When exp matches a part of the text in field, the text is split and re-flowed so that the second part is removed into the next linked field. The separator is omitted from both fields. The packing of the fields -- and surrounding labels -- ought to imply that the separator is still present, because getText() or and getTextBeforeCursor(JTextField) insert sep between the fields. Any number of fields may be added in this fashion, but the last field -- having no associated pattern or separator -- must be added using linkLastField(JTextField). Thus, before linking is actually activated, at least one field must be present. To be meaningful, at least two fields should be linked. NOTE: exp must match sep.
        Parameters:
        field - the field to link
        exp - the separator following the field
        sep - the separator that replaces exp when matched
      • linkLastField

        public void linkLastField​(javax.swing.JTextField field)
        Add the final field, and actually link the fields The fields are not effectively linked until this method is called. Additionally, once this method is called, the linker cannot take any additional fields.
        Parameters:
        field - the final field
      • checkLast

        protected void checkLast()
        Check if this linker is mutable
      • findField

        protected int findField​(java.awt.Component field)
        Get the index of a field.
        Parameters:
        field - the field
        Returns:
        the index, or -1 if the field does not belong to this composite field
      • buildField

        protected javax.swing.JTextField buildField​(int i)
        Provides an opportunity to compose the field from an extension of JTextField
        Parameters:
        i - the index of the field to construct
        Returns:
        a newly-constructed text field
      • syncStateLater

        protected void syncStateLater()
        Schedule a state synchronization.
      • clear

        public void clear()
        Clear the composite field, i.e., clear all the linked fields
      • getText

        public java.lang.String getText()
        Get the full composite text
        Returns:
        the text, including separators
      • setText

        public void setText​(java.lang.String text)
        Set the full composite text
        Parameters:
        text - the text, including separators
      • setCaretPosition

        public void setCaretPosition​(int pos)
                              throws javax.swing.text.BadLocationException
        Set the location of the caret among the composite text
        Parameters:
        pos - the position, including separators
        Throws:
        javax.swing.text.BadLocationException - if the position is larger than the composite text
      • getTextBeforeCursor

        public java.lang.String getTextBeforeCursor​(javax.swing.JTextField where)
        Get the text preceding the caret in the given field
        Parameters:
        where - the field whose caret to consider
        Returns:
        the text
      • getField

        public javax.swing.JTextField getField​(int i)
        Get an individual field in the composite
        Parameters:
        i -
        Returns:
      • getFocusedField

        public javax.swing.JTextField getFocusedField()
        Get the individual field last having focus Effectively, this gives the field containing the composite caret
        Returns:
      • getNumFields

        public int getNumFields()
        Get the number of fields in this composite
        Returns:
        the field count
      • setVisible

        public void setVisible​(boolean visible)
        Set the visibility of all the component fields
        Parameters:
        visible - true to show, false to hide
      • addFocusListener

        public void addFocusListener​(java.awt.event.FocusListener listener)
        Add a focus listener The focus listener will receive a callback only when focus is passed completely outside the composite text field. No events are generated when focus passes from one field in the composite to another.
        Parameters:
        listener - the focus listener to add
      • removeFocusListener

        public void removeFocusListener​(java.awt.event.FocusListener listener)
        Remove a focus listener
        Parameters:
        listener - the focus listener to remove
      • fireFocusListeners

        protected void fireFocusListeners​(java.awt.event.FocusEvent ev)
        Fire the given event on all registered focus listeners
        Parameters:
        ev -
      • twoSpacedFields

        public static TextFieldLinker twoSpacedFields()
        A convenient factory to build two fields separated by spaces
        Returns:
        the linker containing two new linked JTextFields