AJRames Geschrieben 17. Februar 2009 Teilen Geschrieben 17. Februar 2009 Hi Leute! Brauch eure Hilfe, ich komm nicht mehr weiter, obwohl ich schon recht weit gekommen bin... Folgendes: Ich hab ne Datenbank im Hintergrund laufen und ein TextField. Dieses TextField überwache ich mit nem KeyListener und frag während der Eingabe nach ob die Daten in der DB vorhanden sind, falls es einen entsprechenden Eintrag gibt, füllt der Listener automatisch des Feld komplett (Autovervollständigung). Z.B. wenn ich "Ba" eingebe füllt er das TextFeld mit dem Namen "Bachmann". Nur leider klappt das nur auf die eine weise (Ich lass ne for schleife vorher laufen um die Eintrage aus der DB einzulesen). Die For schleife braucht jedoch ne weile und schluckt ressourcen. Ich möchte dies jedoch ohne for, sondern direkt auf die DB zugreifen. Hier nun der Code. Die GUI: package Richtig; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.*; import java.sql.SQLException; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.JTextField; public class TestKlasse2 extends JFrame{ private static final long serialVersionUID = 1L; private JButton bladefirma, bkundeninfo; private JLabel label, iplabel,jlKunden; private JPanel labelpanel, buttonpanel, editpanel; private JTextArea edit, edit2; private JTextField edit3, ip1, jtfKunden; private DROP d; public static String ipadresse; Ohr o = new Ohr(); public TestKlasse2() throws SQLException { super(); this.setTitle("AJ's"); bladefirma = new JButton("Drück mich"); bkundeninfo = new JButton("Info zum Kunden"); label = new JLabel("KundenNr:"); iplabel = new JLabel("ServerIP:"); jlKunden = new JLabel("Kundenname: "); labelpanel = new JPanel(); d = new DROP(50); edit = new JTextArea(); edit2 = new JTextArea(); edit3 = new JTextField(15); ip1 = new JTextField(15); jtfKunden = new JTextField(15); editpanel = new JPanel(new GridLayout(1,2)); editpanel.add(edit); editpanel.add(edit2); labelpanel.setLayout(new GridLayout(3,1)); labelpanel.add(label); labelpanel.add(edit3); labelpanel.add(iplabel); labelpanel.add(ip1); labelpanel.add(jlKunden); labelpanel.add(d.test2()); buttonpanel = new JPanel(); buttonpanel.setLayout(new GridLayout(1,2)); buttonpanel.add(bladefirma); buttonpanel.add(bkundeninfo); this.getContentPane().setLayout(new BorderLayout()); this.getContentPane().add(labelpanel, BorderLayout.NORTH); this.getContentPane().add(editpanel, BorderLayout.CENTER); this.getContentPane().add(buttonpanel,BorderLayout.SOUTH); bladefirma.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { ipadresse = ip1.getText(); o.ladeFirmenBez(edit); } }); bkundeninfo.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e){ ipadresse = ip1.getText(); edit2.append(o.infoZumKunden(edit3.getText())); edit2.append("\n"); } }); /**this.addKeyListener(new KeyAdapter(){ @Override public void keyTyped(KeyEvent e) { System.out.println("Jep"); } }); */ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } Die Klasse für das TextFeld zur Verfollständigung: package Richtig; import java.awt.event.KeyListener; import java.awt.event.KeyEvent; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.JTextField; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Vector; public class DROP extends JTextField implements KeyListener { private Vector<String> data = null; private boolean doNothingElse = false; private static final long serialVersionUID = 1L; public DROP(int lang) { super(lang); addKeyListener(this); data = new Vector<String>(); } public void setData(Vector<String> data) { this.data = data; } public void addData(String str) { data.add(str); } public void deleteData(String str) { data.remove(str); } private void quickSearch(String start) { for (String str : data) { if (str.startsWith(start)) { setText(str); select(start.length(), str.length()); doNothingElse = true; break; } } } private void handleKey(char key) { String selection = getSelectedText(); if (selection != null && selection.charAt(0) == key) { doNothingElse = true; setSelectionStart(getSelectionStart() + 1); } else if (selection != null) { String nonSelected = getText().substring(0, getText().length() - selection.length()) + key; quickSearch(nonSelected); } else { quickSearch(getText() + key); } } public void keyTyped(KeyEvent key) { if (doNothingElse == true) { key.consume(); doNothingElse = false; } } public void keyPressed(KeyEvent key) { if (Character.isLetter(key.getKeyChar()) || key.getKeyChar() == ' ') { handleKey(key.getKeyChar()); } } public void keyReleased(KeyEvent key) { } public DROP test() { //DB Verbindung Herstellen try { Class.forName("org.hsqldb.jdbcDriver"); } catch (Exception e) { System.out.println("ERROR: failed to load HSQLDB JDBC driver."); e.printStackTrace(); } Connection con = null; try { con = DriverManager.getConnection( "jdbc:hsqldb:hsql://192.168.0.3/TrinityTestAJ", "sa", ""); } catch (SQLException e) { System.out.println("Keine Verbindung!"); } Statement state = null; try { state = con.createStatement(); } catch (SQLException e) { System.out.println("Kann kein Statement erzeugen"); } //DB Verbindung ist hergestellt worden System.out.println("Verbindung Steht"); ; for(int i=10105;i<10800;i++){ String sql = "SELECT NAME FROM ADRESSEN WHERE FIRMANR="+i+";"; try { ResultSet res = state.executeQuery(sql); while (res.next()) { String name = res.getString("NAME"); this.addData(name); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); //return name; } } return this; } public DROP test2() throws SQLException { //DB Verbindung Herstellen try { Class.forName("org.hsqldb.jdbcDriver"); } catch (Exception e) { System.out.println("ERROR: failed to load HSQLDB JDBC driver."); e.printStackTrace(); } Connection con = null; try { con = DriverManager.getConnection( "jdbc:hsqldb:hsql://192.168.0.3/TrinityTestAJ", "sa", ""); } catch (SQLException e) { System.out.println("Keine Verbindung!"); } Statement state = null; try { state = con.createStatement(); } catch (SQLException e) { System.out.println("Kann kein Statement erzeugen"); } //DB Verbindung ist hergestellt worden System.out.println("Verbindung Steht"); DROP drop = new DROP(15); String sql1 = "SELECT FIRMANR FROM ADRESSEN WHERE NAME LIKE '"+"Ba"+"%';"; System.out.println(sql1); ResultSet res = state.executeQuery(sql1); String sql2 = null; while (res.next()) { int kundennummer = res.getInt("FIRMANR"); System.out.println(kundennummer); sql2 = "SELECT NAME FROM ADRESSEN WHERE FIRMANR="+kundennummer+";"; //this.addData(namen); } try { System.out.println("test"); ResultSet resu = state.executeQuery(sql2); while (resu.next()) { String namen = resu.getString("NAME"); this.addData(namen); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); //return name; } return this; } /** public static void main(String[] args) { JFrame frame = new JFrame(); DROP stf = new DROP(); stf.test(); } die methode test() funktioniert, mit der for. test2() geht nicht. Mein Problem bei test2() ist diese Zeile: String sql1 = "SELECT FIRMANR FROM ADRESSEN WHERE NAME LIKE '"+"Ba"+"%';"; statt "Ba" möcht ich hier halt die Tastatureingabe. Und ich kriegs nicht hin Wäre froh wenn Ihr mir helfen könntet.... Danke! Gruß AJ Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Dragon8 Geschrieben 18. Februar 2009 Teilen Geschrieben 18. Februar 2009 Also so wie du es dir gerade vorstellst, wird es wohl eher nicht klappen, da du die Daten für die Autovervollständigung deines Textfeldes ja schon in den Vector schreibst kurz nachdem du das Textfeld erzeugt hast, die Eingabe vom Benutzer, nach der du ja suchen willst, kommt ja aber erst viel später. Deine Select-Abfrage auf die Datenbank müsste also in deine Suchmethode (quickSearch(String)) erfolgen und nicht schon vorher. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
dr.dimitri Geschrieben 18. Februar 2009 Teilen Geschrieben 18. Februar 2009 Hi, noch ein Tipp zum genrellen Ablauf: 1. Du solltest die Conjnection ausserhalb der Schleife herstellen und erst schließen wenn Sie wirklich nicht mehr benötigt wird (=Programm wird beendet). 2. Verwende ein PreparedStatement und kein Statement. Auch das sollte die Ausführung beschleunigen - vor allem wo's bei solchen Autovervollständigungen ja um 1/100stel Sekunden geht. Dim Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
AJRames Geschrieben 18. Februar 2009 Autor Teilen Geschrieben 18. Februar 2009 Hi und Danke Ja, habs jetz so hinbekommen das es läuft, nur leider wird bis jetzt bei jedem Tastendruck eine neue DB-Verbdingung aufgebaut...Das möchte ich noch verhindern....irgendwie. Das mit den PreparedStatements ist auf jedenfall ne gute idee, kannte die nicht, da ich noch nicht so fit bin! Danke schonmal! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
dr.dimitri Geschrieben 18. Februar 2009 Teilen Geschrieben 18. Februar 2009 Das möchte ich noch verhindern....irgendwie. Indem Du, wie allgemein üblich, Logik, Oberfläche und Datenbankzugriffe trennst. Schreib Dir eine Klasse, die dafür zuständig ist eine Connection aufzubauen und die deine Datenbankaufrufe kapselt. Dim Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
AJRames Geschrieben 19. Februar 2009 Autor Teilen Geschrieben 19. Februar 2009 Also ich häng momentan an dem Punkt nicht bei jedem Tastendruck eine Verbindung herzustellen. Hab jetzt die Klasse Verb um die Verbindung zu schaffen, dich habe ich ausgelagert: import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class Verb { public Connection con = null; public void verbinden(){ try { Class.forName("org.hsqldb.jdbcDriver"); } catch (Exception e) { System.out.println("ERROR: failed to load HSQLDB JDBC driver."); e.printStackTrace(); } try { con = DriverManager.getConnection( "jdbc:hsqldb:hsql://192.168.0.3/TrinityTestAJ", "sa", ""); } catch (SQLException e) { System.out.println("Keine Verbindung!"); } } } in der DROP hab ich halt das hier in der Variablendeklaration: private Verb v = new Verb(); Und test2 sieht jetz so aus: public DROP test2() throws SQLException { v.verbinden(); PreparedStatement ps = v.con.prepareStatement("SELECT NAME FROM ADRESSEN WHERE NAME LIKE '"+getText()+"%';"); ResultSet res = ps.executeQuery(); while (res.next()) { this.addData(res.getString("NAME")); } res.close(); v.con.close(); ps.close(); return this; } Die Verbindung wird logischerweise immernoch hergestellt...es ist halt so schöner und ich hab PreparedStatements benutzt (ich hoff richtig). Wie mache ich das das ich die Connection in ner Privaten Variable speicher, damit die Verbindung nicht immer hergestellt wird...? Sorry, aber wie gesagt, ich bin totaler neuling in dem Gebiet und die "proffessionellen" feinheiten von Java hab ich auch noch nicht so raus... Ist grad echt depremierend das ichs net hinbekomm des zeug so hinzukriegen das es effizient läuft Ich hoff es entspricht schon ein wenig dem wie du dir das vorstellst dim. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Dragon8 Geschrieben 19. Februar 2009 Teilen Geschrieben 19. Februar 2009 In dem du, wie du schon sagtest, deine Verbindung auf privat setzt und auf das Attribut über eine Methode zugreifst. In dieser Methode kontrollierst du dann einfach ob dein Connection-Objekt noch null ist oder die Connection geschlossen wurde (Connection#isClosed()). Wenn dies der Fall ist erzeugst du ein neues Connection-Objekt und weist das deinem Klassenattribut zu und gibst dieses Attribut zurück, wenn das nicht der Fall ist, gibst du einfach das Attribut zurück, da dies ja eine geöffnete Verbindung ist. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.