java - 键绑定(bind)不适用于某些键,例如插入、删除

标签 java swing jtable key-bindings

我正在尝试绑定(bind) JTable 的快捷方式,它对于字母表工作正常,但不适用于 InsertDelete空格

例如,下面的代码适用于 Ctrl+I 或任何字母表,但如果我选择 Ctrl+Insert 它不起作用,这是为什么?

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.table.DefaultTableModel;

public class NewClass {
public static void main(String args[]) {

    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Windows".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(NewClass.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }

    java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame frame = new JFrame();
            frame.setLayout(new BorderLayout());
            frame.add(new JScrollPane(createTable()), BorderLayout.CENTER);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(400, 500);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
}

public static JTable createTable() {
    DefaultTableModel tmodel = new DefaultTableModel(3, 5);
    JTable table = new JTable(tmodel);
    table.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_I, KeyEvent.CTRL_MASK), "Insert");
    //Not working for VK_INSERT or VK_DELETE or VK_SPACE
    table.getActionMap().put("Insert", new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Insert Action");
        }
    });
    return table;
}

}

更新1

使用 WHEN_IN_FOCUSED_WINDOW 时它不起作用,但如果我使用 WHEN_FOCUSEDWHEN_ANCESTOR_OF_FOCUSED_COMPONENT 则工作正常

最佳答案

  • 必填 WHEN_ANCESTOR_OF_FOCUSED_COMPONENT作为焦点的核心设置(隐藏在 JScrolPane s JViewport 后面)

JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT

The component contains (or is) the component that has the focus. This input map is commonly used for a composite component — a component whose implementation depends on child components. For example, JTables make all their bindings using WHEN_ANCESTOR_OF_FOCUSED_COMPONENT so that if the user is editing, the up-arrow key (for example) still changes the selected cell.

  • 然后全部KeyEvent OP 问题和评论的组合在 Win7/Win10、Java7/Java8 中可以正常工作,也来自 MadProgrammer 已删除的帖子 ( users_rep > 10k )

  • AFAIK 有限制,修饰符的数量,如果 > 2,则 CTRL + ALT + SHIFT + Whatever可以从 AWTEventListener 捕获或来自非常复杂的KeyListener

SSCCE/MCVE 形式的模拟代码

.

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.table.DefaultTableModel;

public class NewClass {

    public static void main(String args[]) {
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info
                    : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Windows".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException |
                IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(
                    NewClass.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(createTable()), BorderLayout.CENTER);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setSize(400, 500);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static JTable createTable() {
        DefaultTableModel tmodel = new DefaultTableModel(3, 5);
        JTable table = new JTable(tmodel);
        table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
                KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, KeyEvent.CTRL_MASK), "Insert");
        table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
                KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, KeyEvent.CTRL_MASK), "Insert");
        table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
                KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK), "Insert");
        table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
                KeyStroke.getKeyStroke(KeyEvent.VK_I, KeyEvent.CTRL_MASK), "Insert");
        table.getActionMap().put("Insert", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Action from JTable");
            }
        });
        return table;
    }
}

关于java - 键绑定(bind)不适用于某些键,例如插入、删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35549032/

相关文章:

java - Swing:DefaultBoundedRangeModel 是否合并多个事件?

java - 如何获取JTable中最后一个单元格的值?

java - 需要帮助创建数组

两个字符串之间的 Java 编译模式(动态)

java - 如何从 JSON 中提取图像的 url(LastFM API)

java - 选择 jlist 项目时添加图像

java - 如何制作一个包含多个组件的 JTable?

java - RxJava - 合并 2 个调用

java - 在 Java 中更改变量值的最传统方法是什么?

java - 停止 Swing 组件在发生 ChangeEvent 时重新定位到初始坐标?