[JAVA] editable JComboBox mit shortcut?

AleX

Erfahrenes Mitglied
hi,
stehe vor folgendem prob:

Also bei einer normalen JComboBox die nicht editable ist, kann man ja ganz einfach mit nem KeyListener den eingegebenen Buchstaben als char einlesen und das Pulldownmenue der cb aufklappen lassen und den ersten mit dem selben buchstaben anfangenden eintrag markieren.

Jetzt hab ich aber das problem, dass meine cb editable ist und ich überhaupt keine events bei drücken von tasten zurückbekomme.
Gut, dann hab ich mir gedacht dass das teil ja sowieso so mischmasch aus Textfield und button usw... also greif ich folgendermaßen drauf zu:
Code:
JComboBox cb = new JComboBox(data);
Component comp = cb.getEditor().getEditorComponent();
        comp.addKeyListener(new MyKeyListener() {
            public void keyPressed(KeyEvent evt) {
                char ch = evt.getKeyChar();
                System.out.println(ch + " gefunden");
                if (ch != KeyEvent.CHAR_UNDEFINED) {
                    cbClassification.showPopup();
                }
            }
        });

So kann ich zwar die eingaben wieder auslesen, weis jetzt allerdings wirklich nicht, wie ich es mache, dass der bei Übereinstimmtung das Pulldownmenue aufmacht und dort den entsprechenden eintrag markiert:

Fürs Verständnis:
ich geb ein:
"Au"
in meinem Pulldownmenue ist folgendes drin:
Aluminium
Oma
Auto
Autofahrer
usw.
und jetzt soll er bei der eingabe das pulldownmenue aufmachen und "Auto" markieren. Hätte ich nur "A" eingegeben sollte er schon bei Aluminium bleiben und dieses markieren.

Es würde mir anfangs auch reichen, wenn er das ganze nur nach einem Buchstaben dursuchen würde. ;)

Hoffe es kann mir jemand weiterhelfen.
Schonmal danke im Vorraus
 

Thomas Darimont

Erfahrenes Mitglied
Das hier hab ich dazu in ner Newsgroup gefunden...
funktioniert ganz gut...

/*
* JSelComboBox.java
*
* Created on 23. Juni 2000, 19:23
*/
Code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
 * Eine editierbare Combobox, die den nächsten wahrscheinlichen 
 * Eintrag vorschlägt. Mit der Methode setInputListItemsOnly(bOnly) 
 * kann festgelegt werden, ob nur die Listeneinträge eingegeben werden
 * können, oder beliebige Eingaben erlaubt werden.
 * Als Standard ist festgelegt, dass alle Eingaben erlaubt sind.
 *
 * Implementations-Info: Um die Logik zu vereinfachen wird bei der 
 * Taste [Entf] das gesamte Feld gelöscht. Sonderfunktionen wie z.B. 
 * Aussschneiden werden noch nicht berücksichtigt.
 * Die Einträge sollten alphabetisch sortiert sein.
 *
 * @author  Aljoscha Rittner
 * @version 1.0 (immer noch ;-)
 */
public class JSelComboBox extends JComboBox implements KeyListener {
  
  // Nur Einträge der Liste editierbar
  boolean inputListItemsOnly = false;
  boolean caseSensitive      = false;
 
  public JSelComboBox () {
    super();
    setEditable(true);
    getEditor().getEditorComponent().addKeyListener(this);
  }
  
  public JSelComboBox (Object[] items) {
    super(items);
    setEditable(true);
    getEditor().getEditorComponent().addKeyListener(this);
  }
  
  /**
   * Setzt das Verhalten für Eingaben, die nicht den Listeneinträgen 
   * entsprechen.
   * @param bOnly true: nur Listeinträge; false: alle Eingaben 
   *              erlauben.
   */ 
  public void setInputListItemsOnly (boolean bOnly) {
    inputListItemsOnly = bOnly;
  }

  /**
   * Gibt das Verhalten für Eingaben, die nicht den Listeneinträgen 
   * entsprechen zurück.
   * @return true: nur Listeinträge; false: alle Eingaben erlauben 
   */ 
  public boolean isInputListItemsOnly () {
    return inputListItemsOnly;
  }

  /**
   * Setzt das Verhalten für die Suche der Listeneinträge.
   * @param bCaseSensitive true: Groß/Kleinschreibung ist notwendig
   */ 
  public void setCaseSensitive (boolean bCaseSensitive) {
    caseSensitive = bCaseSensitive;
  }

  /**
   * Gibt das Verhalten für die Suche der Listeneinträge zurück.
   * @param bCaseSensitive true: Groß/Kleinschreibung ist notwendig
   */ 
  public boolean isCaseSensitive () {
    return caseSensitive;
  }

  public void keyReleased(final java.awt.event.KeyEvent p1) {
  }

  public void keyPressed(final java.awt.event.KeyEvent p1) {
    if (! isPopupVisible() ) {
      setPopupVisible(true);
    }
    if (p1.getKeyCode() == p1.VK_DELETE) {      
      JTextField jtf = (JTextField) getEditor().getEditorComponent();
      resetInput();
      p1.consume();
    }
  }

  public void keyTyped(final java.awt.event.KeyEvent p1) {    
    int nPos = -1;
    String search = null;
    
    JTextField jtf = (JTextField) getEditor().getEditorComponent();
    
    nPos = jtf.getSelectionStart();
    if ( nPos != -1 ) {
      if ( p1.getKeyChar() == p1.VK_BACK_SPACE ) {
        search = jtf.getText()
          .substring(0, nPos == 0 ? nPos : nPos-1);
        if ( search.equals("") ) {
          resetInput();
          p1.consume();
          return;
        }
      } else {
        search = jtf.getText().substring(0, nPos);
        search = search + p1.getKeyChar();
      }

      findAndSel (search, p1);
    } else {
      setSelectedIndex(-1);
    }
  }  
  
  /**
   * Sucht einen Eintrag anhand einer Zeichenkette und wählt evtl. 
   * eine Zeile aus.
   * Wenn nur Listeneinträge ausgewählt werden dürfen und die 
   * Zeichenkette nicht gefunden wurde, dann wird die Eingabe 
   * verhindert.
   * @param search Zeichenkette für die Suche
   * @param p1     Event des Tastendruckes
   */
  protected void findAndSel (String search, 
                             java.awt.event.KeyEvent p1) {
    JTextField jtf = (JTextField) getEditor().getEditorComponent();
    int start = getSelectedIndex() + 1;      
    int index = findString (search, start);

    if ( index == -1 )
      index = findString (search, start-1);

    if ( index == -1 )
      index = findString (search, 0);

    if ( index != -1 ) {
      System.out.println(index);
      String found = getModel().getElementAt(index).toString();
      setSelectedIndex(index);
      jtf.setText(found);
      jtf.setCaretPosition (search.length());
      jtf.setSelectionEnd (found.length());
      jtf.setSelectionStart (search.length());        
      p1.consume();
    } else {
      if ( isInputListItemsOnly () ) {
        getToolkit().beep();
        p1.consume();
      }
    }
  }
  
  /**
   * Sucht einen Eintrag anhand einer Zeichenkette und gibt die Zeile 
   * zurück.
   */
  protected int findString (String search, int start) {
    ComboBoxModel cbm = getModel();
    if ( start < 0 ) start = 0;
    for ( int i = start; i < cbm.getSize(); i++ ) {
      if (isCaseSensitive()) {
        if ( cbm.getElementAt(i).toString().startsWith(search) ) {
          return i;
        }
      } else {
        if ( cbm.getElementAt(i).toString().toLowerCase()
             .startsWith(search.toLowerCase()) ) {
          return i;
        }
      }
    }
    return -1;
  }
  
  /**
   * Setzt die Eingaben und die Auswahlzeile zurück.
   */ 
  protected void resetInput() {
    JTextField jtf = (JTextField) getEditor().getEditorComponent();
    if ( isInputListItemsOnly () == false ) {
      jtf.setText("");
      jtf.setCaretPosition(0);
      setSelectedIndex(-1);
    } else {
      jtf.setText (getModel().getElementAt(0).toString());
      setSelectedIndex(0);
      jtf.setSelectionEnd(jtf.getText().length());
      jtf.setSelectionStart(0);        
    }        
  }
}
Gruss Tom
 
Zuletzt bearbeitet:

AleX

Erfahrenes Mitglied
big thx!

werds mir morgen gleich ansehen

//edit: jo, funktioniert eiwandfrei :)
 
Zuletzt bearbeitet:

Neue Beiträge