Java: how do I remove the default keystrokes from any JComponent?
I want to control which keystrokes belong to which JComponent I even want to know how to delete the default keystroke associated with JComponent and replace it with other favorite keystrokes
I followed the Oracle tutorial, which gave an example of JButton. I tried it and it worked normally, but it didn't work when I tried it with jcombobox!
I tried to delete the space key to prevent JComponent from responding to the space key
I deleted the space key with this Code:
firstButton.getInputMap().put(Keystroke.getKeystroke("SPACE"),"none");
JCombo@R_850_2419 @The same is true
sizesCombo@R_850_2419@.getInputMap().put(Keystroke.getKeystroke("SPACE"),"none");
But it doesn't work, it( JCombo@R_850_2419 @) still respond to the space key
For the firstbutton I deleted the space printer effect; I added the F key, so now when you press the F key on the keyboard, you press the first button, and ant doesn't respond to space Note that even if the firstbutton has no focus, f will be pressed (JComponent. When_in_focused_window)
This is an sscce code showing my example: Note: I deliberately did not add the above code line to the second button "secondbutton", so it still responds to space by default
import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import javax.swing.*; public class KeystrokeTest extends JPanel { JPanel widgetPanel; JPanel textAreaPanel; JButton firstButton; JButton secondButton; JTextArea textArea; JCombo@R_850_2419@<Integer> sizesCombo@R_850_2419@; public Keystroketest() { firstButton = new JButton("First"); firstButton.addActionListener(eventWatcher); firstButton.getInputMap().put(Keystroke.getKeystroke("SPACE"),"none"); firstButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(Keystroke.getKeystroke("F"),"F Key"); firstButton.getActionMap().put("F Key",eventWatcher); secondButton = new JButton("Second"); secondButton.addActionListener(eventWatcher); sizesCombo@R_850_2419@ = new JCombo@R_850_2419@<>(); sizesCombo@R_850_2419@.addItemListener(new itemListenerClass()); for (int i = 1; i <= 8; i++) { sizesCombo@R_850_2419@.addItem(i); } sizesCombo@R_850_2419@.setSelectedIndex(0); sizesCombo@R_850_2419@.getInputMap().put(Keystroke.getKeystroke("SPACE"),"none"); textArea = new JTextArea(0,0); JScrollPane scrollTextArea = new JScrollPane(textArea); scrollTextArea.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); textArea.setEditable(false); widgetPanel = new JPanel(); textAreaPanel = new JPanel(new BorderLayout()); widgetPanel.add(firstButton); widgetPanel.add(secondButton); widgetPanel.add(sizesCombo@R_850_2419@); textAreaPanel.add(scrollTextArea,BorderLayout.CENTER); JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,textAreaPanel,widgetPanel); splitPane.setDividerLocation(280); splitPane.setResizeWeight(.5d); this.setLayout(new BorderLayout()); this.add(splitPane); } AbstractAction eventWatcher = new AbstractAction() { @Override public void actionPerformed(ActionEvent ae) { Object source = ae.getSource(); if (source == firstButton) { textArea.append("First button clicked\n"); } if (source == secondButton) { textArea.append("Second button clicked\n"); } } }; private class itemListenerClass implements ItemListener { @Override public void itemStateChanged(ItemEvent e) { if (e.getSource() == sizesCombo@R_850_2419@) { if (textArea != null) { textArea.append("Item " + sizesCombo@R_850_2419@.getSelectedItem() + "\n"); } } } } private static void createAndShowGUI() { JFrame frame = new JFrame("Keystroke Test"); frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(500,300); frame.add(new Keystroketest(),BorderLayout.CENTER); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokelater(new Runnable() { public void run() { UIManager.put("swing.boldMetal",Boolean.FALSE); createAndShowGUI(); } }); } }
The reason why I want to control the default keystroke of JComponent is because I want to delete the default effect of space on all jcomponents. Except for a button, it will respond to space press. No matter where the focus is, use JComponent WHEN_ IN_ FOCUSED_ Therefore, clicking another component (and moving the focus away from the exception button) will not prevent space from affecting the button
Another point: if you test the above code, you will notice that from JCombo@R_850_2419 @Selecting an item in will produce two rows. If you select item "4", the output in jtextarea is
Why two?
thank you.
Solution
You should use JComponent. Like this WHEN_ ANCESTOR_ OF_ FOCUSED_ Component inputmap (you may notice that I used keyevent and keystroke.getkeystroke (int key, int modifier, Boolean onrelease) because it is easier to read and less prone to errors, that is, typing wrong string parameters, etc.):
sizesCombo@R_850_2419@.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) .put(Keystroke.getKeystroke(KeyEvent.VK_SPACE,false),"none");
As far as I know, the reason well explains here:
So I infer JCombo@R_850_2419 @Is a composite component, so we need the correct inputmap – when_ ANCESTOR_ OF_ FOCUSED_ Component to delete the keybinding function of all internal components of its specific key, i.e. space
As @ mkorbel said (one of his comments) two things may happen:
>Deselect an item > selected an item
These events appear in pairs, just as we deselect the old value when we select a new value Therefore, we must examine and take appropriate action:
@Override public void itemStateChanged(ItemEvent e) { if(e.getStateChange()==ItemEvent.SELECTED) { //am item was selected do something } }
Other recommendations:
>Do not call SetSize. > on JFrame Use appropriate LayoutManager and / or override getPreferredSize to return Dimensions that is suitable for content, and call pack () on JFrame after setting up visibility and adding components.