2017-10-24 26 views
0

패널 중 하나에서 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

감사합니다! 그 생각,하지만 소비() ActionEvent에 사용할 수 없습니다. – lspare

+0

어때요? ActionEvent는 consume() 메서드의 출처 인 AWTEvent을 상속받습니다. 예 : https://docs.oracle.com/javase/8/docs/api/java/awt/event/ActionEvent.html (죄송합니다. 링크가 잘못되었습니다.) –

+0

소모품을 사용할 수없는 경우 사용자가 입력 할 때 숫자 1 또는 2의 추가를 취소하려면 노드에 KeystrokeListener를 추가하십시오. –