Package docking.widgets.textfield
Class TextFieldLinker
- java.lang.Object
-
- docking.widgets.textfield.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 ofJTextField
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 componentprotected class
TextFieldLinker.LinkedField
A field that has been added with its corresponding separator expression and replacementprotected class
TextFieldLinker.LinkerState
A class to track the internal state gathered from the text fields
-
Field Summary
Fields Modifier and Type Field Description protected java.util.List<java.awt.event.FocusListener>
focusListeners
protected javax.swing.JTextField
lastField
protected java.util.List<TextFieldLinker.LinkedField>
linkedFields
protected java.util.concurrent.atomic.AtomicInteger
mute
protected TextFieldLinker.LinkerState
state
-
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 ofJTextField
protected void
checkLast()
Check if this linker is mutablevoid
clear()
Clear the composite field, i.e., clear all the linked fieldsprotected void
dispose()
Unregister all the listeners, effectively unlinking the fieldsprotected 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 listenersjavax.swing.JTextField
getField(int i)
Get an individual field in the compositejavax.swing.JTextField
getFocusedField()
Get the individual field last having focus Effectively, this gives the field containing the composite caretint
getNumFields()
Get the number of fields in this compositejava.lang.String
getText()
Get the full composite textjava.lang.String
getTextBeforeCursor(javax.swing.JTextField where)
Get the text preceding the caret in the given fieldprotected void
instrument()
Once all fields are added, register all the listenersvoid
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 listenervoid
setCaretPosition(int pos)
Set the location of the caret among the composite textvoid
setText(java.lang.String text)
Set the full composite textvoid
setVisible(boolean visible)
Set the visibility of all the component fieldsprotected void
syncStateLater()
Schedule a state synchronization.static TextFieldLinker
twoSpacedFields()
A convenient factory to build two fields separated by spaces
-
-
-
Field Detail
-
linkedFields
protected final java.util.List<TextFieldLinker.LinkedField> linkedFields
-
lastField
protected javax.swing.JTextField lastField
-
state
protected TextFieldLinker.LinkerState state
-
mute
protected java.util.concurrent.atomic.AtomicInteger mute
-
focusListeners
protected final java.util.List<java.awt.event.FocusListener> focusListeners
-
-
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. Whenexp
matches a part of the text infield
, 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, becausegetText()
or andgetTextBeforeCursor(JTextField)
insertsep
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 usinglinkLastField(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 matchsep
.- Parameters:
field
- the field to linkexp
- the separator following the fieldsep
- the separator that replacesexp
when matched
-
linkField
public void linkField(javax.swing.JTextField field, java.util.regex.Pattern pat, java.lang.String sep)
- See Also:
linkField(JTextField, String, String)
-
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 ofJTextField
- 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
JTextField
s
-
-