views:

226

answers:

3

Hi, I'm trying to remap several navigation keys:

  • ENTER: to work like standard TAB behavior (focus to next control)
  • SHIFT+ENTER: to work like SHIFT+TAB behavior (focus to previous control)
  • UP / DOWN arrows: previous /next control
  • etc

I tried with a couple of options but without luck:

from javax.swing import *
from java.awt import *

class JTextFieldX(JTextField):

    def __init__(self, *args):
     # Thanks, Jack!!
        JTextField.__init__(
            self,
            focusGained=self.onGotFocus,
            focusLost=self.onLostFocus,
            *args)

    def onGotFocus (self, event):
        print "onGotFocus "
        self.selectionStart = 0
        self.selectionEnd = len(self.text)

    def onLostFocus (self, event):
        print "onLostFocus ", self.name


class Test(JFrame):
    def __init__(self):
        JFrame.__init__(self,
                        'JDesktopPane and JInternalFrame Demo',
                        size=(600, 300),
                        defaultCloseOperation=JFrame.EXIT_ON_CLOSE)

        self.desktop = JDesktopPane()
        self.contentPane.add(JScrollPane(self.desktop)) # This is the same as self.getContentPane().add(...)

        frame = JInternalFrame("Frame", 1, 1, 1, 1, size=(400, 400), visible=1)
        panel = JPanel()

        self.label = JLabel('Hello from Jython')
        panel.add(self.label)

        self.textfield1 = JTextFieldX('Type something here', 15)
        panel.add(self.textfield1)

        self.textfield2 = JTextFieldX('and click Copy', 15)
        panel.add(self.textfield2)

        panel.add(copyButton)

        frame.add(panel)
        frame.pack()
        self.desktop.add(frame)

        # ENTER=SPACE remapping for buttons (works ok, but only for buttons)
#        inputMap = UIManager.getDefaults().get("Button.focusInputMap")
#        pressedAction = inputMap.get(KeyStroke.getKeyStroke("pressed SPACE"));
#        releasedAction = inputMap.get(KeyStroke.getKeyStroke("released SPACE"));
#        # pressedAction = self.noAction
#        inputMap.put (KeyStroke.getKeyStroke("pressed ENTER"), pressedAction)
#        inputMap.put (KeyStroke.getKeyStroke("released ENTER"), releasedAction)

#        # Attemp to remap ENTER=TAB for TextFields (didn't work, no errors)
#        inputMap = UIManager.getDefaults().get("TextField.focusInputMap")
#        pressedAction = inputMap.get(KeyStroke.getKeyStroke("pressed TAB"));
#        releasedAction = inputMap.get(KeyStroke.getKeyStroke("released TAB"));
#        inputMap.put (KeyStroke.getKeyStroke("pressed W"), pressedAction)
#        inputMap.put (KeyStroke.getKeyStroke("released W"), releasedAction)

#        # Attemp to remap ENTER=TAB for all controls (didn't work, no errors)
#        spaceMap = self.textfield1.getInputMap().get(KeyStroke.getKeyStroke(event.KeyEvent.VK_TAB, 0, True));
#        self.textfield1.getInputMap().put(KeyStroke.getKeyStroke(event.KeyEvent.VK_ENTER, 0, True),spaceMap);

        frame.setSelected(1)
        frame.moveToFront()

    def noAction (self, event):
        print "noAction"
        pass

if __name__ == '__main__':
    test = Test()
    test.setLocation(100, 100)
    test.show()
A: 

Add keyPressed to the swing competent that you want to listen for the key press on

self.textfield1 = JTextField('Type something here',15,focusGained=self.myOnFocus,keyPressed=self.myOnKey)

myOnKey can be named anything in that method do something like:

def myOnKey(self,event):
    print str(event) # see all other info you can get.
    key_code = event.keyCode
    if key_code == 10:
        print "you pressed enter"
        # simulate the "tab" by just focusing the next textbox...

Then you should just be able to play around with the print str(event) command to get all the proper keycodes that you want.

Jack
Ok so far, but then how can I (generically) get the next focusable control?I tried with self.nextFocusableComponent but it's set to None.
PabloG
A: 

I made a new post for readability.

self.textfield1 = JTextField('Type something here',15,focusGained=self.myOnFocus,keyPressed=self.myOnKey)

#create textfield2...must be created before can be referenced below.

self.textfield1.setNextFocusableComponent(self.textfield2)

then in your event handler:

def myOnKey(self,event):
    print str(event) # see all other info you can get.
    key_code = event.keyCode
    if key_code == 10:
        print "you pressed enter"
        # simulate the "tab" just focus next textbox...
        gotFocus = event.getComponent()
        nextToFocus = gotFocus.nextFocusableComponent
        nextToFocus.requestFocus()

Should do it.

Jack
@Jack: first of all, thanks for your help.I'm trying the code you posted, but eithergotFocus.nextFocusableComponentandgotFocus.getNextFocusableComponent()return None.TIA,Pablo
PabloG
did you setNextFocusableComponent like I did in my first block???
Jack
...because the code above works for me with jython 2.5
Jack
+1  A: 

Finally used part of Jack's answer (the keyPressed event) but without manually setting setNextFocusableComponent:

keyFocusMgr = KeyboardFocusManager.getCurrentKeyboardFocusManager()
keyFocusMgr.focusNextComponent()
PabloG
Cool. Glad you got it. Thanks for posting this.
Jack