Package docking.widgets.textfield

# Class TextFieldLinker

java.lang.Object
docking.widgets.textfield.TextFieldLinker

public class TextFieldLinker extends 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 `JTextField`s 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

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `protected final List<FocusListener>`
  `focusListeners`
  `protected JTextField`
  `lastField`
  `protected final List<TextFieldLinker.LinkedField>`
  `linkedFields`
  `protected AtomicInteger`
  `mute`
  `protected TextFieldLinker.LinkerState`
  `state`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `TextFieldLinker()`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `addFocusListener(FocusListener listener)`
  Add a focus listener
  `protected 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(Component field)`
  Get the index of a field.
  `protected void`
  `fireFocusListeners(FocusEvent ev)`
  Fire the given event on all registered focus listeners
  `JTextField`
  `getField(int i)`
  Get an individual field in the composite
  `JTextField`
  `getFocusedField()`
  Get the individual field last having focus
  `int`
  `getNumFields()`
  Get the number of fields in this composite
  `String`
  `getText()`
  Get the full composite text
  `String`
  `getTextBeforeCursor(JTextField where)`
  Get the text preceding the caret in the given field
  `protected void`
  `instrument()`
  Once all fields are added, register all the listeners
  `boolean`
  `isVisible()`
  Check if all component fields are visible
  `void`
  `linkField(JTextField field, String exp, String sep)`
  `void`
  `linkField(JTextField field, Pattern pat, String sep)`
  Add a new text field to this linker
  `void`
  `linkLastField(JTextField field)`
  Add the final field, and actually link the fields
  `void`
  `removeFocusListener(FocusListener listener)`
  Remove a focus listener
  `void`
  `setCaretPosition(int pos)`
  Set the location of the caret among the composite text
  `void`
  `setFont(Font font)`
  Set the font for all linked fields
  `void`
  `setText(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 Details

  - ### linkedFields

    protected final List<TextFieldLinker.LinkedField> linkedFields

  - ### lastField

    protected JTextField lastField

  - ### state

    protected TextFieldLinker.LinkerState state

  - ### mute

    protected AtomicInteger mute

  - ### focusListeners

    protected final List<FocusListener> focusListeners

- ## Constructor Details

  - ### TextFieldLinker

    public TextFieldLinker()

- ## Method Details

  - ### 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(JTextField field, String exp, String sep)
    See Also:
      - `linkField(JTextField, Pattern, String)`

  - ### linkField

    public void linkField(JTextField field, Pattern pat, String sep)
    Add a new text field to this linker

    Links the given field with the others present in this linker, if any. `pat` is a regular expression that dictates where the given field ends, and the next field begins. When `pat` matches a part of the text in `field`, the text is split and re-flowed so that the second part is moved into the next linked field. The separator is omitted from both fields. The fields should be positioned in order with labels between that display the expected separators, so that the user may understand what is happening. The `getText()` and `getTextBeforeCursor(JTextField)` methods will include `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: `pat` must accept `sep`, otherwise calling `setText(String)` with the results of `getText()` will have unexpected effects.

    Parameters:
      `field` - the field to link
      `pat` - the regular expression to search for following the field
      `sep` - the separator that replaces `pat` when matched

  - ### linkLastField

    public void linkLastField(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(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 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 String getText()
    Get the full composite text
    Returns:
      the text, including separators

  - ### setText

    public void setText(String text)
    Set the full composite text
    Parameters:
      `text` - the text, including separators

  - ### setFont

    public void setFont(Font font)
    Set the font for all linked fields
    Parameters:
      `font` - the new font

  - ### setCaretPosition

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

  - ### getTextBeforeCursor

    public String getTextBeforeCursor(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 JTextField getField(int i)
    Get an individual field in the composite
    Parameters:
      `i` - the index of the field
    Returns:
      the field

  - ### getFocusedField

    public JTextField getFocusedField()
    Get the individual field last having focus

    Effectively, this gives the field containing the composite caret

    Returns:
      the last-focused field

  - ### 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

  - ### isVisible

    public boolean isVisible()
    Check if all component fields are visible
    Returns:
      false if any component is not visible, true otherwise

  - ### addFocusListener

    public void addFocusListener(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(FocusListener listener)
    Remove a focus listener
    Parameters:
      `listener` - the focus listener to remove

  - ### fireFocusListeners

    protected void fireFocusListeners(FocusEvent ev)
    Fire the given event on all registered focus listeners
    Parameters:
      `ev` - the event

  - ### twoSpacedFields

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