Сочетание клавиш JFrame с помощью ActionMap?

1

Я пытаюсь создать ярлык для моего JFrame, используя ActionMap и InputMap. Но до сих пор не удается выполнить эту работу. Я создал ActionMap с AbstractAction, чтобы создать действие, и после того, как я создал 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"); 

    }
  • 0
    Что не работает? Вы получаете ошибку компилятора, исключение времени выполнения? Что происходит?
Теги:
netbeans
swing
jframe

2 ответа

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

Теперь все работает.

4

Выложенный код выглядит разумным, но мы не знаем контекста использования кода. Например, добавили ли вы какие-либо компоненты в область содержимого и у вас есть фокус. Когда вы отправляете сообщение о проблеме SSCCE, которое демонстрирует проблему, нам не нужно угадывать, что вы на самом деле делаете.

При обработке действия на уровне кадра я обычно добавляю привязку клавиш к 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.

  • 0
    Является ли SwingUtils классом в JavaSE 8 ? Поскольку вы написали SwingUtils.getDescendantsOfType(...) , похоже, вы используете один внешний класс !!!!
  • 1
    @nIcEcOw, упс, забыл включить ссылку на класс SwingUtils. Благодарю.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню