在Swing App中检测CTRL + V但保留原始功能

phi*_*294 2 java swing keylistener key-bindings ctrl

在聊天应用程序中,我希望用户能够从他/她的剪贴板发送图像.为此,我想抓住任何CTRL+V键盘输入.由于默认情况下应该可以粘贴文本,因此不能覆盖原始的ctrl + v-function(粘贴文本).

我看到有两种方法,其中一种方法对我无效:

1st:取自官方Java文档:KEY LISTENER

editorPane.addKeyListener(new KeyListener() {
    @Override
    public void keyPressed(KeyEvent e) {
        e.getKeyChar()
        // when I press ctrl+v, ^ this is falsely a white square character, looks like (U+25A1). Plain v without ctrl does work.
        e.getKeyCode()
        // ^ this is falsely 0

        // (e.getModifiersEx() correctly returns InputEvent.CTRL_DOWN_MASK)
    }
Run Code Online (Sandbox Code Playgroud)

第二名:关键约束力

InputMap iMap = editorPane.getInputMap(condition);
ActionMap aMap = editorPane.getActionMap();
iMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK), "ctrlV");
aMap.put("ctrlV", new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        // works, but overrides natural ctrl+v function!
    }
});
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

注意:我使用的是"外国"键盘布局(德语).但我不明白为什么这应该有所不同 - 我非常希望我的应用程序在国际上运作.

干杯

编辑.Alt+SomeKey但是KeyListener正确识别

EDIT2.将键盘布局更改为美国后,问题仍然存在.

Gui*_*let 5

坚持使用Keybindings:KeyListener是一个低级API,而Keybindings将为您提供一致,可预测和健壮的行为.

这里的解决方案非常简单.您可以通过添加一个CombinedAction将执行绑定到的"原始"操作CTRL+V和要执行的"自定义"操作的类来自行组合操作.

请参阅以下结合两个操作的小示例(此处我的自定义操作是Sysout):

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

import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.ScrollPaneConstants;

public class TestEditorPane {
    private JEditorPane editorPane;

    public static class CombinedAction implements ActionListener {
        private final ActionListener action1;
        private final ActionListener action2;

        public CombinedAction(ActionListener action1, ActionListener action2) {
            super();
            this.action1 = action1;
            this.action2 = action2;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (action1 != null) {
                action1.actionPerformed(e);
            }
            if (action2 != null) {
                action2.actionPerformed(e);
            }
        }

    }

    public TestEditorPane() {
    }

    private void initUI() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // JTEXTBOX
        editorPane = new JEditorPane();
        KeyStroke ctrlV = KeyStroke.getKeyStroke(KeyEvent.VK_V, KeyEvent.CTRL_DOWN_MASK);
        final ActionListener ctrlVAction = editorPane.getActionForKeyStroke(ctrlV);
        editorPane.registerKeyboardAction(new CombinedAction(ctrlVAction, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("This is my action on CTRL+V");
            }
        }), ctrlV, JComponent.WHEN_FOCUSED);
        // JSCROLLPANE
        JScrollPane scroll1 = new JScrollPane(editorPane);
        scroll1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        scroll1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        frame.add(scroll1);
        frame.setSize(400, 400);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    TestEditorPane test = new TestEditorPane();
                    test.initUI();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

}
Run Code Online (Sandbox Code Playgroud)