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.
