Как изменить целевую привязку по умолчанию для JButton для ActionListener? - PullRequest
0 голосов
/ 10 января 2019

Ключ по умолчанию для вызова целевого ActionListener JButton - это пробел, но как мне поменять его на другой ключ?

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Вам необходимо:

  1. Обновите InputMap компонента, добавив новый KeyStroke, чтобы он указывал на существующий Action.

  2. Не позволяет существующему KeyStroke в InputMap вызывать существующее Action. Этот шаг не является обязательным, если вы хотите использовать обе комбинации клавиш для вызова действия по умолчанию.

Примечание:

  1. вам нужно обновить InputMap для «нажатых» и «отпущенных» клавиш
  2. Обновления InputMap должны выполняться в указанном выше порядке.

Модифицируя код из примера Hovercrafts, вы можете сделать:

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class AlterSpaceBinding extends JPanel {
    private JButton myButton = new JButton("My Button -- associate with \"B\" key");

    public AlterSpaceBinding() {
        myButton = alterDefaultButtonAction(myButton, KeyEvent.VK_B);
        myButton.addActionListener(l -> {
            System.out.println("button pressed");
        });
        add(myButton);
        add(new JButton("Second Button -- no change"));

    }

    public static JButton alterDefaultButtonAction(JButton button, int desiredKeyCode) {

        // get the correct InputMap
        InputMap inputMap = button.getInputMap(JComponent.WHEN_FOCUSED);

        // get both key strokes for space key, but pressed and released
        KeyStroke spaceKeyPressed = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false);
        KeyStroke spaceKeyReleased = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true);

        // key stroke for desired key code
        KeyStroke desiredKeyPressed = KeyStroke.getKeyStroke(desiredKeyCode, 0, false);
        KeyStroke desiredKeyReleased = KeyStroke.getKeyStroke(desiredKeyCode, 0, true);

        // share the Action with desired KeyStroke
        inputMap.put(desiredKeyPressed, inputMap.get(spaceKeyPressed));
        inputMap.put(desiredKeyReleased, inputMap.get(spaceKeyReleased));

        // disable original KeyStrokes (optional)
        inputMap.put(spaceKeyPressed, "none");
        inputMap.put(spaceKeyReleased, "none");

        return button;
    }

    private static void createAndShowGui() {
        AlterSpaceBinding mainPanel = new AlterSpaceBinding();

        JFrame frame = new JFrame("AlterSpaceBinding");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

Приведенному выше коду не нужно:

  1. создать пустышку Action.
  2. манипулировать ActionMap.

Проверьте Использование привязок клавиш для получения дополнительных примеров манипулирования InputMap и ActionMap компонента.

Примечание:

Более вероятный сценарий - вы хотите обновить привязки для всех кнопок в приложении, чтобы у вас был общий LAF. В этом случае вы можете обновить «focusInputMap» из UIManager, который используется всеми JButton:

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

public class SSCCE extends JPanel
{
    SSCCE()
    {
        add( new JButton("Button 1" ) );
        add( new JButton("Button 2" ) );
        add( new JButton("Button 3" ) );
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SSCCE());
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );

        // Update shared InputMap

        InputMap inputMap = (InputMap)UIManager.get("Button.focusInputMap");
        int desiredKeyCode = KeyEvent.VK_B; // type "b" to invoke Action on button

        KeyStroke spaceKeyPressed = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false);
        KeyStroke spaceKeyReleased = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true);

        // key stroke for desired key code
        KeyStroke desiredKeyPressed = KeyStroke.getKeyStroke(desiredKeyCode, 0, false);
        KeyStroke desiredKeyReleased = KeyStroke.getKeyStroke(desiredKeyCode, 0, true);

        // share the Action with desired KeyStroke
        inputMap.put(desiredKeyPressed, inputMap.get(spaceKeyPressed));
        inputMap.put(desiredKeyReleased, inputMap.get(spaceKeyReleased));

        // optionally disable original KeyStrokes
        inputMap.put(spaceKeyPressed, "none");
        inputMap.put(spaceKeyReleased, "none");
    }

    public static void main(String[] args) throws Exception
    {
        java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
/*
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
*/
    }
}
0 голосов
/ 10 января 2019

Это не совсем просто и требует:

  • Использование правильной карты ввода для JButton, связанной с условием JComponent.WHEN_FOCUSED
  • Затем вам нужно получить и удалить InputMap и ActionMap для кнопки, связанной с клавишей пробела, для * и нажатие клавиши и отпущенная клавиша .
  • Затем свяжите оба действия с интересующей вас клавишей, снова обе клавиши нажаты и отпущены.

пример:

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

import javax.swing.*;

@SuppressWarnings("serial")
public class AlterSpaceBinding extends JPanel {
    private JButton myButton = new JButton("My Button -- associate with \"B\" key");

    public AlterSpaceBinding() {
        myButton = alterDefaultButtonAction(myButton, KeyEvent.VK_B);
        myButton.addActionListener(l -> {
            System.out.println("button pressed");
        });
        add(myButton);
        add(new JButton("Second Button -- no change"));

    }

    public static JButton alterDefaultButtonAction(JButton button, int desiredKeyCode) {

        // get the correct InputMap
        int condition = JComponent.WHEN_FOCUSED;
        InputMap inputMap = button.getInputMap(condition);
        ActionMap actionMap = button.getActionMap();

        // empty action that does nothing
        Action emptyAction = new AbstractAction() {            
            @Override
            public void actionPerformed(ActionEvent e) {
                // This does NOTHING
            }
        };

        // get both key strokes for space key, but pressed and released
        KeyStroke spaceKeyPressed = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false);
        KeyStroke spaceKeyReleased = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true);

        // get input map key for pressed and released
        String keyForSpacePressed = (String) inputMap.get(spaceKeyPressed);
        String keyForSpaceReleased = (String) inputMap.get(spaceKeyReleased);

        // get actions for press and release
        Action actionForSpacePressed = actionMap.get(keyForSpacePressed);        
        Action actionForSpaceReleased = actionMap.get(keyForSpaceReleased);

        // substitute empty action
        actionMap.put(keyForSpacePressed, emptyAction);
        actionMap.put(keyForSpaceReleased, emptyAction);

        // key stroke for desired key code
        KeyStroke desiredKeyPressed = KeyStroke.getKeyStroke(desiredKeyCode, 0, false);
        KeyStroke desiredKeyReleased = KeyStroke.getKeyStroke(desiredKeyCode, 0, true);

        // put in the original actions to where wanted
        inputMap.put(desiredKeyPressed, desiredKeyPressed.toString());
        actionMap.put(desiredKeyPressed.toString(), actionForSpacePressed);
        inputMap.put(desiredKeyReleased, desiredKeyReleased.toString());
        actionMap.put(desiredKeyReleased.toString(), actionForSpaceReleased);

        return button;
    }

    private static void createAndShowGui() {
        AlterSpaceBinding mainPanel = new AlterSpaceBinding();

        JFrame frame = new JFrame("AlterSpaceBinding");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...