Windows 和 Mac 在密钥检测方面的 Java 差异
Posted
技术标签:
【中文标题】Windows 和 Mac 在密钥检测方面的 Java 差异【英文标题】:Java difference in key detection between Windows and Mac 【发布时间】:2012-04-16 02:20:54 【问题描述】:我有一个带有键侦听器的 JList,以便用户可以轻松地从列表中删除项目。在 Windows 上,它工作正常。您按下删除键,该项目被删除。在 mac 上,程序不响应删除键。我正在使用KeyEvent.VK_DELETE
,我认为这是一种检测特殊键的平台中立方式。我应该以其他方式检测 Mac 上的按键吗?
studentJList.setModel(studentListModel); // a custom model I wrote
studentJList.addKeyListener(new KeyListener()
@Override
public void keyPressed(KeyEvent e)
if (e.getKeyCode() == KeyEvent.VK_DELETE)
studentListModel.remove(studentJList.getSelectedIndex());
studentJList.revalidate();
@Override
public void keyReleased(KeyEvent e)
@Override
public void keyTyped(KeyEvent e)
);
【问题讨论】:
【参考方案1】:使用keybindings 代替关键侦听器,所有平台上的行为都相同。
另请参阅KeyAdapter listener works in Windows, not on Mac,这或多或少是相同的问题,解决方案也适用于您的问题。
【讨论】:
谢谢。我以前从未接触过 keyBindings,但本教程让它看起来很简单。不过,我不明白为什么 keyListener 不应该工作。 @mKorbel - 感谢您发布此代码示例。 在链接的问题中,其他人提出了 Windows 和 OSX 之间焦点行为存在差异的可能性。并且 keylistener 需要在触发之前获得焦点 @Thorn 确保你遵循 (@kleopatra) 的好建议,这些评论让我发疯 :-) 我遇到了一个相关的问题,但代码在 MacOS 下运行良好,在 Windows 下运行不佳。 Shift 键事件不会在 MacOS 下生成,因此主要在该平台上编写的开发人员并不期望。由于“虚假”换档键事件,Windows 实现被破坏。【参考方案2】:例如
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ListDemo extends JPanel
private static final long serialVersionUID = 1L;
private JFrame frame = new JFrame("ListDemo");
private JList list;
private DefaultListModel listModel;
public ListDemo()
super(new BorderLayout());
listModel = new DefaultListModel();
listModel.addElement("Jane Doe");
listModel.addElement("John Smith");
listModel.addElement("Kathy Green");
list = new JList(listModel);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setSelectedIndex(0);
list.setVisibleRowCount(5);
JScrollPane listScrollPane = new JScrollPane(list);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(listScrollPane, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
setKeyBindings();
private void setKeyBindings()
list.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.put(KeyStroke.getKeyStroke("DELETE"), "clickDelete");
list.getActionMap().put("clickDelete", new AbstractAction()
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e)
int index = list.getSelectedIndex();
if (index > -1)
listModel.remove(index);
);
public static void main(String[] args)
javax.swing.SwingUtilities.invokeLater(new Runnable()
public void run()
ListDemo listDemo = new ListDemo();
);
【讨论】:
我发现我浪费了太多时间可能是因为您的代码又不是 sscce。 SCNR :-) 在更严重的情况下:不要使用 ComponentInputMap(这是 WHEN_IN_FOCUSED_WINDOW 类型的一种),除非绝对必要,否则很难获得足够独特的此类绑定,并且它们始终是最后一个看见。相反,使用最近的父母的 WHEN_ANCESTOR 注册绑定,这是有意义的,这里是 f.i.内容窗格 @kleopatra 同意,但这是限制 KeyStroke DELETE 的原因,仅当 JList 在窗口中有焦点时 :-) 也许是我的肮脏黑客,也许是我的非_****,因为可能放这个监听器直接指向 JList .... 仅当 JList 有焦点时 如果这是您的意图,则绑定是完全错误的 - 使用 WHEN_FOCUSED 类型的列表的 inputMap - 显然与 OP 具有相同的焦点相关问题在 keyListener ;-) @kleopatra 请查看我的编辑,这是我了解KeyBindings
工作原理的方式,我感谢您的宝贵信息,但无法测试ANCESTOR
和@987654324 之间的差异和触发事件@现在以上是关于Windows 和 Mac 在密钥检测方面的 Java 差异的主要内容,如果未能解决你的问题,请参考以下文章
sshd 的 Windows 10 OpenSSH 授权密钥错误
Parallels Desktop 12激活密钥+完整版免费下载
C/C++/Assembly 以编程方式检测超线程在 Windows、Mac 和 Linux 上是不是处于活动状态 [重复]