2012-05-22 1 views
3

Я пытаюсь получить простой JFrame с помощью одной кнопки, чтобы стрелять событие, когда любое из этих событий произойдет:Огонь JButton с пробела или клавишу ввода, или мыши

  • ввода ключа является нажата И JButton имеет фокус
  • Пробел нажимается И у JButton есть фокус
  • Нажата кнопка JButton.

Кажется, что Enter и пробел приходят «бесплатно» вместе с щелчком мыши по умолчанию с помощью addActionListener на JButton; проблема в том, что я читал, что привязки клавиш зависят от используемого Look и Feel.

Я попытался получить универсальное поведение через LaF, добавив Enter и пробел в карту действий JButton и даже добавил случайный ключ («m»), чтобы убедиться, что ActionMap выполняет работу (это было), но теперь щелчок мыши потерян. Единственный способ, с помощью которого я могу получить все ключи и щелчок мыши, - это использовать как карту действий, так и addActionListener.

Есть ли способ заставить эти привязки клавиш и мышей последовательно работать во всех LaF, не пытаясь обнаружить все возможные LaF, которые могут появиться? Могу ли я зарегистрировать один прослушиватель действий, который будет срабатывать как для событий, так и для мыши?

Моим любимым решением было бы добавить щелчок мышью на карту действий JButton и определить, какой ключ или щелчок мыши произошли внутри действия.

Я все еще изучаю веревки здесь, поэтому это, вероятно, не лучший или самый эффективный способ сделать что-то; Я уверен, что он слишком переработан. Это своего рода тренировка, в которой я экспериментирую со всем, что могу получить. Любые комментарии кодовых комментариев приветствуются!

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

import javax.swing.AbstractAction; 
import javax.swing.Action; 
import javax.swing.InputMap; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.KeyStroke; 
import javax.swing.UIManager; 

public class Example extends JFrame { 

// ============================ 
private class BtnListener extends AbstractAction { 
    private static final long serialVersionUID = 1L; 

    public void actionPerformed(ActionEvent ae) { 
     System.out.println("\nclick button listener triggered"); 
     System.out.println(ae.getSource().getClass().toString()); 
    } 
} // class BtnListener 

private static final int NO_MODIFIER = 0; 
private static final boolean ON_KEY_PRESS = false; 
private static final KeyStroke ENTER_PRESSED = KeyStroke.getKeyStroke(
     KeyEvent.VK_ENTER, NO_MODIFIER, ON_KEY_PRESS); 
private static final KeyStroke M_PRESSED = KeyStroke.getKeyStroke(
     KeyEvent.VK_M, NO_MODIFIER, ON_KEY_PRESS); 
private static final KeyStroke SPACEBAR_PRESSED = KeyStroke.getKeyStroke(
     KeyEvent.VK_SPACE, NO_MODIFIER, ON_KEY_PRESS); 
private JButton btnButton; 
private final AbstractAction btnListener = new BtnListener(); 
private JPanel buttonPanel; 
private JFrame frmMain; 

public static void main(String[] args) { 
    Example ex = new Example(); 
    ex.displayFrame(); 
} 

Action btnActionListener = new AbstractAction() { 
    private static final long serialVersionUID = 1L; 

    public void actionPerformed(ActionEvent e) { 
     System.out.println("\nkey button action triggerred"); 
     System.out.println(e.getSource().getClass().toString()); 
     if (e.getSource() instanceof JButton) { 
      System.out.println("button"); 
     } else { 
      System.out.println("Something else"); 
     } 
    } 
}; 

public Example() { 
    initialize(); 
} 

public void displayFrame() { 
    try { 
     UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
    } catch (Throwable e) { 
     e.printStackTrace(); 
    } 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      try { 
       frmMain.setVisible(true); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 

private void initialize() { 

    frmMain = new JFrame(); 
    btnButton = new JButton("Abutton"); 

    // Comment this out, you lose the mouse click 
    btnButton.addActionListener(btnListener); 

    // Comment out ActionMaps, but keep addActionListner (above), and 
      // only lose M_PRESSED 
    InputMap buttonFocusedMap = btnButton 
      .getInputMap(JComponent.WHEN_FOCUSED); 

    buttonFocusedMap.put(ENTER_PRESSED, "blah"); 
    btnButton.getActionMap().put("blah", btnActionListener); 

    buttonFocusedMap.put(SPACEBAR_PRESSED, "blort"); 
    btnButton.getActionMap().put("blort", btnActionListener); 

    buttonFocusedMap.put(M_PRESSED, "gaaak"); 
    btnButton.getActionMap().put("gaaak", btnActionListener); 

    // Is there a way to add a mouse click to the ActionMap? 

    buttonPanel = new JPanel(); 
    buttonPanel.add(btnButton); 

    frmMain.getContentPane().add(buttonPanel); 
    frmMain.setBounds(100, 100, 500, 432); 
    frmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
} 

} 

ответ

9

BasicButtonListener, используемый BasicButtonUI, гарантирует, что все кнопки (проверить, радио, переключение) связаны до Пространство при фокусировке. Это работает на разных платформах, хотя индивидуальный Look & Feels может отображать различные состояния модели кнопок однозначно. Нажатие Space пробуждает нажимаетсяUIAction и отпуская Space вызывает выпущенноеUIAction. То же самое происходит, когда мышь нажата и выпущена в пределах границы кнопки; перетащите за пределы кнопки при нажатии, чтобы увидеть изменение состояния вооружения.

В любом случае, сочетание нажимается и выпустила вызывает actionPerformed() метод вашей кнопки.

Один удобный способ связать Введите к Action, независимо от направленности, осуществляется через setDefaultButton() метод базовой панели. Это example иллюстрирует все три способа щелчка по кнопке.

+1

Отлично! Спасибо за глубокое объяснение. –

0

Что вы можете (и, вероятно, должно) сделать, это создать AbstractAction. Вы можете использовать AbstractAction как для вашего ActionMap, а также для нажатия (у JButton.setAction (...))

Смежные вопросы