# Probleme mit Datenbankzeiger



## Jomama09 (20. Feb 2010)

Bin noch Anfänger und habe ein Paar Probleme mit meiner kleinen Adressdatenbank.

Ich möchte unten in der Bearbeitungsgui anzeigen lassen ,welcher Datensatz ausgewählt ist von Datensätzen.  etwa so   Datensatz 1 von 12.
Dann habe ich ein weiteres Problem mit der Gui. Wenn ich am Ende / oder Anfang angekommen bin muss ich 2x in die andere Richtung drücken damit die Datensätze sich wieder weiter bewegen.
Laut Googlen soll dies mit isLast() und isFirst() behoben werden können ? Habe ich aber leider bisher nicht hinbekommen. Wäre Super wenn ihr mir helfen könntet. Als Anlage mein Code wo die Änderung rein müsste.


```
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.sql.Connection;
import java.sql.ResultSet;

import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;

public class BearbeitenEintrag extends JDialog {
	//automatisch über Eclipse erzeugt
	private static final long serialVersionUID = 2674865770208476234L;
	
	//für die Eingabefelder
	private JTextField name, nachname, strasse, plz, ort, telefon;
	//für die Anzeige
	private JLabel nummer,datensatz;

	//für die Aktionen
	private MeineAktionen loeschenAct, vorAct, zurueckAct, startAct, endeAct, aktualisierenAct;
	
	//für die Verbindung
	private Connection verbindung;
	private ResultSet ergebnisMenge;
	
	//für die Abfrage
	private String sqlAbfrage;
	
	//eine innere Klasse für die Aktionen
	class MeineAktionen extends AbstractAction {
		//automatisch über Eclipse ergänzt
		private static final long serialVersionUID = 8673560298548765044L;

		//der Konstruktor 
		public MeineAktionen(String text, ImageIcon icon, String beschreibung, KeyStroke shortcut, String actionText) {
			//den Konstruktor der übergeordneten Klasse mit dem Text und dem Icon aufrufen
			super(text, icon);
			//die Beschreibung setzen für den Bildschirmtipp
			putValue(SHORT_DESCRIPTION, beschreibung);
			//den Shortcut
			putValue(ACCELERATOR_KEY, shortcut);
			//das ActionCommand
			putValue(ACTION_COMMAND_KEY, actionText);
		}
		
		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getActionCommand().equals("vor"))
				ganzVor();
			if (e.getActionCommand().equals("zurueck"))
				ganzZurueck();
			if (e.getActionCommand().equals("einenvor"))
				einenVor();
			if (e.getActionCommand().equals("einenzurueck"))
				einenZurueck();
			if (e.getActionCommand().equals("loeschen"))
				loeschen();
			if (e.getActionCommand().equals("aktualisieren"))
				aktualisieren();
		}
	}
	
	//die innere Klasse für die Fenster-Ereignisse
	class FensterListener extends WindowAdapter {
		@Override
		public void windowClosing(WindowEvent e) {
			super.windowClosing(e);
			//die Datenbankverbindung trennen
			//ergebnisMenge und verbindung sind Variablen der äußeren Klasse 
			try {
				BearbeitenEintrag.this.ergebnisMenge.close();
				BearbeitenEintrag.this.verbindung.close();
				MiniDBTools.schliessenDB("jdbc:derby:");
			}
			catch(Exception exc) {
				JOptionPane.showMessageDialog(null, "Problem: \n" + exc.toString());
			}
		}
	}
	
	//der Konstruktor der Klasse BearbeitenEintrag
	public BearbeitenEintrag(JFrame parent, boolean modal) {
		super(parent, modal);
		setTitle("Einträge bearbeiten");
		
		//wir nehmen ein Borderlayout
		setLayout(new BorderLayout());
		//die Aktionen erstellen
		loeschenAct = new MeineAktionen("Datensatz löschen", 
				new ImageIcon("icons/Delete24.gif"), 
				"Löscht den aktuellen Datensatz", 
				null,
				"loeschen");
		vorAct = new MeineAktionen("Einen Datensatz weiter", 
				new ImageIcon("icons/Forward24.gif"), 
				"Blättert einen Datensatz weiter", 
				null, 
				"einenvor");
		zurueckAct = new MeineAktionen("Einen Datensatz zurück", 
				new ImageIcon("icons/Back24.gif"), 
				"Blättert einen Datensatz zurück", 
				null, 
				"einenzurueck");
		startAct = new MeineAktionen("Zum ersten Datensatz",
				new ImageIcon("icons/Front24.gif"), 
				"Geht zum ersten Datensatz", 
				null, 
				"vor");
		endeAct = new MeineAktionen("Zum letzten Datensatz", 
				new ImageIcon("icons/End24.gif"), 
				"Geht zum letzten Datensatz", 
				null, 
				"zurueck");
		aktualisierenAct = new MeineAktionen("Änderungen speichern", 
				new ImageIcon("icons/Save24.gif"), 
				"Speichert Änderungen am aktuellen Datensatz", 
				null, 
				"aktualisieren");
		
		//die Symbolleiste oben einfügen
		add(symbolleiste(), BorderLayout.NORTH);

		//die Oberfläche erstellen und einfügen
		add(initGui(), BorderLayout.CENTER);
		
		//zuerst nehmen wir alle Einträge aus der Tabelle adressen
		sqlAbfrage = "SELECT * FROM adressen";
		//diese Abfrage wählt nur alle Müllers aus
		//sqlAbfrage = "SELECT * FROM adressen WHERE nachname = 'Müller'";
		
		//die Datenbankverbindung herstellen
		initDB();
		
		//die Verbindung mit dem Listener des Fensters herstellen
		addWindowListener(new FensterListener());
		
		//packen und anzeigen
		pack();
		setVisible(true);
		//Standard-Operation setzen
		//hier den Dialog ausblenden und löschen
		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
	}
	
	//fügt die Felder in ein Panel ein und liefert das Panel zurück
	private JPanel initGui() {
		JPanel tempPanel = new JPanel();
		//im GridLayout mit zwei Spalten
		tempPanel.setLayout(new GridLayout(0,2));
		//für die Nummer (nur Anzeige)
		tempPanel.add(new JLabel("ID-Nummer:"));
		nummer = new JLabel();
		tempPanel.add(nummer);
		//für die anderen Felder
		tempPanel.add(new JLabel("Vorname:"));
		name = new JTextField();
		tempPanel.add(name);
		tempPanel.add(new JLabel("Nachname:"));
		nachname = new JTextField();
		tempPanel.add(nachname);
		tempPanel.add(new JLabel("Strasse:"));
		strasse = new JTextField();
		tempPanel.add(strasse);
		tempPanel.add(new JLabel("PLZ:"));
		plz = new JTextField();
		tempPanel.add(plz);
		tempPanel.add(new JLabel("Ort:"));
		ort = new JTextField();
		tempPanel.add(ort);
		tempPanel.add(new JLabel("Telefon:"));
		telefon = new JTextField();
		tempPanel.add(telefon);
		
		// Neu hinzugefügt für die Anzeige vom Datensatz Labels
		tempPanel.add(new JLabel("Datensatz"));
		datensatz = new JLabel();
		tempPanel.add(datensatz);
		//zurückgeben
		return tempPanel;
	}
	
	//die Symbolleiste erzeugen und zurückgeben
	private JToolBar symbolleiste() {
		JToolBar leiste = new JToolBar();
		//die Symbole über die Aktionen einbauen
		leiste.add(loeschenAct);
		leiste.add(aktualisierenAct);
		//Abstand einbauen
		leiste.addSeparator();
		leiste.add(startAct);
		leiste.add(zurueckAct);
		leiste.add(vorAct);
		leiste.add(endeAct);
		
		//die komplette Leiste zurückgeben
		return (leiste);
	}
	
	//die Verbindung zur Datenbank herstellen
	private void initDB() {
		try{
			//Verbindung herstellen und Ergebnismenge beschaffen
			verbindung=MiniDBTools.oeffnenDB("org.apache.derby.jdbc.EmbeddedDriver", "jdbc:derby:adressenDB");
			ergebnisMenge = MiniDBTools.liefereErgebnis(verbindung, sqlAbfrage);
			if (ergebnisMenge.next()) 
				datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}

	//die Methode liest die Daten und schreibt sie in die Felder
	private void datenLesen() {
		try {
			nummer.setText(Integer.toString(ergebnisMenge.getInt(1)));
			name.setText(ergebnisMenge.getString(2));
			nachname.setText(ergebnisMenge.getString(3));
			strasse.setText(ergebnisMenge.getString(4));
			plz.setText(ergebnisMenge.getString(5));
			ort.setText(ergebnisMenge.getString(6));
			telefon.setText(ergebnisMenge.getString(7));
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}

	//die Methode geht zum ersten Datensatz
	private void ganzVor() {
		try {
			//ganz nach vorne gehen
			ergebnisMenge.first();
			datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}

	//die Methode geht zum letzten Datensatz
	private void ganzZurueck() {
		try {
			//ganz nach hinten gehen
			ergebnisMenge.last();
			datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
}

	//die Methode geht einen Datensatz weiter
	private void einenVor() {
		try {
			//gibt es noch einen Datensatz?
			if (ergebnisMenge.next())
				datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}
	
	//die Methode geht einen Datensatz zurück
	private void einenZurueck() {
		try{
			//gibt es noch einen Datensatz davor?
			if (ergebnisMenge.previous()) 
				datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}
	
	//die Methode löscht einen Datensatz
	private void loeschen() {
		try {
			//wir müssen uns merken, wo wir sind
			int position;
			position = ergebnisMenge.getRow();
			//den Eintrag löschen
			ergebnisMenge.deleteRow();
        	//Ergebnismenge schließen
	        ergebnisMenge.close();
	        // und neu öffnen
			ergebnisMenge = MiniDBTools.liefereErgebnis(verbindung, sqlAbfrage);
			
			//und wieder zur "alten" Position gehen
			ergebnisMenge.absolute(position);
			//stehen wir jetzt hinter dem letzten?
			if (ergebnisMenge.isAfterLast())
				//dann zum letzten gehen
				ergebnisMenge.last();
			//die Daten neu lesen
			datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}

	//die Methode aktualisiert einen Eintrag
	private void aktualisieren() {
		try {
			//wir müssen uns merken, wo wir sind
			int position;
			position = ergebnisMenge.getRow();
			
			//die Daten aktualisieren
        	ergebnisMenge.updateString(2, name.getText());
        	ergebnisMenge.updateString(3, nachname.getText());
        	ergebnisMenge.updateString(4, strasse.getText());
        	ergebnisMenge.updateString(5, plz.getText());
        	ergebnisMenge.updateString(6, ort.getText());
        	ergebnisMenge.updateString(7, telefon.getText());   	
        	//den Datensatz aktualisieren
        	ergebnisMenge.updateRow();
        	//Ergebnismenge schließen
	        ergebnisMenge.close();
	        // und neu öffnen
			ergebnisMenge = MiniDBTools.liefereErgebnis(verbindung, sqlAbfrage);
			//und wieder zur "alten" Position gehen
			ergebnisMenge.absolute(position);
			//die Daten neu lesen
			datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}
}
```


----------



## Jomama09 (20. Feb 2010)

Habe das korrekte Anzeigen mit der Methode isLast / isFirst jetzt gelösst.
Wäre Super wenn mir einer helfen könnte mit dem Label zum Anzeigen der Datensatzfolge.

Datensatz 1 / 12 z.B. Wie kann ich das bewerkstelligen. Habe ja bereits ein Label für den Namen
eingefügt. Datensatz  und ein label (datensatz) wo ich gerne bei jeder Änderung aktualisieren würde.


----------



## Jomama09 (20. Feb 2010)

Habe das korrekte Anzeigen mit der Methode isLast / isFirst jetzt gelösst.
Wäre Super wenn mir einer helfen könnte mit dem Label zum Anzeigen der Datensatzfolge.

Datensatz 1 / 12 z.B. Wie kann ich das bewerkstelligen. Habe ja bereits ein Label für den Namen
eingefügt. Datensatz  und ein label (datensatz) wo ich gerne bei jeder Änderung aktualisieren würde.


----------



## eRaaaa (20. Feb 2010)

Naja mit getRow() solltest du an die aktuelle Zeile/Datensatznummer kommen

Um die Gesamtanzahl zu erhalten ... mhm, entweder einen extra SQL-Query loslassen (so wie z.B. SELECT COUNT(*)) oder am Anfang mal den Zeiger ans Ende  setzen, getRow() aufrufen und dann wieder an den Anfang setzen:

```
ergebnisMenge.last();
int count = ergebnisMenge.getRow();
ergebnisMenge.beforeFirst();
```


----------



## Jomama09 (20. Feb 2010)

Hi Basti,

kenne mich mit SQL leider so gut wie garnicht aus.
Für dich scheint das recht einfach zu sein, aber ich bin leider noch in meinem JAVA Studium
und Datenbanken ist halt ein Thema für sich.

Was könnte ich das denn verwenden wenn ich in einem Label diese Daten anzeigen will.
Label "Datensatz" und für das Ergebnis JLabel "datensatz" habe ich ja schon angelegt.

Nur wie bekomme ich das Ergebnis und das dann noch in das JLabel ???

Gruss Josef


----------



## eRaaaa (20. Feb 2010)

Zeile 38: private int rowCount;
Zwischen Zeile 214 und 215 einfügen:

```
ergebnisMenge.last();
rowCount = ergebnisMenge.getRow(); 
ergebnisMenge.beforeFirst();
```

somit steht dann in rowCount die Gesamtanzahl.

Und in deiner datenLesen() Methode kannst du einfach mit ergebnisMenge.getRow(); den "aktuellen Datensatz" bestimmen.
Also dann datensatz.setText(ergebnisMenge.getRow()+"/"+rowCount);


----------



## Jomama09 (20. Feb 2010)

Super danke werde ich gleich ausprobieren.

Vielen Dank für deine schnelle Hilfe.

Schönen Samstag noch.


----------



## Jomama09 (20. Feb 2010)

Hallo Leute,

könnt ihr bitte noch mal schauen, leider bekomme ich jetzt immer eine NullPointer Exception. Leider weiss ich nicht warum.
So wie ich das sehe habe ich alle vorgeschlagenen Änderungen so wie angegeben vorgenommen. 
Was mir noch eingefallen ist, das ich wenn ein Datensatz gelöscht wird auch noch aktualisieren muss, da ja dann die vorhandenen
Datensätze.
Wäre Super wenn ich noch einen Tip hinweis bekommen könnte.

[Java]
package de.fernschulen.minidb;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.sql.Connection;
import java.sql.ResultSet;

import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;

public class BearbeitenEintrag extends JDialog {
	//automatisch über Eclipse erzeugt
	private static final long serialVersionUID = 2674865770208476234L;

	//für die Eingabefelder
	private JTextField name, nachname, strasse, plz, ort, telefon;
	//für die Anzeige
	private JLabel nummer,datensatz;

	//für die Aktionen
	private MeineAktionen loeschenAct, vorAct, zurueckAct, startAct, endeAct, aktualisierenAct;

	//für die Verbindung
	private Connection verbindung;
	private ResultSet ergebnisMenge;

	// Counter zum Zählen der Datensätze
	private int rowCount;
	//für die Abfrage
	private String sqlAbfrage;

	//eine innere Klasse für die Aktionen
	class MeineAktionen extends AbstractAction {
		//automatisch über Eclipse ergänzt
		private static final long serialVersionUID = 8673560298548765044L;

		//der Konstruktor 
		public MeineAktionen(String text, ImageIcon icon, String beschreibung, KeyStroke shortcut, String actionText) {
			//den Konstruktor der übergeordneten Klasse mit dem Text und dem Icon aufrufen
			super(text, icon);
			//die Beschreibung setzen für den Bildschirmtipp
			putValue(SHORT_DESCRIPTION, beschreibung);
			//den Shortcut
			putValue(ACCELERATOR_KEY, shortcut);
			//das ActionCommand
			putValue(ACTION_COMMAND_KEY, actionText);
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getActionCommand().equals("vor"))
				ganzVor();
			if (e.getActionCommand().equals("zurueck"))
				ganzZurueck();
			if (e.getActionCommand().equals("einenvor"))
				einenVor();
			if (e.getActionCommand().equals("einenzurueck"))
				einenZurueck();
			if (e.getActionCommand().equals("loeschen"))
				loeschen();
			if (e.getActionCommand().equals("aktualisieren"))
				aktualisieren();
		}
	}

	//die innere Klasse für die Fenster-Ereignisse
	class FensterListener extends WindowAdapter {
		@Override
		public void windowClosing(WindowEvent e) {
			super.windowClosing(e);
			//die Datenbankverbindung trennen
			//ergebnisMenge und verbindung sind Variablen der äußeren Klasse 
			try {
				BearbeitenEintrag.this.ergebnisMenge.close();
				BearbeitenEintrag.this.verbindung.close();
				MiniDBTools.schliessenDB("jdbc:derby:");
			}
			catch(Exception exc) {
				JOptionPane.showMessageDialog(null, "Problem: \n" + exc.toString());
			}
		}
	}

	//der Konstruktor der Klasse BearbeitenEintrag
	public BearbeitenEintrag(JFrame parent, boolean modal) {
		super(parent, modal);
		setTitle("Einträge bearbeiten");

		//wir nehmen ein Borderlayout
		setLayout(new BorderLayout());
		//die Aktionen erstellen
		loeschenAct = new MeineAktionen("Datensatz löschen", 
				new ImageIcon("icons/Delete24.gif"), 
				"Löscht den aktuellen Datensatz", 
				null,
				"loeschen");
		vorAct = new MeineAktionen("Einen Datensatz weiter", 
				new ImageIcon("icons/Forward24.gif"), 
				"Blättert einen Datensatz weiter", 
				null, 
				"einenvor");
		zurueckAct = new MeineAktionen("Einen Datensatz zurück", 
				new ImageIcon("icons/Back24.gif"), 
				"Blättert einen Datensatz zurück", 
				null, 
				"einenzurueck");
		startAct = new MeineAktionen("Zum ersten Datensatz",
				new ImageIcon("icons/Front24.gif"), 
				"Geht zum ersten Datensatz", 
				null, 
				"vor");
		endeAct = new MeineAktionen("Zum letzten Datensatz", 
				new ImageIcon("icons/End24.gif"), 
				"Geht zum letzten Datensatz", 
				null, 
				"zurueck");
		aktualisierenAct = new MeineAktionen("Änderungen speichern", 
				new ImageIcon("icons/Save24.gif"), 
				"Speichert Änderungen am aktuellen Datensatz", 
				null, 
				"aktualisieren");

		//die Symbolleiste oben einfügen
		add(symbolleiste(), BorderLayout.NORTH);

		//die Oberfläche erstellen und einfügen
		add(initGui(), BorderLayout.CENTER);

		//zuerst nehmen wir alle Einträge aus der Tabelle adressen
		sqlAbfrage = "SELECT * FROM adressen";
		//diese Abfrage wählt nur alle Müllers aus
		//sqlAbfrage = "SELECT * FROM adressen WHERE nachname = 'Müller'";

		//die Datenbankverbindung herstellen
		initDB();

		//die Verbindung mit dem Listener des Fensters herstellen
		addWindowListener(new FensterListener());

		//packen und anzeigen
		pack();
		setVisible(true);
		//Standard-Operation setzen
		//hier den Dialog ausblenden und löschen
		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
	}

	//fügt die Felder in ein Panel ein und liefert das Panel zurück
	private JPanel initGui() {
		JPanel tempPanel = new JPanel();
		//im GridLayout mit zwei Spalten
		tempPanel.setLayout(new GridLayout(0,2));
		//für die Nummer (nur Anzeige)
		tempPanel.add(new JLabel("ID-Nummer:"));
		nummer = new JLabel();
		tempPanel.add(nummer);
		//für die anderen Felder
		tempPanel.add(new JLabel("Vorname:"));
		name = new JTextField();
		tempPanel.add(name);
		tempPanel.add(new JLabel("Nachname:"));
		nachname = new JTextField();
		tempPanel.add(nachname);
		tempPanel.add(new JLabel("Strasse:"));
		strasse = new JTextField();
		tempPanel.add(strasse);
		tempPanel.add(new JLabel("PLZ:"));
		plz = new JTextField();
		tempPanel.add(plz);
		tempPanel.add(new JLabel("Ort:"));
		ort = new JTextField();
		tempPanel.add(ort);
		tempPanel.add(new JLabel("Telefon:"));
		telefon = new JTextField();
		tempPanel.add(telefon);

		// Neu hinzugefügt für die Anzeige vom Datensatz Labels
		tempPanel.add(new JLabel("Datensatz"));
		datensatz = new JLabel();
		tempPanel.add(datensatz);
		//zurückgeben
		return tempPanel;
	}

	//die Symbolleiste erzeugen und zurückgeben
	private JToolBar symbolleiste() {
		JToolBar leiste = new JToolBar();
		//die Symbole über die Aktionen einbauen
		leiste.add(loeschenAct);
		leiste.add(aktualisierenAct);
		//Abstand einbauen
		leiste.addSeparator();
		leiste.add(startAct);
		leiste.add(zurueckAct);
		leiste.add(vorAct);
		leiste.add(endeAct);

		//die komplette Leiste zurückgeben
		return (leiste);
	}

	//die Verbindung zur Datenbank herstellen
	private void initDB() {
		try{
			ergebnisMenge.last();
			rowCount = ergebnisMenge.getRow(); 
			ergebnisMenge.beforeFirst();
			//Verbindung herstellen und Ergebnismenge beschaffen
			verbindung=MiniDBTools.oeffnenDB("org.apache.derby.jdbc.EmbeddedDriver", "jdbc:derby:adressenDB");
			ergebnisMenge = MiniDBTools.liefereErgebnis(verbindung, sqlAbfrage);
			if (ergebnisMenge.next()) 
				datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}

	//die Methode liest die Daten und schreibt sie in die Felder
	private void datenLesen() {
		try {
			nummer.setText(Integer.toString(ergebnisMenge.getInt(1)));
			name.setText(ergebnisMenge.getString(2));
			nachname.setText(ergebnisMenge.getString(3));
			strasse.setText(ergebnisMenge.getString(4));
			plz.setText(ergebnisMenge.getString(5));
			ort.setText(ergebnisMenge.getString(6));
			telefon.setText(ergebnisMenge.getString(7));
			ergebnisMenge.getRow(); 
			datensatz.setText(ergebnisMenge.getRow()+"/"+rowCount); 
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}

	//die Methode geht zum ersten Datensatz
	private void ganzVor() {
		try {
			//ganz nach vorne gehen
			ergebnisMenge.first();
			datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}

	//die Methode geht zum letzten Datensatz
	private void ganzZurueck() {
		try {
			//ganz nach hinten gehen
			ergebnisMenge.last();
			datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
}

	//die Methode geht einen Datensatz weiter
	// Durch Erweiterung mit Methode isLast den Fehler beim Blättern behoben
	private void einenVor() {
		try {
			if(ergebnisMenge.isLast())
				aktualisieren();

			else

			if(ergebnisMenge.next())
			datenLesen();

		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}

	//die Methode geht einen Datensatz zurück
	// Durch Erweiterung mit Methode isFirst den Fehler beim Blättern behoben
	private void einenZurueck() {
		try{
			//gibt es noch einen Datensatz davor?
			if(ergebnisMenge.isFirst())
				aktualisieren();		
			else	
			if (ergebnisMenge.previous()) 
				datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}

	//die Methode löscht einen Datensatz
	private void loeschen() {
		try {
			//wir müssen uns merken, wo wir sind
			int position;
			position = ergebnisMenge.getRow();
			//den Eintrag löschen
			ergebnisMenge.deleteRow();
        	//Ergebnismenge schließen
	        ergebnisMenge.close();
	        // und neu öffnen
			ergebnisMenge = MiniDBTools.liefereErgebnis(verbindung, sqlAbfrage);

			//und wieder zur "alten" Position gehen
			ergebnisMenge.absolute(position);
			//stehen wir jetzt hinter dem letzten?
			if (ergebnisMenge.isAfterLast())
				//dann zum letzten gehen
				ergebnisMenge.last();
			//die Daten neu lesen
			datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}

	//die Methode aktualisiert einen Eintrag
	private void aktualisieren() {
		try {
			//wir müssen uns merken, wo wir sind
			int position;
			position = ergebnisMenge.getRow();

			//die Daten aktualisieren
        	ergebnisMenge.updateString(2, name.getText());
        	ergebnisMenge.updateString(3, nachname.getText());
        	ergebnisMenge.updateString(4, strasse.getText());
        	ergebnisMenge.updateString(5, plz.getText());
        	ergebnisMenge.updateString(6, ort.getText());
        	ergebnisMenge.updateString(7, telefon.getText());   	
        	//den Datensatz aktualisieren
        	ergebnisMenge.updateRow();
        	//Ergebnismenge schließen
	        ergebnisMenge.close();
	        // und neu öffnen
			ergebnisMenge = MiniDBTools.liefereErgebnis(verbindung, sqlAbfrage);
			//und wieder zur "alten" Position gehen
			ergebnisMenge.absolute(position);
			//die Daten neu lesen
			datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}
}
[/code]


----------



## andiv (20. Feb 2010)

An welcher Stelle im Programm bekommst du denn die NullPointerException? Hast du denn schon den Debugger verwendet um die Stelle zu finden? Ohne diese Information ist es nicht ganz leicht den Fehler zu finden.

Außerdem halte ich es für guten Stil bei if, else, etc. grundsätzlich die geschweiften Klammern {} hinzuschreiben, auch wenn man nur eine Anweisung macht. Damit vermeidet man den ein oder anderen lästigen Fehler, wenn man später mal schnell eine zweite Anweisung hinzufügt und dann vergisst die Klammern hinzuschreiben.


----------



## Jomama09 (20. Feb 2010)

Danke für den Tip.
Das mit den Klammern muss ich mir noch angewöhnen.

Werde sehen das ich das mit dem Debugger mal probiere.

Gruss Jupp


----------



## Jomama09 (21. Feb 2010)

Hi Leute habe es fast geschafft ,sind nur noch zwei kleine Macken drin.
Am Anfang wird der Datensatz noch falsch angezeigt .   Datensatz 1 / 0 ,sobald ich einen vor blättere zeigt er mir z.B.
1 / 3 . Das sollte schon beim Start da stehen, anscheinend weiss rowCount am Anfang nicht die Gesamtzahl.

Und dann habe ich noch das Problem wenn ich einen Satz lösche das die Anzeige der Datensätze sofort aktualisiert wird.
Wenn ich die Gui schliesse und neustarte stimmt die Anzeige wieder.

Wäre super wenn ich hilfe bekommen könnte.
Denke folgende Codeabschnitte sind betroffen.


```
//die Verbindung zur Datenbank herstellen
	private void initDB() {
		try{
			//Verbindung herstellen und Ergebnismenge beschaffen
			verbindung=MiniDBTools.oeffnenDB("org.apache.derby.jdbc.EmbeddedDriver", "jdbc:derby:adressenDB");
			ergebnisMenge = MiniDBTools.liefereErgebnis(verbindung, sqlAbfrage);
			if (ergebnisMenge.next()) 
				datenLesen();
			// Hier wird die Variable rowCount gefüllt, die später abgefragt wird für die Datensatzanzeige
			ergebnisMenge.last();
			rowCount = ergebnisMenge.getRow(); 
			ergebnisMenge.beforeFirst();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}
```


```
//die Methode liest die Daten und schreibt sie in die Felder
	private void datenLesen() {
		try {
			nummer.setText(Integer.toString(ergebnisMenge.getInt(1)));
			name.setText(ergebnisMenge.getString(2));
			nachname.setText(ergebnisMenge.getString(3));
			strasse.setText(ergebnisMenge.getString(4));
			plz.setText(ergebnisMenge.getString(5));
			ort.setText(ergebnisMenge.getString(6));
			telefon.setText(ergebnisMenge.getString(7));
			// Ergänzung zum ermitteln der Datensätze und zum Anzeigen in der Gui
			ergebnisMenge.getRow();
			datensatz.setText(ergebnisMenge.getRow()+"/"+rowCount); 
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}
```


```
//die Methode löscht einen Datensatz
	private void loeschen() {
		try {
			//wir müssen uns merken, wo wir sind
			int position;
			position = ergebnisMenge.getRow();
			//den Eintrag löschen
			ergebnisMenge.deleteRow();
        	//Ergebnismenge schließen
	        ergebnisMenge.close();
	        // und neu öffnen
			ergebnisMenge = MiniDBTools.liefereErgebnis(verbindung, sqlAbfrage);
			
			//und wieder zur "alten" Position gehen
			ergebnisMenge.absolute(position);
			//stehen wir jetzt hinter dem letzten?
			if (ergebnisMenge.isAfterLast())
				//dann zum letzten gehen
				ergebnisMenge.last();
			//die Daten neu lesen
			datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}
```

Weiter oben hatte ich ja bereits mal alles eingestellt aus dieser Klasse, aber das ist ja recht viel. Die Änderungen müssten so wie ich denke hier gemacht werden. 

Wäre Super wenn einer helfen könnte.


----------



## andiv (21. Feb 2010)

Zum ersten Problem, die Reihenfolge ist bei dir im Moment folgendermaßen:

```
//...
            ergebnisMenge.getRow();
            datensatz.setText(ergebnisMenge.getRow()+"/"+rowCount); 
//...
            ergebnisMenge.last();
            rowCount = ergebnisMenge.getRow(); 
            ergebnisMenge.beforeFirst();
//...
```
Wenn du dir das anschaust sollte eigentlich klar sein, warum getRow() / rowCount dir beim ersten mal den falschen Wert liefert. Berechne einfach die Variable rowCount bevor du die Daten liest und anzeigst.

Dein zweites Problem hab ich nicht verstanden, willst du jetzt dass sich die Anzeige NICHT gleich aktualisiert oder willst du das, aber sie tut es im Moment noch nicht?


----------



## Jomama09 (21. Feb 2010)

Ich möchte das beim löschen aktualisiert wird.
Leider klappt es im Moment nicht direkt.

Deinen ersten Tip teste ich gleich mal.


----------



## andiv (21. Feb 2010)

Also das einzige was mir gerade noch auffällt ist, dass du rowCount beim Löschen um eins erniedrigen solltest, sonst brauchst du dich nicht wundern, wenn sich die angezeigte Gesamtzahl nicht ändert.


----------



## Jomama09 (21. Feb 2010)

Das mit dem Datensatz korrigieren nach dem löschen habe ich nun gelösst.

rowCount = rowCount - 1 ;

das hätte mir selbst einfallen sollen. Naja halt vor lauter Bäume den Wald nicht mehr gesehen.:toll:

Aber das mit dem korrekten Anzeigen der Datensätze am Anfang.  1 / 5 z.B. bekomme ich nicht hin.
Verstehe nicht warum die Reihenfolge falsch sein soll ???? :bahnhof:

Wie sollte ich das denn ändern ???
Wäre dann ja mit meinen Anforderungen fertig. Meiner Meinung nach passt es, nur das Programm zeigt mir was anderes ;(


----------



## andiv (21. Feb 2010)

```
//die Verbindung zur Datenbank herstellen
	private void initDB() {
		try{
			//Verbindung herstellen und Ergebnismenge beschaffen
			verbindung=MiniDBTools.oeffnenDB("org.apache.derby.jdbc.EmbeddedDriver", "jdbc:derby:adressenDB");
			ergebnisMenge = MiniDBTools.liefereErgebnis(verbindung, sqlAbfrage);

			// rowCount vor Verwendung füllen
			ergebnisMenge.last();
			rowCount = ergebnisMenge.getRow(); 
			ergebnisMenge.beforeFirst();

			if (ergebnisMenge.next()) 
// Die Methode datenLesen verwendet die Variable rowCount
				datenLesen();
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}
```


```
//die Methode liest die Daten und schreibt sie in die Felder
	private void datenLesen() {
		try {
			nummer.setText(Integer.toString(ergebnisMenge.getInt(1)));
			name.setText(ergebnisMenge.getString(2));
			nachname.setText(ergebnisMenge.getString(3));
			strasse.setText(ergebnisMenge.getString(4));
			plz.setText(ergebnisMenge.getString(5));
			ort.setText(ergebnisMenge.getString(6));
			telefon.setText(ergebnisMenge.getString(7));
			// Ergänzung zum ermitteln der Datensätze und zum Anzeigen in der Gui
			ergebnisMenge.getRow();
// Hier wird rowCount verwendet!
			datensatz.setText(ergebnisMenge.getRow()+"/"+rowCount); 
		}
		catch(Exception e) {
			JOptionPane.showMessageDialog(this, "Problem: \n" + e.toString());
		}
	}
```

So müsste das meiner Meinung nach passen.

Ach und statt rowCount = rowCount - 1; kann man auch einfach rowCount--; schreiben


----------



## Jomama09 (22. Feb 2010)

Danke !!!

Super einfach Klasse. :applaus:
Ja hatte ich vergessen mit -- geht es ja auch eins runter ++ gleich eins rauf.
Ja hatte leider die Reihenfolge etwas durcheinander gebracht.

Jetzt passt es.

Netten Gruss aus Köln

Josef


----------



## Rim123! (25. Sep 2021)

Hallo grüß an alle.
Können Sie mir nur sagen wo ich dass rowCount--; schreiben sollte?
Danke im Voraus


----------



## Oneixee5 (25. Sep 2021)

Du kannst es dir doch auch einfach machen. Lass dir die Werte einfach vom SQL geben.

```
select
  row_number() over (order by t.ID) ROW_NUM,
  count(t.ID) over () ROW_COUNT,
  t.ID,
  t...
from <TABLE> t
order by t.ID
```
Die Sortierung: order by t.ID ist nur als Beispiel gedacht und soll die Funktionsweise verdeutlichen. Eine Adresse würde man evtl. nach PLZ + Ort sortieren. ROW_NUM ist die aktuelle Zeile, ROW_COUNT ist die Gesamtzahl der Zeilen.
SQL ist schnell und mächtig, solche Dinge kann man sich so einfach und komfortabel machen wie möglich. Die verwendest einfach nur JDBC und bist deshalb auch an keinerlei DTO's gebunden.


----------



## mrBrown (26. Sep 2021)

Rim123! hat gesagt.:


> Hallo grüß an alle.
> Können Sie mir nur sagen wo ich dass rowCount--; schreiben sollte?
> Danke im Voraus


Mach für deine Frage doch bitte einen eigenen Thread auf und kaper' keinen 10 Jahre alten


----------

