2017-10-24 10 views
0

ペインの1つにJTreeを持つ分割ペインを使用して、JFrameにホットキーを実装しようとしています。キーバインドは、ユーザーがJTreeノードの名前を編集しているときにキーバインディングを持つキーを押すと、キー入力がテキスト領域およびに入力され、キーバインディングがトリガーされる点を除いて、機能します。どのようにホットキーを実装しながら、ノードの編集を許可するための任意のアイデア?キーバインディングをトリガーするTextAreaでのタイピングを防ぐには?

以下は動作を示す例です。 "1"と "2"のキーがバインドされているので、いずれかをテキストエリアに入力するとポップアップが表示されます。

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import javax.swing.AbstractAction; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.JToolBar; 
import javax.swing.KeyStroke; 
import javax.swing.SwingUtilities; 

public class KeyBindingTest { 
    static JButton button1; 
    static JButton button2; 
    static JPanel panel; 

    public KeyBindingTest() { 
     panel = new JPanel(new BorderLayout()); 
     JToolBar tb = new JToolBar(); 
     tb.setFloatable(false); 

     button1 = new JButton("First Button"); 
     button1.addActionListener(new ButtonAction()); 
     button2 = new JButton("Second Button"); 
     button2.addActionListener(new ButtonAction()); 
     tb.add(button1); 
     tb.add(button2); 

     panel.add(tb, BorderLayout.PAGE_START); 

     JTextArea ta = new JTextArea(10, 30); 
     JScrollPane opts = new JScrollPane(ta); 
     panel.add(opts, BorderLayout.PAGE_END); 

     setKeyBindings(tb); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       KeyBindingTest test = new KeyBindingTest(); 
       test.createAndShowUI(); 
      } 
     }); 
    } 

    private void setKeyBindings(JToolBar tb) { 
     tb.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "first"); 
     tb.getActionMap().put("first", new ButtonAction()); 
     tb.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_2, 0), "second"); 
     tb.getActionMap().put("second", new ButtonAction()); 
    } 

    private void createAndShowUI() { 
     JFrame frame = new JFrame(); 
     frame.getRootPane().setDefaultButton(button1); 
     frame.setLayout(new BorderLayout()); 
     frame.add(panel, BorderLayout.CENTER); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    } 

    public class ButtonAction extends AbstractAction { 
     private static final long serialVersionUID = 1L; 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      JOptionPane.showMessageDialog(panel, "You pressed a button \n" + e.paramString()); 
     } 
    } 
} 

答えて

3

これは、一般的にホットキーを持っている理由ですAltまたはControlモディファイア。

あなたは、コンポーネントがフォーカスしているかを判断するためにアクションを変更することができます。

@Override 
public void actionPerformed(ActionEvent e) 
{ 
    KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); 
    Component focusedComponent = kfm.getFocusOwner(); 

    if (focusedComponent instanceof JTextArea) 
     return; 

    JOptionPane.showMessageDialog(panel, "You pressed a button \n"+e.paramString()); 
} 
+0

ありがとう。その答えは主に「あなたがやっているようにしないでください」と私は受け入れることができます。 :) – lspare

0

は、私がスイングを行ってきたので、しばらくしているが、私はあなたが他のリスナーに渡されることを防ぐためのActionEventに()を消費呼び出すことができると思います。つまり、キーストロークが他のリスナーに当たる前に消費を呼び出すと、数字がフィールドに表示されないようにすることができます。明確にするために

:(。私が言ったように、それはしばらくしている)

public class ButtonAction extends AbstractAction 
{ 
    private static final long serialVersionUID = 1L; 

    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     JOptionPane.showMessageDialog(panel, "You pressed a button \n"+e.paramString()); 
     e.consume(); 
    } 
} 

あなたはかかわらず、リスナーの順序を説明するために必要がある場合があります

+0

ありがとうございました!私はそれを考えましたが、Consume()はActionEventでは利用できません。 – lspare

+0

どうですか? ActionEventは、consume()メソッドの元となるAWTEventを継承します。例えば、 https://docs.oracle.com/javase/8/docs/api/java/awt/event/ActionEvent.html (申し訳ありませんがリンクが間違っています。) –

+0

消費が利用できない場合は、ユーザーが入力するときに番号1または2の追加を取り消すには、ノードにKeystrokeListenerを追加します。 –

関連する問題