AutoComplete GUI

Status
Nicht offen für weitere Antworten.

bjcoon

Aktives Mitglied
Hallo an euch alle.

Meine Aufgabe ist es eine AutoComplete-Klasse zu schreiben.

Im Grunde soll diese schlicht über eine GUI - JFrame, JTextfield etc. eingetippte Strings mit Enter in bspw. ein Array schreiben. Den Inhalt dieses Arrays wenn notwendig in eine Datei schreiben.

Nun soll bei jedem weiteren Versuch einer Eingabe eines neuen Wortes ein AutoComplete stattfinden. Und zwar auf Basis der bereits im Array bzw. Datei vorhandenen Strings.

Mit welchen Klassen realisiere ich das Ganze?
Ich bin mir nicht sicher, ob ich den FileWriter, einen FileOutputStream nutzen soll...
wäre toll, wenn ich von euch eine Art Abbildung in die "reale Welt" bekommen könnte. Eine Art Modellierung.

Vielen Dank!
 

bjcoon

Aktives Mitglied
Hab bereits folgendes implementiert:


Code:
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;


public class AutoCompleteGUI extends JFrame implements KeyListener {

	public AutoCompleteGUI() {
	
		setSize(200,100);
		setBackground(Color.BLUE);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLayout(new FlowLayout());
		
		JTextField field = new JTextField(10);
		add(field);
		JLabel label = new JLabel("\nEingabe");
		add(label);
		
		setVisible(true);
		
		
	}
	
	public static void main (String[]args) {
		
		new AutoCompleteGUI();
		
	}
	
	
	public void keyPressed(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

}

Es passiert noch nicht viel, eigentlich garnichts, aber in waiser Voraussicht habe ich bereits den KeyListener implementiert. Arbeite ich mit OutputStream und nem FileOutputStream weiter?! Erstelle ich eine weitere Klasse!?
 

Zed

Bekanntes Mitglied
Ich gabe die Frage nicht richtig gelesen und hab nur Käse in dem Post geschrieben. Darum hab ich ihn wegeditiert
 

Ebenius

Top Contributor
bjcoon, warum gehst Du denn nicht auf SlaterBs Suchergebnisse oben ein. Der erste Treffer klingt doch schonmal super.
 

bjcoon

Aktives Mitglied
Ich möchte keine Grundsatzdiskussion entfachen, aber entsprechend meinen Kenntnissen, welche ich bei der Auswahl des Forumsbereichs bereits berücksichtigt habe und deswegen im Anfängerforum geschrieben habe, ist auch die Frage.

Leider ich bin ich mit meinen Fähigkeiten nicht soweit, dass ich Code den ich über google finde, analysieren und verstehen kann. Ich würde die Klasse gerne auf Basis meiner Kenntnisse aufbauen. Das Suchergebnis über google ist nicht schlecht und es ist auch nicht so, dass ich nicht schon Codebeispiele gefunden habe. Allerdings entziehen diese sich meistens meinem Kenntnisstand. Und es geht ja in erster Linie darum, seinen Code zu verstehen und nicht zu kopieren.

Ich bitte also um Entschuldigung, sollte ich euch mit Anfängerfragen belästigen.

Ich möchte gerne einen ObjetOutputstream verwenden und weiß nicht, wo ich diesen implementieren soll. In eine andere Klasse auslagern, oder im Konstruktor des GUIs.
 

Zed

Bekanntes Mitglied
Geh doch Schrittweise vor.

Du musst es erstmal schaffen eine Datei mit den eingegebenen Wörtern zu erstellen. Dabei musst du beachten das schon vorhandene ergebnisse nicht nochmal in diese Datei geschrieben werden.

Die einfache Möglichkeit wäre die Datei bei Progammstart in ein HashSet<String> einzulesen. Und jedesmal neu auf die Platte schreiben wenn ein neuer Eintrag hinzukommt.

Versuch erstmal das zu implementieren. Dazu brauchst du einen ActionListener, Filewriter, File und ein HasSet
 

bjcoon

Aktives Mitglied
Also in die Datei zu schreiben funktioniert mit folgendem:


Code:
public class AutoCompleteGUI extends JFrame implements KeyListener, ActionListener {

	protected String[] elements;
	
	public AutoCompleteGUI() {
	
		setSize(200,100);
		setBackground(Color.BLUE);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLayout(new FlowLayout());
		
		JTextField field = new JTextField(10);
		add(field);
		JLabel label = new JLabel("Eingabe");
		add(label);
		
		setVisible(true);
		pack();
		
		field.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent ae){
				FileWriter fw = null;
			    try
			    {
			     	fw = new FileWriter( "fileWriter.txt", true );
			    	fw.write(ae.getActionCommand() + "\n");
			    	

			    	
			    }
			    catch ( IOException e ) {
			      System.err.println( "Konnte Datei nicht erstellen" );
			    }
			    finally {
			      if ( fw != null )
			        try { 
			        	fw.close();
			        } catch (IOException ioe) {}
			    }				
		}});
		
	}
 

Ebenius

Top Contributor
bjcoon, damit habe ich kein Problem. Aber wenn Du in Deinem Thread auf solche Hinweise nicht eingehst ─ indem Du beispielsweise sagst, wo Du gefundene Informationen nicht verstanden hast, oder irgendwas ─ sondern sie einfach ignorierst, dann darfst Du Dich nicht wundern, wenn keiner mehr etwas schreibt.

Dann also zum Thema:
  1. Du möchtest beim Eintippen eine Liste aufklappen lassen mit allen gefundenen Treffern. Dazu würde ich eine JComboBox nutzen, da diese bereits den Mechanismus zum Aufklappen einer Liste mitbringt. Die JComboBox muss editierbar sein, ansonsten kann man nur auswählen und nichts eintippen. Deutsche Anleitungen kenne ich nicht (gibt es ganz sicher), aber ─ annehmbare Englischkenntnisse vorausgesetzt ─ das Sun-Tutorial: How to Use Combo Boxes ist ein guter Einstiegsstoff.
  2. Da Du einen wiederverwendbaren Mechanismus bauen möchtest der die Grundfunktion einer JComboBox erweitert würde ich eine Klasse erzeugen JAutoCompleteComboBox die von JComboBox erbt.[Anhang A]
  3. Ein bisschen schwierig ist es herauszufinden, wie man an die eingegebenen Daten kommt, während der Nutzer tippt. Dazu holt man sich den ComboBoxEditor, dessen Editorkomponente und nimmt an, dass es sich dabei um ein JTextField handelt. Das ist der Fall, sofern man keinen anderen ComboBoxEditor setzt. Von diesem JTextField kann man sich dann das Dokument holen und an dieses kann man einen DocumentListener anhängen. Das ist besser als KeyboardEvents abzufangen, da man direkt dem Modell zuhören kann. [Anhang B]
  4. Der Listener kann als innere Klasse der JAutoCompleteComboBox aufgebaut werden und hat die Aufgabe, bei jeder Änderung im Dokument zu prüfen, ob der Text des Dokuments im Modell der JAutoCompleteComboBox enthalten vorkommt. Wenn dies der Fall ist wird der gefundene Eintrag ausgewählt.
Genügt das als Ansatz?

Ebenius
Anhang A
Code:
public class JAutoCompleteComboBox extends JComboBox {

  /**
   * Creates a new {@code JAutoCompleteComboBox}.
   */
  public JAutoCompleteComboBox() {
    super();
  }

  // ... Hier geht es weiter
}
Anhang B
Code:
public class JAutoCompleteComboBox extends JComboBox {

  // ... Quelltext von oben

  public void setEditor(ComboBoxEditor editor) {
    final ComboBoxEditor oldComboBoxEditor = getEditor();
    super.setEditor(editor);
    // TODO: DocumentListener an die Editorkomponente des neuen Editors hängen
    // wenn dieser nicht null ist. DocumentListener von der Editorkomponente des
    // alten Editors entfernen, wenn dieser nicht null ist.
  }

  // ... Hier geht es weiter
}
 

bjcoon

Aktives Mitglied
@ebenius

Ich hab leider nichts von ner ComboBox erwähnt. Die brauch ich auch nicht. Es geht ganz banal nur ums Auslesen des Inhalts einer Datei oder Arrays, welches mit der aktuellen Eingabe im TextField auf Übereinstimmung verglichen wird und "Autovervollständigen" - naja ich sag mal - passieren soll.

Ich kann dein Problem mit Anfängern wie mir nachvollziehen, aber ich habe echt als letztes irgendetwas ignoriert. Das muss du bitte berücksichtigen. Es geht um keine Combox, sondern nur um das vorschlagen von treffern im textfield selbst!!
 

diggaa1984

Top Contributor
muss man wohl fragen wie sich das "auto-vervollstädnigen" in deiner Gui grafisch verhalten soll .. nehmen wir das Bsp aus nem Browser .. dort klappt auch was herunter .. das geht mit nem normalen Textfeld nicht einfach so, das müsstest selbst noch drum bauen (wie auch immer das praktisch umgesetzt wird, fällt mir grad auch nix simples ein um das zu realisieren). Eine Combobox bringt diesen Aufklappmechanismus schon mit, daher könnte dir das die arbeit wesentlich erleichtern, und daher der Vorschlag von Ebenius nehm ich an :D
Oder willst das so machen: Wort suchen gemäß erfolgter Eingabe .. Wenn eins gefunden was so anfängt, dann in Textfeld schreiben, und Rest, der automatisch rangedichtet wurde markieren, sodass bei weiteren Eingaben alles rangedichtete verschwindet und er aufgrund der neuen fixen Eingabe wieder sucht!?.

denke die Art der Vervollständigung sollte erstmal geklärt werden um dir gezielt helfen zu können
 

Ebenius

Top Contributor
Mit nur einem JTextField kann man natürlich auch arbeiten, das wäre dann so wie die Wortvervollständigung beim SMS-Tippen auf vielen Handies. Meinst Du sowas?

@diggaa, richtig angenommen.

Ebenius
 

bjcoon

Aktives Mitglied
diggaa1984 hat gesagt.:
Oder willst das so machen: Wort suchen gemäß erfolgter Eingabe .. Wenn eins gefunden was so anfängt, dann in Textfeld schreiben, und Rest, der automatisch rangedichtet wurde markieren, sodass bei weiteren Eingaben alles rangedichtete verschwindet und er aufgrund der neuen fixen Eingabe wieder sucht!?.

denke die Art der Vervollständigung sollte erstmal geklärt werden um dir gezielt helfen zu können

genau das ist es, was ich programmieren will. die umsetzung mit nem objectoutputstream und nem fileoutputstream zu machen sein.

ich hab, wie im code oben zu sehen, schon nen actionlistener für die speicherung in ner datei implementiert und brauch halt nur noch ne suche und abgleichung mit den bereits eingegebenen und in die datei geschriebenen strings. von mir aus auch kann ein array als "suchobjekt" herhalten...
 

bjcoon

Aktives Mitglied
diggaa1984 hat gesagt.:
Oder willst das so machen: Wort suchen gemäß erfolgter Eingabe .. Wenn eins gefunden was so anfängt, dann in Textfeld schreiben, und Rest, der automatisch rangedichtet wurde markieren, sodass bei weiteren Eingaben alles rangedichtete verschwindet und er aufgrund der neuen fixen Eingabe wieder sucht!?.

denke die Art der Vervollständigung sollte erstmal geklärt werden um dir gezielt helfen zu können

genau das ist es, was ich programmieren will. die umsetzung mit nem objectoutputstream und nem fileoutputstream zu machen sein.

ich hab, wie im code oben zu sehen, schon nen actionlistener für die speicherung in ner datei implementiert und brauch halt nur noch ne suche und abgleichung mit den bereits eingegebenen und in die datei geschriebenen strings. von mir aus auch kann ein array als "suchobjekt" herhalten...
 

bjcoon

Aktives Mitglied
Mein Code sieht folgendermaßen aus (mittlerweile):


Code:
public class AutoCompleteGUI extends JFrame implements KeyListener, ActionListener {

	protected String[] elements;
	
	public AutoCompleteGUI() {
	
		setSize(200,100);
		setBackground(Color.BLUE);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLayout(new GridLayout(2,1));
		
		JTextField field = new JTextField(10);
		add(field);
		JLabel label = new JLabel("Eingabe");
		add(label);
		
		setVisible(true);
		pack();
		
		field.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent ae){
//				FileWriter fw = null;
				ObjectOutputStream oos = null;
			    try {
//			     	fw = new FileWriter( "fileWriter.txt", true );
//			    	fw.write(ae.getActionCommand() + "\n");
			    	oos = new ObjectOutputStream(new FileOutputStream("elsenew.txt"));
			    	oos.writeObject(this);
			    	oos.close();
			    	
				}
			    	
//			    }
			    catch ( IOException e ) {
			      System.err.println( "Konnte Datei nicht erstellen" );
			    }
		}});
	}

Leider wird die Datei, in die geschrieben werden soll nicht erstellt und die Exception greift. Was ist der Fehler?!
 

Ebenius

Top Contributor
In Zeile 35 einfügen und die Ausgabe posten:
Code:
e.printStackTrace();
[edit] Wahrscheinlich lässt sich was nicht serialisieren. Es ist ohnehin keine gute Idee einen ObjectOutputStream zu benutzen. Warum auch. Du willst nur Strings aus einem Array schreiben:
Code:
BufferedWriter w = null;
try {
  w = new BufferedWriter(new FileWriter(new File("myFile")));
  for (String word : myArray) {
    w.write(word);
    w.newLine();
  }
  w.flush();
} catch (IOException ex) {
  ex.printStackTrace();
  // TODO: your exception handling here
} finally {
  if (w != null) {
    try {
      w.flush(); // needs to be done in Java <= 5
    } catch (IOException ex) { /* can't help here */ }
    try {
      w.close();
    } catch (IOException ex) { /* can't help here */ }
  }
}
Fertig. Ein Begriff pro Zeile.

Ebenius
 

bjcoon

Aktives Mitglied
Code:
java.io.NotSerializableException: AutoCompleteGUI$1
	at java.io.ObjectOutputStream.writeObject0(Unknown Source)
	at java.io.ObjectOutputStream.writeObject(Unknown Source)
	at AutoCompleteGUI$1.actionPerformed(AutoCompleteGUI.java:34)
	at javax.swing.JTextField.fireActionPerformed(Unknown Source)
	at javax.swing.JTextField.postActionEvent(Unknown Source)
	at javax.swing.JTextField$NotifyAction.actionPerformed(Unknown Source)
	at javax.swing.SwingUtilities.notifyAction(Unknown Source)
	at javax.swing.JComponent.processKeyBinding(Unknown Source)
	at javax.swing.JComponent.processKeyBindings(Unknown Source)
	at javax.swing.JComponent.processKeyEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
	at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
	at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
	at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
	at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

offensichtlich ist eine "unknown source" das problem. ;)
 

Ebenius

Top Contributor
Offensichtlich versuchst Du Deinen ActionListener zu serialisieren. Warum überhaupt GUI-Komponenten serialisieren. Nee, nee...

Nimm lieber den Code oben (hab editiert)!

Ebenius
 

diggaa1984

Top Contributor
ne andere seite: java.io.NotSerializableException: AutoCompleteGUI$1
Thrown when an instance is required to have a Serializable interface. The serialization runtime or the class of the instance can throw this exception. The argument should be the name of the class.
 

Ebenius

Top Contributor
diggaa, bitte lass uns von der Serialisierung weggehen... Der ThreadOpener will nur ein StringArray schreiben und lesen. Was gibt es da besseres als lesbaren Text?
 

diggaa1984

Top Contributor
nix, wollte ihn nur auf den Fehler stoßen :D .. das Interpretieren des Fehlers fing ja schon im deuten der falschen Zeile an ^^

Serialisierung ist hier natürlich fehl am Platz, bin ich ganz deiner Meinung
 

bjcoon

Aktives Mitglied
ist es schlichtweg falsch mit serialisierung zu arbeiten, oder einfach nicht die eleganteste Art?
Die meisten bei uns im Semester haben damit gearbeitet. Nur ne Frage?
Hauptsache es funktioniert am Ende...

Kann mir einer von euch beiden jetzt nohc klar machen, was ich zum Erreichen meines Ziels noch brauch!? Ich steh ein wenig auf dem Schlauch im Moment.
 

Ebenius

Top Contributor
Serialisierung ist dafür da, Objekte zu übertragen. Sie ist nicht dafür da, Objekte abzuspeichern. Man kann das machen, sollte man aber nicht. Und es fängt bereits bei solchen Problemen wie Du oben hattest an: "Whoops, war ja das falsche Objekt." Oder "Huch, ist ja eine Ableitung der Klasse, die hab ich in dem anderen Programm aber gar nicht und bekomme damit die Daten nicht zurück". :)

Die Schreibfunktion oben hast Du gesehen und verstanden? Schon eingebaut? Funktioniert sie?

Wenn das Schreiben geht, kümmer Dich um's einlesen! Das geht im Prinzip so ähnlich, nur mit BufferedReader / File Reader statt Writer. Wenn Du das fertig hast, geht's irgendwie weiter. :)

Ebenius
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben