Java: Swing: Components: Actions: Text actions
Text actions are currently only (and there exclusively) used for the actions returned by JTextComponent's and EditorKit's getActions. They are thus installed by the LAF TextUI class in the text component's UI action map (and also in the KeyMap?). This reduces the number of "Action names" by one, since the name of the action and the action map key are always the same. But it is also sensitive to name-clashes - one cannot have an action in a custom editor kit with the same name as a superclass already uses - it will override it (to avoid this, prefix class-name?).
isEnabled is always true for all current editor kit actions. Instead they bark (or do nothing) in actionPerformed (As they guess their target component anyway, they could support isEnabled better then a generic action-map Action and actually return false here based on their expected target). Thus they always consume the activating key stroke (this breaks some accelerator keys (ENTER, CTRL-T, SHIFT_CTRL-T, see below, and some other problems: TAB vs. CTRL-I, Backspace vs. CTRL-H)).
They also have unlocalized names and no other interesting properties. So they can usually only be used as ActionMap actions (which, on the other hand, does not make sense for almost all StyledTextActions).
By default, They are shared for all DefaultEditorKits (i.e. only one instance per each parameter setup exists). This means using the modifying methods in Action might have weird side-effects.
TextActions can obtain their target component in different ways:
Method | Result | Use |
|---|---|---|
ActionEvent.getSource | event source (may be different then the text component, does this actually happen?) | parameterized StyledTextActions (unimportant) |
TextAction.getFocusedComponent | updated by focusGained (JTextComponent-internal listener) | JTextField, JFormattedTextField actions |
TextAction.getTextComponent | action event's source if JTextComponent, or getFocusedComponent is this safe? | all other |
StyledEditorKit.StyledTextAction.getEditor | getTextComponent if JEditorPane, or null | most StyledTextActions, most HTMLEditorKit actions |
No parameters. The actions are added in/to JTextComponent.getActions().
Class | Name | Purpose | isEnabled |
|---|---|---|---|
JTextField.NotifyAction | JTextField.notifyAction= "notify-field-accept" | calls postActionEvent on target | iff text field hasActionListener (uses getFocusedComponent) |
JFormattedField.CommitAction (subclass of JTextField.NotifyAction) | "notify-field-accept", i.e replace the superclasses' action (documented?) | first calls commitEdit, if it succeeds, calls super (postActionEvent) | iff JFormattedTextField: true (1.5: if otherwise see JTextField (uses getFocusedComponent) |
JFormattedTextField.CancelAction | "reset-field-edit" (undocumented) | call setValue(getValue()); | 1.4: iff JFormattedTextField 1.5: iff JFormattedTextField: as CommitAction; otherwise true |
While not in DefaultEditorKit, StyledEditorKit's insert break action also included here, because it replaces DefaultEditorKit's and is different than the other StyledEditorKit actions.
Only DefaultKeyTyped and InsertContent use the action command.
Only the following actions modify the document, most others the caret (including selection), some (at the end, strange) the text component. Here's how they handle text component states:
Class(+Action) | !isEnabled | !isEditable |
|---|---|---|
DefaultKeyTyped | do nothing | do nothing |
InsertContent | error feedback | error feedback |
InsertBreak InsertTab | error feedback | error feedback |
StyledEditorKit. StyledInsertBreak | error feedback | error feedback |
DeletePrevChar DeleteNextChar | error feedback | |
Cut, Paste |
For the standard use of these actions (text component's own action map) isEnabled() is probably not needed.
Cut/Paste: probably should test (#4323476) (JTextComponent's cut/paste are not documented to test and their relation to user actions is unclear (as is replaceSelection's (#4173018)
public classes/keys emphasized.
Class | Name Standard getActions | Parameters | Purpose | Remarks |
|---|---|---|---|---|
DefaultKeyTypedAction | defaultKeyTypedAction | if (seemingly) valid action command and modifiers, replaceSelection | automatically by JTextComponent's default keymap, (but also getActions) | |
InsertContentAction | insertContentAction | replaceSelection(actionCommand) | ||
InsertBreakAction InsertTabAction | insertBreakAction insertTabAction | replaceSelection("n") replaceSelection("t") | InsertBreakAction wrapped in TextActionWrapper in BasicTextUI (so that enter key is not consumed if it happens to be used for default button) (shouldn't the same by done for InsertTab?) | |
StyledEditorKit. StyledInsertBreakAction (new in 1.4) | insertBreakAction | replaceSelection("n") with input attribute logic | (taken because augmentList prefers the second array) | |
DeletePrevCharAction DeleteNextCharAction | deletePrevCharAction deleteNextCharAction | remove selection, or previous character(s) remove selection, or next character(s) | ||
CutAction CopyAction PasteAction | cutAction= "cut-to-clipboard" copyAction= "copy-to-clipboard" pasteAction= "paste-from-clipboard" | cut copy paste | Values included because non-obvious | |
VerticalPageAction | forwards pageUpAction pageDownAction selectionPageUpAction="selection-page-up" selectionPageDownAction="selection-page-down" | left or right move or set | move caret to a position based on visibleRect etc. | |
PageAction | forwards selectionPageLeftAction="selection-page-left" selectionPageRightAction="selection-page-right" | left or right move or set | move caret to a position based on visibleRect etc. (much easier than VerticalPageAction?) | |
NextVisualPositionAction | forwards forwardAction, backwardAction upAction, downAction selectionForward/Backward/Up/DownAction | direction move or set | ||
BeginWordAction EndWordAction | forwards begin/endWordAction selectionBegin/EndWordAction | move or set | see Utilities | |
PreviousWordAction NextWordAction | forwards previousWordAction selectionPreviousWordAction nextWordAction selectionNextWordAction | move or set | ||
BeginLineAction EndLineAction BeginParagraphAction EndParagraphAction | forwards beginLineAction selectionBeginLineAction endLineAction selectionEndLineAction beginParagraphAction selectionBeginParagraphAction endParagraphAction selectionEndParagraphAction | move or set | ||
BeginAction EndAction | forwards beginAction selectionBeginAction endAction selectionEndAction | move or set | move/set caret to 0 move/set caret to document's length | |
SelectWordAction SelectLineAction | selectWordAction selectLineAction | used directly by DefaultCaret based on Begin/EndXXXAction (created with name "pigdog"!) | ||
SelectParagraphAction | selectParagraphAction | based on Begin/EndXXXAction (created with name "pigdog"!) | ||
SelectAllAction UnselectAction | selectAllAction unselectAction= "unselect" | unselect may change bias! | ||
ReadOnlyAction WritableAction | readOnlyAction writableAction | set text component to (non)-editable | why two classes? | |
ToggleComponentOrientationAction | toggleComponentOrientationAction= "toggle-componentOrientation" | |||
BeepAction | beepAction | provideErrorFeedback (was: beep) | ||
DumpModel | "dump-model" | if document is AbstractDocument, dump to System.err |
That should be all defined action Strings (some are not public).
The LAFs seem to install (except on single-line fields) key strokes for SelectAll/Unselect and all up to Begin/End, except for InsertContent and DefaultKeyTyped (which is automatically inherited); and also (always?) for toggle-componentOrientation (which is hardly useful except for testing). There is no reason why a LAF shouldn't also register key strokes for Select(Word|LineParagraph).
At least the last actions are a little weird and/or insecure for custom editors (But I don't think it makes sense for an LAF to register them.)
(minus StyledInsertBreakAction, which is already discusses with DefaultEditorKit)
All (except StyledTextAction itself) use StyleConstants attributes.
The parameter actions "alternatively" use the action command.
There are no tests for isEnabled/isEditable. This seems to confirm that these actions are intended to be of a different nature.
All of these modify the document.
It seems a little pointless to have them by default in the components actions (and the arrays are copied for each StyledEditorKit again).
Class | Name | Parameters | Purpose | getActions | Remarks |
|---|---|---|---|---|---|
StyledTextAction | abstract, forwards | support for setting attributes etc. | |||
BoldAction ItalicAction UnderlineAction | "font-bold" "font-italic" "font-underline" | toggle (always adds) bold, resp. italic, underline | "font-bold" "font-italic" "font-underline" | One class could also have handled all three (and more) attributes | |
ForegroundAction | forwards | Color | set foreground to either a Color-decoded action command (only if event's source is editor, also in the following) or its property | ||
AlignmentAction | forwards | int | set alignment to either a int-decoded action command or its property | "left-justify", "center-justify", "right-justify" | why not "xx-alignment"? |
FontSizeAction | forwards | int | set font size to either a int-decoded action command or its property | "font-size-xx" for sizes 8, 10, 12, 14, 16, 18, 24, 36, 48 | |
FontFamilyAction | forwards | String | set font size to either the action command (if != null) or its property | "font-family-xx" for SansSerif, Monospaced, Serif |
italic: StyledTextAction
None test for isEnabled or use the action command.
The link actions do nothing for an editable text component. It's isEnabled is not used.
Class | Name | Parameters | Purpose | getActions | Remarks |
|---|---|---|---|---|---|
ActivateLinkAction | "activate-link-action" | fireHyperlinkUpdate if link at caret position | "activate-link-action" | ||
NavigateLinkAction | forwards | none! (takes direction by name comparison) | move to next/previous link | "next-link-action" "previous-link-action" | |
HTMLTextAction | abstract, forwards | helper methods | |||
InsertHTMLTextAction | forwards | HTML-String, various "tags" | complicated inserting logic | "InsertTable" (single cell, border) "InsertTableRow" (single cell) "InsertTableDataCell" "InsertUnorderedList" "InsertUnorderedListItem" "InsertOrderedList" "InsertOrderedListItem" "InsertPre" | |
InsertHRAction | "InsertHR" | special inserting logic | "InsertHR" |
All the static action name Strings (that means all static Strings except DEFAULT_CSS) in HTMLEditorKit are unused.
The link actions are actually bound by the LAFs ((SHIFT) CTRL T, CTRL Space), so these key strokes won't work as accelerators.
(C) 2001-2009 Christian Kaufhold (swing@chka.de)