为什么一个Swing按键有效,而另一个无效?

时间:2019-03-24 18:20:07

标签: java swing keystroke

我正在编写一个带有JTable的Swing程序;我想使用control-V粘贴到JTable中,并使用control-S来保存JTable中的信息。

我首先使用JTable.registerKeyboardAction()向control-V键注册动作,并且可以使用,但是我注意到它的javadoc说它已经过时了,为此,新代码应使用输入映射和动作映射。目的。

我已经将它们用于control-S键,该键也已映射到JButton,因此我认为它很容易复制。这是我现在用于创建JFrame的代码片段:

  private JFrame createMainframe()
  {
    JFrame frame = new JFrame("VisaExtraction");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    String saveFileActionName = "Save";
    String pasteActionName = "Paste";

    Action saveFileAction = new SaveFileAction(saveFileActionName, frame, tableModel);
    Action pasteAction    = new PasteAction(pasteActionName, frame, tableModel);

//    JButton saveButton = new JButton(saveFileAction);
//    saveButton.setMnemonic(KeyEvent.VK_S);

    JPanel topPanel = new JPanel();
//    topPanel.add(saveButton);

    mainTable = new LastColumnChangesWidthJTable(tableModel);
    JScrollPane scrollPane = new JScrollPane(mainTable);

    // set ctrl-s to the 'saveFile' action
    //  and ctrl-v to the 'paste' action
    InputMap  tableInputMap  = mainTable.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);

    KeyStroke saveKeystroke  = KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK);
    tableInputMap.put(saveKeystroke, saveFileActionName);

    KeyStroke pasteKeystroke = KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK);
    tableInputMap.put(pasteKeystroke, pasteActionName);

    // set the saveFile and paste actions to be executed when invoked.
    ActionMap tableActionMap = mainTable.getActionMap();
    tableActionMap.put(saveFileActionName,  saveFileAction);
    tableActionMap.put(pasteActionName,     pasteAction);

    frame.add(topPanel,   BorderLayout.NORTH);
    frame.add(scrollPane, BorderLayout.CENTER);

    frame.pack();

    // register ctrl-v to paste into the JTable
//    mainTable.registerKeyboardAction
//    ( actionListener -> handlePaste(tableModel, new VisaExtractionListener(tableModel)),
//      KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK), 
//      JComponent.WHEN_IN_FOCUSED_WINDOW
//    );

    return frame;
  }

如您所见,我使用“ S”和“保存”执行的操作与使用“ V”和“粘贴”执行的操作相同,但是在启动程序后,“ control-S”起作用(就告诉我没有什么可保存的范围而言),而“ control-V”则没有(actionPerformed()方法中的断点未命中)。

什么可能导致这两者之间的差异?

1 个答案:

答案 0 :(得分:1)

您的问题可能是由于JTable已在另一个输入映射中使用ctrl-V操作。了解组件有3个输入映射,并且我相信<ion-tabs> <ion-tab-bar slot="bottom"> <ion-tab-button [routerLink]="nextChapterLink"> <ion-label>{{'Next Chapter' | translate}}</ion-label> <ion-icon name="checkbox-outline"></ion-icon> </ion-tab-button> </ion-tab-bar> </ion-tabs> 的那些优先于1.- Your table offices 2.- Your table employees 3.- Your table customers.

我的MCVE用于概念验证。在下面的代码中更改带注释的字段,以查看哪个有效:

JComponent.WHEN_FOCUSED

再次,由于您是寻求帮助的人,因此创建MCVE的工作应该由您来承担。

编辑:我错了。 WHEN_IN_FOCUSED_WINDOW地图就是已经在使用并且使您感到困惑的输入地图。在我的MCVE更新中,该键具有用于控制V键的非空键String:

import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class Foo {
    public static void main(String[] args) {
        Integer[][] rowData = {{1, 2}, {3, 4}};
        String[] columnNames = {"A", "B"};
        JTable table = new JTable(rowData, columnNames);
        JScrollPane scrollPane = new JScrollPane(table);

        // int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
        int condition = JComponent.WHEN_FOCUSED;
        InputMap inputMap = table.getInputMap(condition);
        ActionMap actionMap = table.getActionMap();

        KeyStroke saveKeystroke  = KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK);
        KeyStroke pasteKeystroke = KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK);

        inputMap.put(saveKeystroke, saveKeystroke.toString());
        inputMap.put(pasteKeystroke, pasteKeystroke.toString());

        actionMap.put(saveKeystroke.toString(), new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("save action");
            }
        });
        actionMap.put(pasteKeystroke.toString(), new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("paste action");
            }
        });

        JFrame frame = new JFrame("Foo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(scrollPane);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}