2014-06-20 1 views
-1

Enter 키를 입력 할 때처럼 Tab 키를 입력 할 때 강조 표시된 값을 받아들이려면 Java 콤보 박스를 어떻게 얻습니까? 저는 이것을 UI 표준으로 생각하고 웹 사이트와 데스크톱 프로그램에서 본 적이 있으므로 Java가 기본적으로 그렇게하지 않는 이유를 모르겠습니다. (이스케이프 키를 눌러 취소 할 수 있습니다.)Tab 키로 Swing JComboBox의 값을 받아들이는 방법

Tab과 같이 작동하도록 Enter를하는 방법을 포함하여 몇 가지 관련 질문이 있지만 다른 방법으로 이동하는 것이 더 힘들어서 그것을했다. 아마 나는 쉬운 길을 놓쳤다!

특히 초점 시스템에서 탭 키를 이미 사용했기 때문에 the closest posting I could find이 작동하지 않았습니다. 기타 관련 질문은 herehere이며, 힌트는 here 일 수 있습니다.

답변

1

Enter 키 처리 방법에 액세스 할 수 없기 때문에 까다로운 작업입니다. BasicComboBoxUI.actionPerformed()에있는 큰 if-else 트리에서 발생합니다. 이것은 액세스 할 수없는 팝업 메뉴에서 값을 콤보 상자로 가져 오는 곳입니다. 포커스 - 트래 버설 키 이벤트는 당신이 그들과 함께 무엇이든 할 수 있기 전에 소비되기 때문에 까다로운 일입니다.

이 작업을 수행하려면 포커스 이동 키 집합에서 Tab을 제거하고 JComboBox에서 processKeyEvent()을 재정의하고 을 미안 해요!은 UI가 정상적으로 Enter 키를 수행하도록하기 위해 가짜 Enter-key 이벤트를 수퍼 클래스에 전달합니다. 그런 다음 수동으로 초점 전환을 처리해야했습니다.

여기에 몇 가지 코드가 있습니다. (I는 시프트 탭/뒤로 순회에게 아마 잔인한 사람이었다 같은 방식으로, 집중 처리.)

protected final JComboBox combobox = new JComboBox() { 
    @Override 
    public void processKeyEvent(KeyEvent e) {   
     if (e.getID() != KeyEvent.KEY_PRESSED 
       || e.getKeyCode() != KeyEvent.VK_TAB) { 
      super.processKeyEvent(e); 
      return; 
     } 

     if (isPopupVisible()) { 
      assert e.getSource() instanceof Component; 
      KeyEvent fakeEnterKeyEvent = new KeyEvent((Component) e.getSource(), 
        e.getID(), 
        e.getWhen(), 
        0,     // No modifiers. 
        KeyEvent.VK_ENTER, // Enter key. 
        KeyEvent.CHAR_UNDEFINED); 
      super.processKeyEvent(fakeEnterKeyEvent); 
     } 
     if (e.getModifiers() == 0) { 
      transferFocus(); 
     } else if (e.getModifiers() == KeyEvent.SHIFT_MASK) { 
      transferFocusBackward(); 
     } 
    } 
}; 

// Remove tabs from focus traversal keylists. 
// Forward. 
Set<AWTKeyStroke> focuskeys = Sets.newHashSet(combobox.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS)); 
KeyStroke lTabKeystroke = KeyStroke.getKeyStroke("pressed TAB"); 
focuskeys.remove(lTabKeystroke); 
combobox.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, focuskeys); 
// Backward. 
focuskeys = Sets.newHashSet(combobox.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS)); 
KeyStroke lShiftTabKeystroke = KeyStroke.getKeyStroke("shift pressed TAB"); 
focuskeys.remove(lShiftTabKeystroke); 
combobox.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, focuskeys); 
1

스윙 다른 키 스트로크 (keystroke)에 대한 작업을 호출하는 키 바인딩을 사용합니다. JComboBox에는 ENTER 키에 대한 액션이 있습니다. 모든 바인딩 목록을 Key Bindings에서 확인하십시오.

그래서 나는 다른 키 스트로크에 Enter 액션을 바인딩하는 간단한 케이스라고 생각했다.

물론 Enter 키 동작을 RIGHT 화살표 키에 바인딩 할 때 기능이 예상대로 작동했습니다.

그러나 입력 동작을 TAB 키에 바인딩하면 작동하지 않습니다. 그러나 팝업 메뉴는 여전히 닫혀 있습니다. 그래서 지금 Tab 키가 새로운 TAB 키 바인딩이 작동하지 못하게하는 메뉴를 닫기 위해 다른 구성 요소에 의해 처리되는지 궁금합니다. 어쩌면 다른 사람이 이것에 대해 통찰력을 가지고 있을까요?

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

public class ComboBoxTest2 extends JFrame 
{ 
    JComboBox comboBox; 
    JTextField textField; 
    String[] tabs; 
    public ComboBoxTest2() 
    { 
     String[] tabs = { "a", "b", "c", "d", "e", "f", "g" }; 

     DefaultComboBoxModel model = new DefaultComboBoxModel(tabs); 
     comboBox = new JComboBox(model); 
     add(comboBox, BorderLayout.NORTH); 
     add(new JButton("A Component To Tab To"), BorderLayout.SOUTH); 

     // This works 

     InputMap im = comboBox.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 
     KeyStroke existingKeyStroke = KeyStroke.getKeyStroke("ENTER"); 
     KeyStroke rightKS = KeyStroke.getKeyStroke("RIGHT"); 
     im.put(rightKS, im.get(existingKeyStroke)); 

     // This doesn't work 

     comboBox.setFocusTraversalKeysEnabled(false); 
     KeyStroke tabKS = KeyStroke.getKeyStroke("TAB"); 
     im.put(tabKS, im.get(existingKeyStroke)); 
    } 
    public static void main(String[] args) 
    { 
     JFrame frame = new ComboBoxTest2(); 
     frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
+0

안녕하십니까. 후속 조치에 감사드립니다. 내가 언급하지 않은 한 가지 : 나는 당신의 솔루션을 시도했을 때 실제로 im.get (ENTER)에 대해 null을 얻었습니다. WHEN_FOCUSED를 사용하여 WHEN_ANCESTOR_OF가 아닌 입력 된 맵을 얻습니다. WHEN_ANCESTOR 지금 시도하고 null이 아닌 바인딩을 볼 않았다. 여기서보고 한 것처럼 TAB에 대해 동일한 바인딩을 설정해도 작동하지 않습니다. (한 가지 더 메모 : 팝업이 표시되지 않는 경우 Tab과 Enter는 다르게 동작해야한다고 생각합니다.이 경우 탭만이 다음 구성 요소로 포커스를 이동해야합니다.) –

관련 문제