FernandoPaiva
FernandoPaiva

Reputation: 4460

JFrame keyboard shortcut using ActionMap?

I`m trying create shortcut for my JFrame using ActionMap and InputMap. But still can't do this work. I created the ActionMap with AbstractAction to create the action and after I created the InputMap to register the event, but doesn't work

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"); 

    }

Upvotes: 1

Views: 2180

Answers (2)

FernandoPaiva
FernandoPaiva

Reputation: 4460

I solved the problem. I did this: I added a JPanel principal, and inside this JPanel I added others JPanel and the actions I did using JPanel principal.

Here how I did.

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");
    }

Now everything works.

Upvotes: 2

camickr
camickr

Reputation: 324108

The posted code looks reasonable but we don't know the context of how the code is used. For example, did you add any components to the content pane and do they have focus. When posting a question post a SSCCE that demonstrates the problem to we don't have to guess what you are really doing.

When handling an Action at the frame level I usually add the key binding to the JRootPane of the frame. Here is a SSCCE that demonstrates this approach:

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());
    }
}

Edit:

This example will also need the Swing Utils class.

Upvotes: 5

Related Questions