gpt4 book ai didi

java - JMenuItem 快捷键 Ctrl-C/Ctrl-V 或 Ctrl-Insert/Shift-Insert 不再起作用

转载 作者:行者123 更新时间:2023-12-04 05:01:03 51 4
gpt4 key购买 nike

我有一个较旧的基于 Java swing 的独立应用程序,它使用 JFrame 和 JMenuBar,其中包含多个 Jmenu 元素(具有相应的 JMenuItem 项)。

在 Windows(7 和 vista)上升级到最新的 1.6.0_41(或 1.7.x)JVM 后,我注意到带有快捷键 Ctrl-C(或 Ctrl-Insert)的菜单项不再收到它的 ActionEvent,如果JTable 被添加到框架中。但是,如果通过鼠标单击访问菜单,则会调用菜单 ActionListener。如果删除了 JTable,则该快捷方式有效。如果我将快捷方式组合更改为 Ctrl-C 或 Ctrl-Insert(即 Ctrl-L)以外的其他内容,则会调用 ActionListener。

它过去的工作方式(我刚刚在 Windows Vista 上使用 jvm 1.4 确认了它 - 我知道该环境得到任何认真关注已经有一段时间了 :) 是 Ctrl-C 将执行标准复制到剪贴板功能如果焦点位于可编辑字段内,则为 JTable。否则,我的菜单 ActionListener 是通过 setAccelerator() 方法分配的快捷方式调用的。

看起来 JTable 实现在 1.6.* 中发生了变化,以在 Windows 上以不同方式处理 Ctrl-C 绑定(bind)事件。

在 Mac OS (JVM 1.6.0_43) 上运行这个应用程序我可以看到 ActionListener 是通过 Ctrl-C 快捷方式调用的。虽然可能是因为 JTable 在 Mac OS 下使用 Command-C 而不是 Ctrl-C 来复制到剪贴板。

我已经提取了演示问题的代码的相关部分。非常感谢任何建议。

public class TestFrame extends JFrame {

public TestFrame(String title) {

super(title);
}

private void init() {

getContentPane().setLayout(new BorderLayout());

addMenu();
addTable();

// Change default exit operation
setDefaultCloseOperation(EXIT_ON_CLOSE);

pack();
setVisible(true);
}

private void addTable() {

JTable jTable = new JTable(createTableModel());

// Place table in JScrollPane
JScrollPane scrollPane = new JScrollPane(jTable);

// Add Table
add(scrollPane, BorderLayout.CENTER);
}

private TableModel createTableModel() {

Object[][] data = new Object[][]{
{new Date(), "First Row, 2nd column", "First Row, 3rd column"},
{new Date(), "Second Row, 2nd column", "Second Row, 3rd column"},
};

Object[] columnNames = new Object[]{"Date", "Type", "Description"};

DefaultTableModel model = new DefaultTableModel(data, columnNames) {

public boolean isCellEditable(int row, int column) {
return column != 0;
}

};

return model;
}

private void addMenu() {

// Create the menu bar.
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);

JMenu editMenu = new JMenu("Edit");
menuBar.add(editMenu);

TestActionListener listener = new TestActionListener();
JMenuItem menuItem = null;

menuItem = new JMenuItem("Copy 1");
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, ActionEvent.CTRL_MASK));
menuItem.addActionListener(listener);
editMenu.add(menuItem);

menuItem = new JMenuItem("Copy 2");
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK));
menuItem.addActionListener(listener);
editMenu.add(menuItem);

menuItem = new JMenuItem("Copy 3");
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, ActionEvent.CTRL_MASK));
menuItem.addActionListener(listener);
editMenu.add(menuItem);
}


public static void main(String[] args) {

TestFrame frame = new TestFrame("Test");
frame.init();
}


private static class TestActionListener implements ActionListener {

public void actionPerformed(ActionEvent e) {
System.out.println("TestFrame.TestActionListener.actionPerformed(): e="+ e);
}
}

}

最佳答案

问题是您的框架没有聚焦,并且整个组件层次结构中没有元素具有焦点,这意味着没有人会“捕获”事件并尝试用它做某事。由于JMenuItem将他们的快捷方式绑定(bind)到输入映射 JComponent.WHEN_IN_FOCUSED_WINDOW ,您的快捷方式永远不会“回答”事件。

要解决此问题,请将焦点放在其中一个组件上或直接放在 JFrame 上。 (例如 frame.requestFocusInWindow(); )。这里的小例子:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class TestFrame extends JFrame {

public TestFrame(String title) {

super(title);
}

private void init() {

getContentPane().setLayout(new BorderLayout());

addMenu();
addTable();

// Change default exit operation
setDefaultCloseOperation(EXIT_ON_CLOSE);

pack();
setVisible(true);
}

private void addTable() {

JTable jTable = new JTable();

// Place table in JScrollPane
JScrollPane scrollPane = new JScrollPane(jTable);

// Add Table
add(scrollPane, BorderLayout.CENTER);
}

private void addMenu() {

// Create the menu bar.
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);

JMenu editMenu = new JMenu("Edit");
menuBar.add(editMenu);

TestActionListener listener = new TestActionListener();
JMenuItem menuItem = null;

menuItem = new JMenuItem("Copy 1");
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, KeyEvent.CTRL_MASK));
menuItem.addActionListener(listener);
editMenu.add(menuItem);

menuItem = new JMenuItem("Copy 2");
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_MASK));
menuItem.addActionListener(listener);
editMenu.add(menuItem);

menuItem = new JMenuItem("Copy 3");
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.CTRL_MASK));
menuItem.addActionListener(listener);
editMenu.add(menuItem);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
TestFrame frame = new TestFrame("Test");
frame.init();
frame.requestFocusInWindow();
}
});
}

private static class TestActionListener implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
System.out.println("TestFrame.TestActionListener.actionPerformed(): e=" + e);
}
}
}

补充说明:
  • 不要扩展 JFrame如果不需要
  • 使用 SwingUtilities.invokeLater() 从事件调度线程 (EDT) 启动您的 UI
  • 关于java - JMenuItem 快捷键 Ctrl-C/Ctrl-V 或 Ctrl-Insert/Shift-Insert 不再起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16138826/

    51 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com