Zum Inhalt springen

Hilfe bei Datenbankabfrage mit KeyListener


AJRames

Empfohlene Beiträge

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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!

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...