需要class方便快捷键绑定

Need class to facilitate key binding

在 SO 和@kleopatra 的帮助下,我得到了下面的代码,可以将 Ctrl-Shift-U 分配给 JButton。 (我在不应该清楚地告诉我什么必须匹配的地方使用了 CAPS。)

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import static java.awt.event.InputEvent.CTRL_DOWN_MASK;
import static java.awt.event.InputEvent.SHIFT_DOWN_MASK;
import static java.awt.event.KeyEvent.VK_U;
import javax.swing.*;
import static javax.swing.KeyStroke.getKeyStroke;

public class FirstTry {
  private static JButton MYACTIONBUTTON;
  private static JFrame frame;
  private static JPanel panel;

  public FirstTry(){
    Action MYACTION = new AbstractAction(){
      @Override
      public void actionPerformed(ActionEvent e){
          JOptionPane.showMessageDialog(null,"do this");
      }};

    MYACTIONBUTTON = new JButton(MYACTION);
    MYACTIONBUTTON.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
                          .put(getKeyStroke(VK_U, CTRL_DOWN_MASK | SHIFT_DOWN_MASK),
                                      "MAKE_THESE_MATCH"); 
    MYACTIONBUTTON.getActionMap().put("MAKE_THESE_MATCH", MYACTION);

    frame = new JFrame();
    panel = new JPanel();
    panel.add(MYACTIONBUTTON);
    frame.add(panel);
    frame.setVisible(true);
    frame.pack();
}

public static void main(String[] args) {
  new FirstTry();
}

下次我想做一个类似的键绑定时要经历很多事情,所以我认为应该可以推断逻辑以形成一个 abstract class 可以轻松地启用分配键击(例如, Ctrl-X) 通过如下语句执行操作(例如 "Ctrl-X was pressed",如图所示):

button = new KeyBoundButton("WHATEVER", VK_X, CTRL_DOWN_MASK) 
{
  @Override
  public void actionPerformed(ActionEvent e)
  {
    JOptionPane.showMessageDialog(null,"Ctrl-X was pressed!");
  }
};

我为此工作了整(半)天,但一无所获。我有 3 个 classes:main、UI 和 KeyBoundButton。我承认我在我的头上。

public class NewMain {

  static UI ui;

  public static void main(String[] args) 
  {
    java.awt.EventQueue.invokeLater(new Runnable() 
    {
      @Override
      public void run() 
      {
        ui = new UI();
      }
    }); 
  }
}

UI:

import java.awt.event.ActionEvent;
import static java.awt.event.InputEvent.CTRL_DOWN_MASK;
import static java.awt.event.KeyEvent.VK_X;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;

public class UI {

  static JFrame frame;
  static JPanel panel;
  static KeyBoundButton button;

  UI(){
    frame = new JFrame();
    panel = new JPanel();

    button = new KeyBoundButton("WHATEVER", VK_X, CTRL_DOWN_MASK) 
    {
      @Override
      public void actionPerformed(ActionEvent e)
      {
        JOptionPane.showMessageDialog(null,"Ctrl-X was pressed!");
      }
    };

    panel.add(button);
    frame.add(panel);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    frame.pack();
  }
}

KeyBoundButton:

import java.awt.event.ActionEvent;
import javax.swing.*;
import static javax.swing.KeyStroke.getKeyStroke;

public abstract class KeyBoundButton extends JButton{

  public abstract void actionPerformed(ActionEvent e);

  public KeyBoundButton(String actionMapKey, int key, int mask)
  {
    Action myAction = new AbstractAction()
    {
      @Override
      public void actionPerformed(ActionEvent e)
      { // to be overridden   
      }
    };    

     new JButton(myAction);

    getInputMap(WHEN_IN_FOCUSED_WINDOW)
                  .put(getKeyStroke(key, mask),actionMapKey);
    getActionMap().put(                        actionMapKey, myAction);
  }
}

我是否完全接近于使这个 class 启用如上(和下)所示的简单键绑定?还是只是一厢情愿,对键绑定等知识不够了解?

button = new KeyBoundButton("WHATEVER", VK_X, CTRL_DOWN_MASK) 
{
  @Override
  public void actionPerformed(ActionEvent e)
  {
    JOptionPane.showMessageDialog(null,"Ctrl-X was pressed!");
  }
};

您的 KeyBoundButton 不需要 new JButton(myAction);,而是使用 setAction(myAction)

第二个按钮的创建与任何事情都没有关系,实际上,在您调用new JButton(myAction)之后,该对象立即符合垃圾回收条件

我不久前写了一个实用程序 class,它做类似的事情,但这意味着我不需要为我想使用的每个人创建 "custom" classes,所以我可以简单地传递一个 Component、名称、KeyStrokeAction(以及可选的焦点级别),这让生活变得更加简单

@MadProgrammer 让我开始了;这是有效的方法。对原始代码的更改用 /////////////// 标记。 (我不确定为什么原始行 public abstract void actionPerformed(ActionEvent e) 不起作用....看起来不错。[?])

import java.awt.event.ActionEvent;
import javax.swing.*;
import static javax.swing.KeyStroke.getKeyStroke;

public abstract class KeyBoundButton extends JButton{

  public abstract void doThis(ActionEvent e); //////////////////////

  public KeyBoundButton(String actionMapKey, int key, int mask)
  {
    Action myAction = new AbstractAction()
    {

      @Override
      public void actionPerformed(ActionEvent e)
      {
        doThis(e); ///////////////////////////
      }
    };    

    setAction(myAction); //////////////////////////////

    getInputMap(WHEN_IN_FOCUSED_WINDOW)
                  .put(getKeyStroke(key, mask),actionMapKey);
    getActionMap().put(                        actionMapKey, myAction);
  }
}

我的初衷是(正如 Mad 也暗示的那样)在合理的范围内对任何组件进行这项工作;现在开始。我可能会回来寻求更多帮助。