I have two Jtables Emplyoee and Manager.If I enter on Emplyoee Table then focus should go on Manager table.I used ChangeSelection but it is not working.
The simplest solution I can think of is to attach a key binding to the Employee table that moves focus to the Manager
Take a look at Key Bindings for more details.
Within your action handler, you would need to call requestFocusInWindow using a instance of the Manager table.
I did look at the focus sub system, but this would effect the entire focus root, which I felt was beyond the scope of what you were asking.
Updated
You could change the focus traversal keys, but this will only move focus to the next focusable component...
Set forward = new HashSet(table.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
forward.add(KeyStroke.getKeyStroke("ENTER"));
table.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forward);
//Set backward = new HashSet(table.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
//backward.add(KeyStroke.getKeyStroke("shift TAB"));
//table.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backward);
Related
I asked this question a little earlier, but maybe some of you were asleep, as where I live at the time it was probably very early in silicon valley.
My program has assigned new functions to the arrow keys, but for the very last part of the Swing display's presentation I need them to function normally within a TextArea, moing the cursor and such.
Is there a way to restore to defaults, or through an AbstractAction assign simple movement of the cursor once again?
The original answer I gave you showed how to replace the Action. If you need to restore the default Action then it is probably easier to create a new InputMap and ActionMap entry for the Action. The Key Bindings link I gave you shows how to do this.
Then when you need to restore the default Action you can use:
textField.getInputMap().put(keystroke, "none");
This will cause the original InputMap to be search again.
Another approach it to save the Action before you update the ActionMap with the custom Action. Something like:
Action original = textField.getActionMap().get(...);
Reread the Key Bindings link to better understand the usage of the InputMap and ActionMap.
Note: see the edit (save some time reading)
I'm trying to make my mind-mapping program respond to shortcuts like CTRL+RIGHT (reordering nodes) and TAB (insert child at next indent level). I have a JPanel that handles all of the keystrokes. It resides inside of a JTabbedPane that might be the cause for Key Bindings not working. I've chickened out and decided to just use KeyListener.
The problem is that with the aforementioned key combinations, Swing automatically shifts the focus to some other component. I'd rather not manually put setFocusable(false) everywhere. How can I disable these shortcuts altogether in such a way that the focus will not be shifted, and the relevant KeyEvents will still be sent to my JPanel?
Edit:
I used the following code:
for (int id : new int[] {KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS})
setFocusTraversalKeys(id, Collections.EMPTY_SET);
to disable the default traversal keys (particularly TAB.)
Now the issue is actually why CTRL+UP causes a loss of focus. When pressing CTRL+DOWN, for instance, it's fine. The component behaves as expected. But with CTRL+UP, it works as expected and then focus is shifted/lost somehow. Can anyone say what CTRL+UP means and how to disable it wherever it is? Google isn't helping.
KeyBinding are used for all KeyEvents implemented in Swing APIs, maybe there is/are conflict
is required to override required KeyBindings, change used Keys, set to null, e.i. depends of your requirements
list of KeyBindings by #camickr
I have a JTree, a JTable and a JList which displays the same set of objects, but in different order and with different information. If an item is selected from one of the Component, I want to select the same object on the other two Components (meaning they should be highlighted). Naturally I monitor the selection events with a Listener. Here is the problem, when a Component retrieves the selected object, I'll have to make sure the object is selected on the other Components by calling selection methods on them. This, will then notify the selection listeners on the other two components. But each of those events will in turn call selection events on components other than itself, causing an infinite loop going among the three Components.
I see one solution is to use a boolean flag, and make the listeners not propagate the selection if the flag is set. However, this seems cumbersome and not elegant. Is there a way to simply tell JTree, JTable and JList to make the selection but not fire any events (as oppose to fire an event and then catching and stopping it with a boolean flag)?
Take a look at SharedModelDemo. I think it does what you're looking for.
I would use a flag indicating whether it's user changes or internal changes but yu can also remove listeners before selection call and add them after to prevent events firing.
I have added some accelerators to the main menu, using MenuItem.setAccelerator(). Just basic stuff like ctrl-c for copy, etc.
This works ok. But the app is a bit like an IDE, it has several panels containing JTables. If a table cell has focus, it absorbs the accelerator key, which means the main menu never sees it.
Clearly, if an editable table cell is active I would like the cut and paste keys to function normally, but in every other case I would like the main menu to respond.
Any ideas?
KeyStrokes go to the component that has focus first. Since JTable binds Ctrl+C to an Action, that action is invoked.
If you don't like the default Action of the table, then you would need to remove the binding from the table.
Read the section from the Swing tutorial on How to Use Key Bindings. It shows you how to remove a binding.
Thanks, that got me on the right track.
Removing the bindings didn't quite work, it just stopped the table doing its default action so the keypress was ignored altogether.
However, adding this to the table itself worked ok:
component.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK), "copy");
component.getActionMap().put("copy", actions.copyAction);
(Repeated for each desired key of course). Needs to be kept in synch with any changes to the main menu itself, but I can't see a way to avoid that with any method.
I've a problem with setAccelerator(). Right now, I have the code that works for Ctrl+X for DELETE operation. I want to set the accelerator to Shift+Delete as well for same JMenuItem.
My code as follows:
JMenuItem item = new JMenuItem(menuText);
item.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_X, KeyEvent.CTRL_MASK));
item.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_DELETE, KeyEvent.SHIFT_MASK));
but this is working only for Shift+Delete operation. Seems it is overriding the Ctrl+X operation. Can we make both these keystrokes work at the same time?
Please guide.
Yes it can be done. Behind the scenes the setAccelerator() is just creating a Key Binding, however as you noticed the second binding replaces the first.
So, you need to create an Action (not an ActionListener) to add the to the menu item. Read the section from the Swing tutorial on How to Use Actions for more information. Now that you have created the Action, you can share the Action with another KeyStroke by manually creating a Key Binding. You can read the section from the Swing tutorial on How to Use Key Bindings for a detailed explanation. Or you can read my blog on Key Bindings which give some simple code examples.
This second binding will not show up on the menu item itself.
From: http://java.sun.com/j2se/1.4.2/docs/api/java/awt/AWTEvent.html
The masks are also used to specify to which types of events an AWTEventListener should listen.
So you can combine the mask for two keys, but not the KeyEvents.
item.setAccelerator(
KeyStroke.getKeyStroke(
KeyEvent.VK_X, KeyEvent.CTRL_MASK + KeyEvent.SHIFT_MASK));
A workaround solution would be to catch the KeyEvent in the middle (after your component fired it, but before your listeners will act on it) and check, whether its one of the two combinations. Then fire one event, on which you programmatically agree to represent the action you wanted.
The second call indeed overrides the accelerator. If the method starts with set, there will be only one. If the method starts with add, you can have more than one (for example for a number of listeners).
If you want multiple keystrokes to do the same, I think you should add a keyListener to the top frame (or panel, dialog, ...) which invokes the action listeners added to the menuItem.