Java:如何从任何JComponent中删除默认的KeyStrokes?
|
我想控制哪个击键属于哪个Jcomponent.我甚至想知道如何删除与Jcomponent关联的默认击键,并将其替换为其他喜欢的击键. 我跟着这个oracle tutorial,它给出了一个JButton的例子,我尝试了它并且工作正常,但是当我用JComboBox尝试它时它不起作用! 我试图删除SPACE键,这是为了防止JComponent响应SPACE按键 我用这段代码删除了SPACE键: firstButton.getInputMap().put(KeyStroke.getKeyStroke("SPACE"),"none");
JComboBox也是如此 sizesComboBox.getInputMap().put(KeyStroke.getKeyStroke("SPACE"),"none");
但是不起作用,它(JComboBox)仍然响应SPACE键 对于我删除了SPACE印刷机效果的firstButton;我添加了键F,所以现在当你按下键盘上的F键时按下了firstButton,ant没有响应SPACE(意图).请注意,即使firstButton没有焦点,也会发生F的按下(JComponent.WHEN_IN_FOCUSED_WINDOW) 这是一个显示我的例子的SSCCE代码: 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;
JComboBox<Integer> sizesComboBox;
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);
sizesComboBox = new JComboBox<>();
sizesComboBox.addItemListener(new itemListenerClass());
for (int i = 1; i <= 8; i++)
{
sizesComboBox.addItem(i);
}
sizesComboBox.setSelectedIndex(0);
sizesComboBox.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(sizesComboBox);
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 clickedn");
}
if (source == secondButton)
{
textArea.append("Second button clickedn");
}
}
};
private class itemListenerClass implements ItemListener
{
@Override
public void itemStateChanged(ItemEvent e)
{
if (e.getSource() == sizesComboBox)
{
if (textArea != null)
{
textArea.append("Item " + sizesComboBox.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();
}
});
}
}
我想要控制JComponent的默认击键的原因是因为我想在所有JComponent上删除SPACE的默认效果,除了一个按钮,它将响应SPACE按下,无论焦点在哪里,使用JComponent.WHEN_IN_FOCUSED_WINDOW,因此,单击另一个组件(并将焦点从例外按钮移开)将不会阻止SPACE对该按钮的影响. 另一点:如果您测试了上面的代码,您会注意到从JComboBox中选择一个项目会产生两行,如果您选择项目“4”,则JTextArea中的输出为
为什么两个? 谢谢. 解决方法
您应该像这样使用JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT InputMap(您可能会注意到我使用了KeyEvent和KeyStroke.getKeyStroke(int key,int modifier,boolean onRelease),因为它更易读,更不容易出错,即键入错误的字符串参数等.): sizesComboBox.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,false),"none");
据我所知,其原因很好地解释了here:
所以我推断JCombobox是一个复合组件,因此我们需要正确的InputMap – WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,以删除其特定键的所有内部组件KeyBinding功能,即SPACE.
正如@mKorbel所述(他的评论中有1条)可能会发生两件事: >取消选择一个项目 这些事件成对出现,就像我们选择新值时取消选择旧值一样.因此,我们必须检查并采取适当行动: @Override
public void itemStateChanged(ItemEvent e)
{
if(e.getStateChange()==ItemEvent.SELECTED) {
//am item was selected do something
}
}
其他建议: >不要在JFrame上调用setSize.>使用适当的LayoutManager和/或覆盖getPreferredSize以返回适合内容的Dimensions,并在设置可见之前和添加组件之后调用JFrame上的pack(). (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
