JTextPane and VK_HOME

Hi,

I have a JTextPane in my plugin, and I want it to have custom VK_HOME event handler, which would move the caret to the beginning of the last line. However, it looks like IDEA takes over and first moves the caret to the beginning of the whole text, so the caret jumps twice. Here's relevant stack trace, taken from the caret listener:


What is the civilized way to overcome it? I don't want to hack JTextArea.setCaretPosition
Thanks

6 comments
Comment actions Permalink

Hello Konstantin,

You need to implement the Home key handling as an AnAction and use registerCustomShortcutSet()
to associate the Home key with it. Then your handler will be called instead
of IDEA's own Home key handling.

I have a JTextPane in my plugin, and I want it to have custom VK_HOME
event handler, which would move the caret to the beginning of the last
line. However, it looks like IDEA takes over and first moves the caret
to the beginning of the whole text, so the caret jumps twice. Here's
relevant stack trace, taken from the caret listener:

 e = dot=0,mark=0
> java.lang.Exception:
> at org.kos.bsfconsoleplugin.Console$2.caretUpdate(Console.java:128)
> at
> javax.swing.text.JTextComponent.fireCaretUpdate(JTextComponent.java:39
> 1)
> at
> javax.swing.text.JTextComponent$MutableCaretEvent.fire(JTextComponent.
> java:4389)
> at
> javax.swing.text.JTextComponent$MutableCaretEvent.stateChanged(JTextCo
> mponent.java:4411)
> at
> javax.swing.text.DefaultCaret.fireStateChanged(DefaultCaret.java:782)
> at
> javax.swing.text.DefaultCaret.changeCaretPosition(DefaultCaret.java:12
> 57)
> at javax.swing.text.DefaultCaret.handleSetDot(DefaultCaret.java:1153)
> at javax.swing.text.DefaultCaret.setDot(DefaultCaret.java:1134)
> at javax.swing.text.DefaultCaret.setDot(DefaultCaret.java:1031)
> at
> javax.swing.text.JTextComponent.setCaretPosition(JTextComponent.java:1
> 652)
> at
> com.intellij.openapi.editor.textarea.TextComponentCaretModel.moveToOff
> set(TextComponentCaretModel.java:23)
> at
> com.intellij.openapi.editor.textarea.TextComponentCaretModel.moveToLog
> icalPosition(TextComponentCaretModel.java:8)
> at
> com.intellij.openapi.editor.actions.EditorActionUtil.moveCaretToLineSt
> art(EditorActionUtil.java:256)
> at
> com.intellij.openapi.editor.actions.LineStartAction$Handler.execute(Li
> neStartAction.java:2)
> at
> com.intellij.codeInsight.lookup.impl.HomeHandler.execute(HomeHandler.j
> ava:2)
> at
> com.intellij.codeInsight.template.impl.editorActions.HomeEndHandler.ex
> ecute(HomeEndHandler.java:12)
> at
> com.intellij.openapi.editor.actionSystem.EditorAction$1.run(EditorActi
> on.java:76)
> at
> com.intellij.openapi.command.impl.CommandProcessorImpl.executeCommand(
> CommandProcessorImpl.java:2)
> at
> com.intellij.openapi.editor.actionSystem.EditorAction.actionPerformed(
> EditorAction.java:88)
> at
> com.intellij.openapi.editor.actionSystem.EditorAction.actionPerformed(
> EditorAction.java:62)
> at
> com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher$1.performAction
> (IdeKeyEventDispatcher.java:2)
> at
> com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.processAction(I
> deKeyEventDispatcher.java:3)
> at
> com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.d(IdeKeyEventDi
> spatcher.java:1)
> at
> com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher.dispatchKeyEven
> t(IdeKeyEventDispatcher.java:170)
> at com.intellij.ide.IdeEventQueue.b(IdeEventQueue.java:211)
> at
> com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:217)
> at
> java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThrea
> d.java:273)
> at
> java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.j
> ava:183)
> at
> java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThrea
> d.java:173)
> at
> java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
> at
> java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
> at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
> ]]>

What is the civilized way to overcome it? I don't want to hack
JTextArea.setCaretPosition Thanks

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Hello Dmitry,


Thanks, it works, but raises another question: specifying keyboard-shortcut for my actions in plugin.xml makes them visible and editable in IDE preferences, but also makes them global. For instance, I want to define a HistoryUpAction mapped to the 'UP' key by default, which will only work inside of my tool window. Setting <keyboard-shortcut keymap="$default" first-keystroke="UP"/> overrides 'UP' key for the whole IDE, which is very inconvenient of course because the 'UP' key stops working in lots of dialogs. Is there a way to tell IDEA not to do it?
I'd still like to see my default shortcuts in the keyboard layout editor though, but I'll also have to call registerCustomShortcutSet again if the user changes the layout I guess.

0
Comment actions Permalink

Hello Konstantin,

Do not register your action in plugin.xml. Simply create an instance of your
AnAction-derived class programmatically, and use registerCustomShortcutSet()
to associate it with a component.

Hello Dmitry,

 You need to implement the Home key handling as an AnAction and use
> registerCustomShortcutSet()
> to associate the Home key with it. Then your handler will be called
> instead
> of IDEA's own Home key handling.
> ]]>

Thanks, it works, but raises another question: specifying
keyboard-shortcut for my actions in plugin.xml makes them visible and
editable in IDE preferences, but also makes them global. For instance,
I want to define a HistoryUpAction mapped to the 'UP' key by default,
which will only work inside of my tool window. Setting
<keyboard-shortcut keymap="$default" first-keystroke="UP"/> overrides
'UP' key for the whole IDE, which is very inconvenient of course
because the 'UP' key stops working in lots of dialogs. Is there a way
to tell IDEA not to do it?

I'd still like to see my default shortcuts in the keyboard layout
editor though, but I'll also have to call registerCustomShortcutSet
again if the user changes the layout I guess.

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Hello Dmitry,

OK, but how to make their shortcuts configurable then? They won't show up in configure->keymap->plugins->(my plugin)..

0
Comment actions Permalink

Hello Konstantin,

Thanks, it works, but raises another question: specifying
keyboard-shortcut for my actions in plugin.xml makes them visible and
editable in IDE preferences, but also makes them global. For instance,
I want to define a HistoryUpAction mapped to the 'UP' key by default,
which will only work inside of my tool window. Setting
<keyboard-shortcut keymap="$default" first-keystroke="UP"/> overrides
'UP' key for the whole IDE, which is very inconvenient of course
because the 'UP' key stops working in lots of dialogs. Is there a way
to tell IDEA not to do it?


Your action should call presentation.setEnabled(false) in its update() method
if it's not in the appropriate context. Then it will not interfere with the
standard IDEA up action.

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Hello Dmitry,

Many thanks, now it works as I want it to :)

0

Please sign in to leave a comment.