背景:テーブルセルエディタがあり、呼び出されると、チェックボックスのリストと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用ではないことに注意してください。