# Text-Vorschläge für JTextField aus ner Liste laden



## Paddy. (26. Jul 2011)

Ich würde gerne bei einem JTextField während der Eingabe überprüfen als Anfang bzw. komplett in einem (sortierten) ArrayList vorkommt.
Also ich gebe Text ein und falls vorkommt wird ein Vorschlag gemacht wie man ergänzen könnte.
Und dann kann man den entweder so stehen lassen oder weiter tippen und damit ggf. das Wort ändern.

habs mit setSelectionStart und End versucht klappt aber net so recht.


----------



## Monaria (26. Jul 2011)

Hast du vllt etwas Code?
Denn bei mir funktioniert das hier einwandfrei:

```
JTextField input = new JTextField();
input.setText("Word");
input.setSelectionStart(0);
input.setSelectionEnd(4);
```


----------



## Paddy. (27. Jul 2011)

ja so hab ichs auch gemacht!
zum KeyType-Event:

```
JTextField tf=(JTextField)evt.getSource();
        for(int i=0;i<liste.size();i++){
            String z=liste.get(i);
            if(z.startsWith(tf.getText())){
                int eingabe=tf.getText().length();
                tf.setText(z);
                tf.setSelectionStart(eingabe);
                tf.setSelectionEnd(z.length());
            }
        }
```
Vielleicht ist also das Event Falsch zumind gibts Probleme wenn ich weiter Tippe.


----------



## SlaterB (27. Jul 2011)

> zumind gibts Probleme wenn ich weiter Tippe. 
geht es einen Tick genauer?

auch das Zur-Verfügung-Stellen eines kompletten kleinen Testprogramms mit Dummy-Daten wäre hilfreich,
dann könnte es jeder kopieren, direkt ausprobieren und vielleicht was schlaues dazu sagen,

so kannst du nur auf die Leute hoffen, die es direkt wissen oder sich den Aufwand machen selber ein Testprogramm zusammenzustellen,
das ist wohl ein kleineres Zielpublikum..

-----

falls noch nicht bekannt:
das (edit: ein) Fachwort dafür ist autocomplete, 
'jcombobox autocomplete' findet vieles in Suchmaschinen


----------



## Paddy. (27. Jul 2011)

Also ungefähr so:
Ne JFrame mit einem JTextField.
Wenn ich nun in das Textfeld eingebe passiert nix und das gebenfalls löschen klappt auch net so recht.


```
public class NewJFrame extends javax.swing.JFrame {

    java.util.ArrayList<String> liste =new java.util.ArrayList();
    public NewJFrame() {
        initComponents();
        liste.add("Auto");
        liste.add("Flugzeug");
        liste.add("Apfel");
        liste.add("Buch");
        liste.add("Brücke");
        liste.add("Ampel");
        java.util.Collections.sort(liste);
    }

    
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jTextField1 = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jTextField1.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                jTextField1KeyTyped(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(269, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>

    private void jTextField1KeyTyped(java.awt.event.KeyEvent evt) {
        javax.swing.JTextField tf=(javax.swing.JTextField)evt.getSource();
        for(int i=0;i<liste.size();i++){
            String z=liste.get(i);
            System.out.println("Liste:"+liste.get(i)+"\tText:"+tf.getText());
            if(z.startsWith(tf.getText())){
                int eingabe=tf.getText().length();
                tf.setText(z);
                tf.repaint();
                tf.select(eingabe,z.length() );
            }
        }
    }


    public static void main(String args[]) {
        NewJFrame njf=new NewJFrame();
        njf.setVisible(true);
    }
    // Variables declaration - do not modify
    private javax.swing.JTextField jTextField1;
    // End of variables declaration
}
```


----------



## SlaterB (27. Jul 2011)

das unvermeidliche GroupLayout, ohne GUI-Builder gehts nicht?
Zeile 30 bis 45 könnten auch ganz einfach durch 
add(jTextField1);
ersetzt werden..

ich habe soweit festgestellt, dass ein Problem ist, dass wohl noch andere Listener nebenher aktiv arbeiten und teilweise das aktuell getippte Zeichen noch gar nicht in tf.getText() drin ist, als auch nach deinem setText() noch der Text wieder überschrieben wird, was mich etwas erstaunt,

eine kurzfristige Lösung ist, die Überarbeitung etwas verzögert zu starten, dann funktioniert es bei mir, siehe Programm unten,
soweit will ich es erstmal belassen und nicht alles erforschen (kann ich vielleicht auch gar nicht), evtl. sollte man das Document austauschen usw.,
die Verzögerung kann auch ganz praktisch sein, evtl. darauf achten dass nicht mehrere gleichzeitig laufen wenn schnell viel eingetippt wird


```
public class Test {

    public static void main(String[] args) {
        NewJFrame njf = new NewJFrame();
        njf.setVisible(true);
    }
}

class NewJFrame  extends JFrame {
    private List<String> liste = new java.util.ArrayList();
    private JTextField jTextField1;

    public NewJFrame() {
        initComponents();
        liste.add("Auto");
        liste.add("Flugzeug");
        liste.add("Apfel");
        liste.add("Buch");
        liste.add("Brücke");
        liste.add("Ampel");
        java.util.Collections.sort(liste);
    }

    private void initComponents() {
        jTextField1 = new JTextField();
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        jTextField1.addKeyListener(new KeyAdapter() {
                public void keyTyped(final KeyEvent evt)  {
                    Runnable r = new Runnable()  {
                            public void run()  {
                                try { Thread.sleep(100); } catch (Exception e) {}
                                jTextField1KeyTyped(evt);
                            }
                        };
                    new Thread(r).start();
                }
            });

        add(jTextField1);
        pack();
    }

    private void jTextField1KeyTyped(KeyEvent evt) {
        JTextField tf = (JTextField)evt.getSource();
        for (int i = 0; i < liste.size(); i++)  {
            String z = liste.get(i);
            System.out.println("Liste:" + liste.get(i) + "\tText:" + tf.getText());
            if (z.startsWith(tf.getText()))  {
                int eingabe = tf.getText().length();
                tf.setText(z);
                tf.repaint();
                tf.select(eingabe, z.length());
                return;
            }
        }
    }
}
```


----------



## Monaria (27. Jul 2011)

```
if (z.startsWith(tf.getText()))
```

sollteman noch in 


```
if (z.startsWith(tf.getText()) &&  !tf.getText().isEmpty())
```

ändern, denn "" enthält jeder String in der Liste.


----------



## Paddy. (27. Jul 2011)

SlaterB hat gesagt.:


> das unvermeidliche GroupLayout, ohne GUI-Builder gehts nicht?
> Zeile 30 bis 45 könnten auch ganz einfach durch
> add(jTextField1);
> ersetzt werden..
> ...


----------



## Monaria (27. Jul 2011)

Fehlt nurnoch, dass bei bestimmten Tasten nur ihre eigentliche Funktion ausgeführt wird.
Ein Vorschlag wäre das hier...eventuell müssen noch ein paar Werte in isWriting hinzugefügt werden, damit alles abgefangen wird. Man könnte für die Werte auch gleich eine Liste anlegen, aber im mom sind es ja nur 4.
(isWriting prüft, ob etwas eingetippt wird oder nicht...liefert also z.B. beim Löschen false)


```
public void keyPressed(final KeyEvent evt){
        if(isWriting(evt)){
        	Runnable r = new Runnable()  {
        		public void run()  {
                                try { Thread.sleep(100); } catch (Exception e) {}
                                jTextField1KeyTyped(evt);
                       }
                 };
                 new Thread(r).start();
                 System.out.println(evt.getKeyCode());
        }
}

private boolean isWriting(KeyEvent e){
        int i = e.getKeyCode();
        if(i != 8 && i != 127 && i != 37 && i != 39)
        	return true;
        return false;
}
```


----------

