4

I created a small application using Netbeans 8.1 on OSX, doing these steps:

  • I created a new JForm using category "Swing GUI forms"
  • I added three menus to it:

enter image description here

  • I added a JDialog with text fields and linked it to the third menu ("TAnalyse").

In this JDialog i need copy / paste functionality for the text fields. The problem is: copy / paste only works in this dialog with "ctrl" + "c","x" or "v" and not with the osx standard "cmd" key.

I tried to add the following line of code to the constructor of the JForm but it didn't work:

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

Additional information: I am using JDK7 and OSX Yosemite. Look and feel is "Nimbus". The two other menus ("File","Edit") aren't implemented yet.

Can you give a hint for a solution?

Update: I created another small example with Netbeans GUI builder (Swing GUI Forms -> JDialog). I just added a menu bar to the JFrame and the a JMenuItem in the GUI builder. With the remarks from the answer below i added manually some code to the constructor:

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);
    }

The result is:

enter image description here

Update2: I created another small example with Netbeans GUI builder (Swing GUI Forms -> Application sample form).

The result is:

enter image description here

Finally i created an example with Netbeans (Empty Java file) with source code slightly modified from the answer below.

The result is:

enter image description here

Bebass
  • 141
  • 11
  • Any luck using the `DefaultEditorKit` actions with the approach shown [here](http://stackoverflow.com/a/5129757/230513)? – trashgod Jan 15 '16 at 22:14
  • I took the code from your example into a new empty NetBeans project and changed the chooser into 'chooser.showSaveDialog' to get a textfield for testing. Copy & Paste works with OSX cmd-keys + 'c' or 'x' or 'v'. But i have no idea why. I haven't found any code relating to this topic in the generated gui code of the app described above. I think i don't understand the whole background of the topic. Could you provide more information about the underlying mechanisms? – Bebass Jan 16 '16 at 12:18

1 Answers1

3

Java uses Actions to encapsulate functionality and Key Bindings to respond to keys typed by the user. In this example, the DefaultEditorKit action CopyAction is used as the menu item's Action. It will copy the user's selection from the focused text component to the clipboard. Use Toolkit.getMenuShortcutKeyMask() to get the correct accelerator, as discussed here.

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://stackoverflow.com/a/34830519/230513
 */
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);
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Thanks for clarifying the mechanisms. I think when using Netbeans GUI builder to create menus it is preferable to just add the menu items with it and attach actions and accelerators manually in the source code. What's your opinion? – Bebass Jan 17 '16 at 12:49
  • I created a small update to the original question. It is so far ok, but instead of the cmd-Key symbol i get a text 'meta'. Do you know how to tweak this? – Bebass Jan 17 '16 at 13:24
  • I'm not sure how it fails; maybe an aliased variable? I prefer to limit the scope of the GUI builder using the approach shown [here](http://stackoverflow.com/a/2561540/230513). – trashgod Jan 17 '16 at 17:50
  • I added two more examples with different scope of the GUI builder. Obviously the form type in the GUI builder makes a difference. While copying the code i noticed that 'getDefaultToolkit()' is from AWT. May this cause a conflict with the Swing forms? – Bebass Jan 19 '16 at 19:39
  • @Bebass: there's no conflict, as Swing builds on AWT; you may want to open new question that focuses on menus in the GUI builder; I just don't use it enough to spot the anomaly. – trashgod Jan 19 '16 at 20:51
  • I opened a new question and posted a solution: http://stackoverflow.com/q/35925578/5081387 – Bebass Apr 03 '16 at 11:12