使用ActionMap的JFrame键盘快捷键?

时间:2014-07-13 16:35:19

标签: java swing netbeans jframe

我正在尝试使用ActionMap和InputMap为我的JFrame创建快捷方式。但仍然无法完成这项工作。 我用AbstractAction创建了ActionMap来创建动作,在我创建了InputMap以注册事件之后,但是没有工作

private void acoesTela(){         
        JPanel painel = (JPanel)this.getContentPane();
        ActionMap actionMap = painel.getActionMap();    
        actionMap.put("consultaProdutos", new AbstractAction() {  
            @Override  
            public void actionPerformed(ActionEvent evt) {  
                System.out.println("F3 is pressed");
            }              
        });  

        /** registra acoes */
        InputMap imap = painel.getInputMap(JPanel.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);  
        imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0), "consultaProdutos"); 

    }

2 个答案:

答案 0 :(得分:4)

发布的代码看起来很合理,但我们不知道代码的使用方式。例如,您是否将任何组件添加到内容窗格并且它们是否具有焦点。在发布问题SSCCE时发布问题时,我们不必猜测您的确在做什么。

在帧级处理Action时,我通常会将键绑定添加到帧的JRootPane。这是展示此方法的SSCCE

import java.awt.*;
import java.awt.event.*;
import java.util.List;
import javax.swing.*;
import javax.swing.event.*;

/**
**  This class will close a JDialog (or a window) when the Escape key is used.
**  However, first it must check to see if a popup component is visible in
**  which case the Escape key will close the popup normally, then you must use
**  the Escape key a second time to close the dialog.
*/
public class EscapeAction extends AbstractAction
{
    public void actionPerformed(ActionEvent e)
    {
        boolean visiblePopup = false;
        Component c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();

        //  Check if light weight popup is being used

        List<JPopupMenu> popups = SwingUtils.getDescendantsOfType(JPopupMenu.class, (Container)c, true);

        for (JPopupMenu p: popups)
        {
            p.setVisible( false );
            visiblePopup = true;
        }

        //  Check if a heavy weight popup is being used

        Window window = SwingUtilities.windowForComponent(c);

        for (Window ownedWindow: window.getOwnedWindows())
        {
            if (ownedWindow.isVisible())
            {
                Component rootPane = ownedWindow.getComponent(0);
                List<JPopupMenu> ownedPopups =
                    SwingUtils.getDescendantsOfType(JPopupMenu.class, (Container)rootPane, true);

                for (JPopupMenu ownedPopup: ownedPopups)
                {
                    ownedPopup.setVisible( false );
                    visiblePopup = true;
                    ownedWindow.dispose();
                }
            }
        }

        //  No popups so close the Window

        if (! visiblePopup)
            //SwingUtilities.windowForComponent(c).setVisible(false);
            SwingUtilities.windowForComponent(c).dispose();
    }

    public static void main(String[] args)
    {
        String laf = null;
        laf = "javax.swing.plaf.metal.MetalLookAndFeel";
//      laf = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
//      laf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";

        try { UIManager.setLookAndFeel(laf); }
        catch (Exception e2) { System.out.println(e2); }

        JDialog dialog = new DialogEscape();

        JPopupMenu popup = new JPopupMenu();
        popup.add( new JMenuItem("SubMenuA") );
        popup.add( new JMenuItem("SubMenuB") );
        popup.add( new JMenuItem("SubMenuC") );
        popup.add( new JMenuItem("SubMenuD") );

        String[] items = { "Select Item", "Color", "Shape", "Fruit" };
        JComboBox<String> comboBox = new JComboBox<String>( items );
        dialog.add(comboBox, BorderLayout.NORTH);

        JTextField textField = new JTextField("Right Click For Popup");
        textField.setComponentPopupMenu(popup);
        dialog.add(textField);

        dialog.setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE );
        dialog.setSize(200, 200);
        dialog.setLocationRelativeTo(null);
        dialog.setVisible( true );

        //  Add the Key Bindings to the JRootPane for the EscapeAction

        JRootPane rootPane = dialog.getRootPane();
        String escapeText = "ESCAPE";
        KeyStroke escapeKeyStroke = KeyStroke.getKeyStroke(escapeText);
        rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escapeKeyStroke, escapeText);
        rootPane.getActionMap().put(escapeText, new EscapeAction());
    }
}

编辑:

此示例还需要Swing Utils类。

答案 1 :(得分:2)

我解决了这个问题。 我这样做了:我添加了一个JPanel主体,在这个JPanel中我添加了其他JPanel和我使用JPanel主体执行的操作。

这是我的表现。

private void acoesTela(){
        ActionMap am = panelPrincipal.getActionMap();
        am.put("vaiQtd", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                txtFieldQtd.requestFocus();
                txtFieldQtd.selectAll();
            }
        });

        am.put("vaiCodigo", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                txtFieldCod.requestFocus();
                txtFieldCod.selectAll();
            }
        });

        InputMap im = panelPrincipal.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_F4, 0), "vaiQtd");
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0), "vaiCodigo");
    }

现在一切正常。