在OSX Java应用程序中,仅使用ctrl键才能使用复制粘贴快捷键。

4

我在OSX上使用Netbeans 8.1创建了一个小应用程序,具体步骤如下:

  • 我使用“Swing GUI forms”类别创建了一个新的JForm
  • 我添加了三个菜单:

enter image description here

  • 我添加了一个带有文本字段的JDialog,并将其链接到第三个菜单(“TAnalyse”)。

在这个JDialog中,我需要对文本字段进行复制/粘贴功能。问题是:只能使用“ctrl”+“c”,“x”或“v”来在此对话框中执行复制/粘贴操作,不能使用OSX标准的“cmd”键。

我尝试将以下代码行添加到JForm的构造函数中,但不起作用:

KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());

额外信息: 我正在使用JDK7和OSX Yosemite。外观是“Nimbus”。另外两个菜单(“文件”,“编辑”)尚未实现。
你能给出解决方案的提示吗?
更新: 我使用Netbeans GUI构建器(Swing GUI表单 -> JDialog)创建了另一个小例子。我只是在JFrame中添加了一个菜单栏和GUI构建器中的JMenuItem。根据下面答案中的注释,我手动添加了一些代码到构造函数中:
public NewJDialogGUI(java.awt.Frame parent, boolean modal) {
        super(parent, modal);   
        initComponents();

        AbstractAction copyAction = new DefaultEditorKit.CopyAction();
        copyAction.putValue(Action.ACCELERATOR_KEY,KeyStroke.getKeyStroke(KeyEvent.VK_C, MASK));

        this.jMenuItem1.setAction(copyAction);
        this.jMenuItem1.setText("Copy");
        this.jMenuItem1.setMnemonic(KeyEvent.VK_C);
    }

结果如下:

结果是:

输入图像描述

更新2: 我使用Netbeans GUI构建器(Swing GUI Forms -> Application sample form)创建了另一个小例子。

结果如下:

输入图像描述

最后,我使用Netbeans(空Java文件)创建了一个示例,其中源代码稍微修改了下面的答案。

结果如下:

输入图像描述


你有没有尝试使用这里展示的方法(https://dev59.com/22435IYBdhLWcg3w7kwK#5129757)来使用`DefaultEditorKit`操作? - trashgod
我将您示例中的代码复制到一个新的空NetBeans项目中,并将选择器更改为“chooser.showSaveDialog”,以获取用于测试的文本字段。在OSX上,使用cmd键+c或x或v可以进行复制和粘贴。但我不知道为什么。我在所述应用程序的生成GUI代码中没有找到与此主题相关的任何代码。我认为我不理解整个主题的背景。您能否提供有关底层机制的更多信息? - Bebass
1个回答

3
Java使用操作来封装功能,使用键绑定响应用户键入的按键。在此示例中,DefaultEditorKit操作CopyAction用作菜单项的Action。它将从聚焦文本组件中复制用户选择到剪贴板。使用Toolkit.getMenuShortcutKeyMask()获取正确的加速键,如此处所述。

image

import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.text.DefaultEditorKit;

/**
 * @see https://dev59.com/UJLea4cB1Zd3GeqP9Pqe#34830519
 */
public class MenuTest {

    private static final int MASK
        = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();

    private void display() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("Edit");
        menu.setMnemonic(KeyEvent.VK_E);
        JMenuItem menuItem = new JMenuItem();
        AbstractAction copyAction = new DefaultEditorKit.CopyAction();
        copyAction.putValue(Action.ACCELERATOR_KEY,
            KeyStroke.getKeyStroke(KeyEvent.VK_C, MASK));
        menuItem.setAction(copyAction);
        menuItem.setText("Copy");
        menu.add(menuItem);
        menuBar.add(menu);
        f.setJMenuBar(menuBar);
        f.add(new JTextField(10));
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new MenuTest()::display);
    }
}

感谢您澄清机制。我认为,使用Netbeans GUI构建器创建菜单时,最好只需添加菜单项,并在源代码中手动附加操作和加速键。您的意见是什么? - Bebass
我对原问题进行了小更新。目前还可以,但是我得到的不是cmd键符号,而是一个文本“meta”。你知道如何调整吗? - Bebass
我不确定它是如何失败的,也许是一个别名变量?我更喜欢使用此处所示的方法[https://dev59.com/-UzSa4cB1Zd3GeqPqu7i#2561540]来限制GUI构建器的范围。 - trashgod
我添加了两个不同范围的GUI生成器示例。显然,GUI生成器中的表单类型会产生影响。在复制代码时,我注意到“getDefaultToolkit()”来自AWT。这可能会导致与Swing表单冲突吗? - Bebass
@Bebass:没有冲突,因为Swing是在AWT的基础上构建的;你可能想要打开一个新问题,专注于GUI构建器中的菜单;我只是没有足够的使用量来发现这个异常。 - trashgod
我打开了一个新的问题并发布了解决方案:http://stackoverflow.com/q/35925578/5081387 - Bebass

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接