2

背景:テーブルセルエディタがあり、呼び出されると、チェックボックスのリストと2つのボタン([OK]と[キャンセル])を含むダイアログがポップアップ表示されます。すべてうまくいきます。後でキーボードアクションを登録して、ENTERキーとESCAPEキーがok/cancelアクションを実行するようにしました。それでも問題ありません。

同じ手法を使用して、スペースキーを登録して3番目のアクションを実行しようとしました。これは発火しませんでした。サンプルコード:

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class DialogTest implements Runnable
{
  JDialog dialog;
  JList jlist;

  public static void main(String[] args)
  {
    SwingUtilities.invokeLater(new DialogTest());
  }

  public void run()
  {    
    ActionListener okListener = new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        close(true);
      }
    };

    ActionListener cancelListener = new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        close(false);
      }
    };

    ActionListener otherListener = new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        doOther();
      }
    };

    JButton okButton = new JButton("OK");
    okButton.addActionListener(okListener);

    JButton cancelButton = new JButton("Cancel");
    cancelButton.addActionListener(cancelListener);

    jlist = new JList(new String[]{"A", "B", "C", "D", "E", "F", "G"});
    jlist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    jlist.setVisibleRowCount(5);

    JScrollPane scroll = new JScrollPane(jlist);
    scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

    JPanel buttonsPanel = new JPanel(new FlowLayout());
    buttonsPanel.add(okButton);
    buttonsPanel.add(cancelButton);

    JPanel content = new JPanel(new BorderLayout());
    content.add(scroll, BorderLayout.CENTER);
    content.add(buttonsPanel, BorderLayout.SOUTH);

    dialog = new JDialog((Frame) null, true);
    dialog.setContentPane(content);
    dialog.pack();
    dialog.setLocationRelativeTo(null);

    dialog.getRootPane().registerKeyboardAction(okListener,
        KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
        JComponent.WHEN_IN_FOCUSED_WINDOW);

    dialog.getRootPane().registerKeyboardAction(cancelListener,
        KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
        JComponent.WHEN_IN_FOCUSED_WINDOW);

    // This doesn't work
    dialog.getRootPane().registerKeyboardAction(otherListener,
        KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0),
        JComponent.WHEN_IN_FOCUSED_WINDOW);

    dialog.setVisible(true);
  }

  private void close(boolean commit)
  {
    if (commit)
    {
      System.out.println("Now saving...");
    }
    else
    {
      System.out.println("Now closing...");
      System.exit(0);
    }
  }

  private void doOther()
  {
    System.out.println("current selection: " + jlist.getSelectedValue());
  }
}

編集

mKorbelの提案(そして便利なリンク!)のおかげで、私はこれを機能させることができました:

1)行ActionListener otherListener = new ActionListener(){...}を次のように変更します。

Action otherListener = new AbstractAction(){...}

2)SPACEキーストローク登録を次のように変更します。

KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0);
Object key = keyStroke.toString();
jlist.getInputMap().put(keyStroke, key);
jlist.getActionMap().put(key, otherAction);

登録はJList用であり、他の2つのキーストロークのようにJDialog用ではないことに注意してください。

4

1 に答える 1

2

あなたの威厳にどんな包丁も言うのは難しい…。

編集

SPACEが人間のJBu​​ttonアクセラレータ(マウス、ENTER、およびSPACE)としてKeyBindingsに登録されていることを忘れました。JButtonが選択されている場合、同時発生の可能性があります

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

public class DialogTest implements Runnable {

    private JDialog dialog;
    private JList jlist;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new DialogTest());
    }

    @Override
    public void run() {
        ActionListener okListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                close(true);
            }
        };

        ActionListener cancelListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                close(false);
            }
        };

        ActionListener otherListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                doOther();
            }
        };
        JButton okButton = new JButton("OK");
        okButton.addActionListener(okListener);
        JButton cancelButton = new JButton("Cancel");
        cancelButton.addActionListener(cancelListener);
        jlist = new JList(new String[]{"A", "B", "C", "D", "E", "F", "G"});
        jlist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        jlist.setVisibleRowCount(5);
        JScrollPane scroll = new JScrollPane(jlist);
        scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        JPanel buttonsPanel = new JPanel(new FlowLayout());
        buttonsPanel.add(okButton);
        buttonsPanel.add(cancelButton);
        JPanel content = new JPanel(new BorderLayout());
        content.add(scroll, BorderLayout.CENTER);
        content.add(buttonsPanel, BorderLayout.SOUTH);
        dialog = new JDialog((Frame) null, true);
        dialog.setContentPane(content);
        dialog.pack();
        dialog.setLocationRelativeTo(null);
        dialog.getRootPane().registerKeyboardAction(okListener,
                KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
                JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

        dialog.getRootPane().registerKeyboardAction(cancelListener,
                KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
                JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        // This doesn't work
        /*dialog.getRootPane().registerKeyboardAction(otherListener,
        KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0),
        JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);*/
        dialog.getRootPane().getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "doSomething");
        dialog.getRootPane().getActionMap().put("doSomething", new AbstractAction() {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        dialog.setVisible(true);
    }

    private void close(boolean commit) {
        if (commit) {
            System.out.println("Now saving...");
        } else {
            System.out.println("Now closing...");
            System.exit(0);
        }
    }

    private void doOther() {
        System.out.println("current selection: " + jlist.getSelectedValue());
    }
}
于 2012-11-29T16:50:35.517 に答える