启用禁用组件的特定键绑定

问题描述 投票:0回答:1

就我而言,我希望能够在

ctrl F6
上启用和禁用
JDesktopPane

现在我以这种方式禁用它:

KeyStroke remove = KeyStroke.getKeyStroke(KeyEvent.VK_F6, InputEvent.CTRL_DOWN_MASK);
InputMap im = desktop.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
im.put(remove, "none");

并且按键绑定似乎不再有效。

我不知道如何重新启用它,或者在禁用之前保存什么以便稍后再次启用它。

基于答案https://stackoverflow.com/a/76689063/399637 我尝试处理

Action
,这是一个测试代码:

desktop = new JDesktopPane();
KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_F6, InputEvent.CTRL_DOWN_MASK);
InputMap im = desktop.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
ActionMap am = desktop.getActionMap();
String key = (String)im.get(keyStroke);
Action action = am.get(key);
assert action != null;
action.setEnabled(false);

但是它不起作用,

control f6
仍然在
JDesktopPane
中启用。

java swing
1个回答
1
投票

你会想要获取原始的键值,并用它来获取 ActionMap 所持有的原始 Action,保存该值,然后当你想恢复键的原始功能时替换它:

KeyStroke remove = KeyStroke.getKeyStroke(KeyEvent.VK_F6, InputEvent.CTRL_DOWN_MASK);
InputMap im = desktop.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
Object keyValue = im.get(remove);
ActionMap am = desktop.getActionMap();

// store this original action somewhere   
Action originalAction = am.get(keyValue);

然后,稍后当您想要将 f6 ctrl-down 按键恢复为原始功能时,将该操作放回操作映射中,将其与输入映射中的键值关联起来。


实际上,如果您不取消按键与操作的关联,则可以在与感兴趣的击键关联的操作上使用

.enabled(true)
.enabled(false)
。例如,在下面的代码中,我可以通过使用 ctrl-V 按键启用和禁用相关操作来启用和禁用 JTextArea 使用 ctrl-V 粘贴文本的功能。

import java.awt.BorderLayout;
import java.awt.event.InputEvent;
import java.awt.event.ItemEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class TestInputActionMaps extends JPanel {
    private JCheckBox enableAction = new JCheckBox("Enable Action", true);
    private KeyStroke controlV = KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK);
    private JTextArea textArea = new JTextArea("This is text", 10, 30);
    private InputMap inputMap = textArea.getInputMap(JComponent.WHEN_FOCUSED);
    private ActionMap actionMap = textArea.getActionMap();    
    String ctrlVKey = (String) inputMap.get(controlV);
    Action ctrlVAction = actionMap.get(ctrlVKey);
    
    public TestInputActionMaps() {
        enableAction.addItemListener(e -> checkBoxChanged(e));
        
        
        textArea.setWrapStyleWord(true);
        textArea.setLineWrap(true);
        JScrollPane scrollPane = new JScrollPane(textArea);
        
        JPanel topPanel = new JPanel();
        topPanel.add(enableAction);
        
        setLayout(new BorderLayout());
        add(topPanel, BorderLayout.PAGE_START);
        add(scrollPane);
    }
    
    private void checkBoxChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
            ctrlVAction.setEnabled(true);
        } else {
            ctrlVAction.setEnabled(false);
        }
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            TestInputActionMaps mainPanel = new TestInputActionMaps();

            JFrame frame = new JFrame("GUI");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.