2016-04-01 1 views
0

私はいくつかのテキストフィールドと編集可能なJComboBoxを持つパネルを持っています。 Enterキーを押すと、下の検索ボタンを押すように、これらのすべてが機能するようにします。これはActionListenerJTextFieldで問題なく動作します。ただし、入力したときに検索を開始し、ドロップダウンリストが表示されないようにするには、JComboBoxに検索を開始する必要があります。私。ユーザーがドロップダウン内のオプションを選択するためにEnterキーを押した場合、何も起こらないはずです。編集可能なJComboBox:ドロップダウン選択でそれを無視している間にEnterを押すかどうかを決定しますか?

この動作の達成方法を教えてください。

イベントが発生すると、getActionCommand()をチェックして、"comboBoxEdited"または"comboBoxChanged"のいずれかを表示しました。 "comboBoxEdited"は、オプションを選択した後Enterを押すと、編集可能なフィールドでEnterキーを押したときに起動されます。 "comboBoxChanged"は、オプション間を移動するときに起動され、"comboBoxEdited"の直前だけでなく、テキストの編集後に入力を押すと起動されます。

私は以前のActionCommandを保存した醜いハックを試みましたが、手動でテキストを入力した後に2回押す必要があるため、完璧ではありません。

public void actionPerformed(ActionEvent e) { 
    if (e.getActionCommand().equals("comboBoxEdited") && 
     !combohack.equals("comboBoxChanged")) { 

     combohack=""; 
     //PERFORM SEARCH! 
    } 
    combohack=e.getActionCommand(); 
} 

は、私は、さらに、実際の手紙どこが押されたときに、文字列をリセットするためにもKeyListenerを追加することによっても、醜い私のハックを作ってみましたが、それは助けにはなりませんでした。

アイデア?

+0

フィールドの編集中に[Enter]を押したユーザーと、ドロップダウンからアイテムを選択したユーザーの違いは何ですか? – MadProgrammer

+0

@MadProgrammerユーザーは、検索を実行する前に、他の検索フィールドにタブインして何かを入力することができます。矢印キーでオプションを選択すると[Enter]キーを押すのが自然です([Tab]キーを押すこともできます)。アプリケーションはマウスを使用するためのものではありません。 – Kilgore

答えて

1

さて、これは少し重い利きですが、何これが行うのは、とのKeyEvent.VK_ENTERActionを置き換え私たち自身だから、基本的に、ユーザーは Enterキーを押したときに、アウトActionに通知されるが、

Actionコンボボックスではありません(そうJComboBoxはそれのためActionEventをトリガしません - しかし、選択の変更のための意志)努力のため

import java.awt.Component; 
import java.awt.EventQueue; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import javax.swing.AbstractAction; 
import javax.swing.ActionMap; 
import javax.swing.ComboBoxEditor; 
import javax.swing.InputMap; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.KeyStroke; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      setLayout(new GridBagLayout()); 
      final JComboBox<String> cb = new JComboBox<>(new String[]{"Apples", "Bananas", "Pears"}); 
      cb.setEditable(true); 
      SimpleComboBoxEditor editor = new SimpleComboBoxEditor(); 
      InputMap im = editor.getInputMap(); 
      ActionMap am = editor.getActionMap(); 
      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter"); 
      am.put("enter", new AbstractAction() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        if (!cb.isPopupVisible()) { 
         System.out.println("Editor did action"); 
        } 
        cb.hidePopup(); 
       } 
      }); 
      cb.setEditor(editor); 
      cb.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        System.out.println("Combobox did action"); 
       } 
      }); 
      add(cb); 
     } 

     public class SimpleComboBoxEditor extends JTextField implements ComboBoxEditor { 

      @Override 
      public Component getEditorComponent() { 
       return this; 
      } 

      @Override 
      public void setItem(Object anObject) { 
       if (anObject != null) { 
        setText(anObject.toString()); 
       } else { 
        setText(null); 
       } 
      } 

      @Override 
      public Object getItem() { 
       return getText(); 
      } 

     } 

    } 

} 

感謝!それは私がそれを望むように実際には動作しません。選択されたテキストをエディタに残してドロップダウンを閉じるのではなく、[Enter]を押して強調表示された項目を選択すると、 "comboBoxEdited"でイベントが発生します。ドロップダウンが閉じてユーザーが[Enter]を押すと、イベントを発生させるだけです。 [Enter]を押して項目を選択し、[Enter]を押してアクションを開始します。

だから、私は最終的にWindowsマシン上でコードを実行するようになったと基本的には、キーバインディングのためActionに、私はそれがないとき、それは「編集者が行動しなかった」印刷され、isPopupVisibleのチェックをしましたイベント、それ以外の場合はそこではなく、シンプルでエレガントなソリューションが実際にある何も

+0

努力をいただきありがとうございます!それは私がそれを望むように実際には動作しません。エディタに選択したテキストを残してドロップダウンを閉じるのではなく、[Enter]を押して強調表示された項目を選択すると、イベントは '' comboBoxEdited "'で起動します。ドロップダウンが閉じてユーザーが[Enter]を押すと、イベントを発生させるだけです。そこで[Enter]を押して項目を選択し、[Enter]を押してアクションを開始します。 – Kilgore

+0

最初のアプローチを使用し、フィールド自体に反応します – MadProgrammer

+0

私はMacを使用しているので、ドロップのオプションを矢印で押すことはできません。「Enter」を押してください:P – MadProgrammer

-1

しません:直接JComboBoxに追加した場合KeyListenerが動作しないこと

combo.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() { 
    @Override 
    public void keyPressed(KeyEvent e) { 
     if (e.getKeyCode()==KeyEvent.VK_ENTER && !combo.isPopupVisible()) { 
      System.out.println("SEARCH!"); 
     } 
    } 
}); 

注意は、そのEditorComponentに追加する必要があります。

+0

' KeyListener'は決して解決策ではありません。特にテキストコンポーネントを扱うときは、間違っていて問題を解決するための多くの方法があります。 – MadProgrammer

+0

@MadProgrammer間違っているか、私に何らかの情報源を指している? – Kilgore

+0

一般的に、ほとんどの場合、キーリスナーは不適切な選択です。イベントが配信される順序や、イベントチェーンのある時点でキーが消費された場合、フィールドが更新された可能性がある場合、一般的な経験則として、達成しようとしていることに応じて、キーバインディング、DocumentFilterまたはDocumentListenerをKeyListenerで使用する必要があります – MadProgrammer

関連する問題