# NullPointerException



## zilti (17. Okt 2007)

Ich rufe von einer Klasse eine neue Instanz von der Klasse ReadUserlist auf, dann übergebe ich der Klasse die Datenklasse UserDataClass und starte dann ReadUserlist als Thread. ReadUserlist schreibt Daten in die UserDataClass.
Der Klasse UserListModel übergebe ich ebenfalls die UserDataClass, und starte sie dann als TableModel einer JTable. Diese UserListModel ruft Daten von der UserDataClass ab:

```
public Object getValueAt(int arg0, int arg1) {
		// TODO Auto-generated method stub
		UserDataClass userdata = new UserDataClass();
		switch(arg1)
		{
		case 0: return userdata.getRow(arg0)[0];
		case 1: return userdata.getRow(arg0)[1];
		case 2: return userdata.getRow(arg0)[2];
		default: return null;
		}
	}
```
Die UserDataClass liefert dabei das Ergebnis des folgenden Codes ab:

```
public String[] getRow(int row)
	{
		String[] ret = new String[] { username[row], clan[row], ""+time[row] };
		return ret;
	}
```
Dabei kommt es immer zu einer NullPointerException. Wieso?


----------



## Murray (17. Okt 2007)

Weil username, clan und/oder row zu diesem Zeitpunkt null sind?

//EDIT: statt row war natürlich time gemeint; row kann als primitiver Typ nicht null, sondern nur 0 sein, und das wäre unkritisch. Richtig also:
Weil username, clan und/oder *time* zu diesem Zeitpunkt null sind?


----------



## SlaterB (17. Okt 2007)

oder arg1 > 2?


----------



## zilti (17. Okt 2007)

arg1>2 kann nicht sein, es hat ja nicht mehr Spalten.
Aber wie kann ich verhindern, dass von UserDataClass Daten abgerufen werden, die nicht existieren? Mindestens ein Eintrag ist auf jeden Fall vorhanden.


----------



## André Uhres (17. Okt 2007)

In getValueAt solltest du  keine neue Instanz von UserDataClass erzeugen,
sondern die Instanz benutzen, die du dem Model übergeben hast.


----------



## SlaterB (17. Okt 2007)

also den Aufruf von der JTable kannst du nicht verhindern, aber null oder "" zurückgegeben, wenn keine Daten vorhanden sind:

if (userdata== null || userdata.getRow(arg0) == null || userdata.getRow(arg0).length <= arg1) {
return null;
}
return userdata.getRow(arg0)[arg1];


----------



## zilti (17. Okt 2007)

Ich habe jetzt beim UserListModel folgendes von dir geschriebene eingefügt:

```
if (userdata== null || userdata.getRow(arg0) == null || userdata.getRow(arg0).length <= arg1) {
return null;
}
return userdata.getRow(arg0)[arg1];
```
Und in der UserDataClass steht jetzt:

```
public String[] getRow(int row)
	{
		String[] ret = null; 
		if (username.length > row) 
		{
			ret = new String[] { "", "", "" };
			return ret;
		} 
		else
		{
			ret = new String[] { username[row], clan[row], ""+time[row] };
			return ret;
		}
	}
```
Vorher sah man den Eintrag noch in der JTable noch, trotz den Fehlermeldungen, aber jetzt ist da einfach ne leere Zeile. Aber die Fehlermeldung ist immer noch.


----------



## SlaterB (17. Okt 2007)

> if (username.length > row) 
eher
if (username.length <= row) 

für clan genauso

--------

> Aber die Fehlermeldung ist immer noch.

hast du eigentlich einen StackTrace dazu?
hat das überhaupt was mit deinem Code zu tun?
gehts, wenn du testweise

public Object getValueAt(int arg0, int arg1) { 
return "Rababerkuchen";
}
verwendest?


----------



## zilti (17. Okt 2007)

Hier ist die Ausgabe:


> Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
> at javax.swing.JTable.prepareRenderer(Unknown Source)
> at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
> at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
> ...


Die kommt auch bei deinem Test.
Immerhin habt ihr mir schon so weit geholfen, dass jetzt nur noch das kommt - vorher war noch ne Zeilennummer drin.


----------



## SlaterB (17. Okt 2007)

nun ja, Zeilennummer ist ja besser 

also das klingt nun nach allgemeinen Aufbau-Fehlern wie falsche Column-Anzahl in irgendwelchen Models oder Änderungen nicht im AWT-Event-Thread duchgeführt oder ähnliches

dazu kann ich nix konkretes sagen, schon gar nicht ohne Code,
da wäre ein vollständiges möglichst kurzes Programm hilfreich,
die meisten von deinen eigenen Klassen brauchen nicht dabei sein,
möglichst durch Dummys wie 'Rababerkuchen' ersetzen,
aber der Fehler sollte natürlich auch im Beispiel noch auftreten 

schwierig sicherlich, vielleicht weiß wer anders so weiter


----------



## zilti (17. Okt 2007)

Erstmal danke für die Hilfe!
Ich suche noch ein bisschen und melde mich morgen wieder.


----------



## ToKaM OnE (18. Okt 2007)

Passwörter kannst du auch gut in einer Collection des Typs Propperties speicher.
Diese Kannst du sogar von java als xml abspeichern lassen und wieder einlesen.
Wenn du passwörter nicht in reinform haben willst, kannst du den hash von string 1 und string 2 vergleichen.
mfg tokam.

Falls du es machen möchtest und dabei nicht weiterkommst, bin ich für Rückfragen offen..


----------



## zilti (18. Okt 2007)

Wie kommst du jetzt auf Passwörter?
Danke für den Tipp, aber ich hab sie MD5-"Verschlüsselt", denn in der DB sind sies auch.


----------



## zilti (18. Okt 2007)

Ich bin noch am suchen. Mal ne Frage: Kann folgender Code einen NullPointerException auslösen?

```
private String[] username, clan;
	private long[] time;
	
	public void userdata(String[] username, String[] clan, long[] time)
	{
		this.username = new String[username.length];
		this.clan = new String[clan.length];
		this.time = new long[time.length];
		this.username = username;
		this.clan = clan;
		this.time = time;
	}
```


----------



## SlaterB (18. Okt 2007)

wenn die übergebenen Arrays null sind, ja,

welchen Sinn hat es eigentlich, erst ein neues Array zu erstellen:
this.username = new String[username.length]; 
und dann mit dem alten Array zu überschreiben?:
this.username = username;

das ist so als wenn du ein Auto geschenkt bekommst,
dir einen Auto-Parkplatz anlegst und dort ein neues Auto draufstellst
und 1 sec später dieses schöne neue Auto verschrottest um dann endlich das geschenkte Auto draufzustellen


----------



## Murray (18. Okt 2007)

Ja, wenn die Methode userdata in mindestens einem der drei Parameter null übergeben bekommt (das kann auch eine noch nicht initialisierte Referenz sein).

//EDIT: schon wieder zu langsam


----------



## zilti (18. Okt 2007)

Ach so, das ist also doch nicht nötig... Wollte bloss sicher sein, dass es nicht wegen zu kleinem Array-Index nicht geht.


----------



## Murray (18. Okt 2007)

zilti hat gesagt.:
			
		

> Wollte bloss sicher sein, dass es nicht wegen zu kleinem Array-Index nicht geht.


Wenn irgendwo ein Array-Index zu klein (also kleiner 0) oder zu groß (größer oder gleich der Array-Länge) ist, dann kommt keine NullPointerException, sondern eine ArrayIndexOutOfBoundsException.


----------



## André Uhres (18. Okt 2007)

http://www.java-forum.org/de/viewtopic.php?p=345229#345229


----------



## zilti (18. Okt 2007)

Muss schon sagen, der sinnvollste Link seit langem.
Was willst du damit sagen?


----------



## André Uhres (18. Okt 2007)

Wenn du in getValueAt immer wieder neue Instanzen der Datenklasse erzeugst, dann ist natürlich nie was drin. Denn der Thread, der die Daten reinspeisen soll, kennt diese Instanzen ja nicht.


----------



## maki (18. Okt 2007)

> Muss schon sagen, der sinnvollste Link seit langem.
> Was willst du damit sagen?


Kilck doch mal den link und lies Andrés Kommentar... dann denke drüber nach.

Ansonsten: So einen Fehler hättest du schon längst alleine gefunden wenn du ein Logging-Framework wie zB. log4j einsetzen würdest.


----------



## zilti (18. Okt 2007)

Ja, er schreibt, ich solle dort keine neue Instanz machen. Das hab ich längst schon korrigiert.


----------



## André Uhres (18. Okt 2007)

Wenn man nicht mehr weiter weiss, dann ist es vielleicht gut, 
mal ein einfaches Beispiel wie dieses zu nehmen:
http://www.java-forum.org/de/userfiles/user3690/DataFeed.jar
Der Quellcode ist im jar enthalten.
Es enthält die Datenklasse "STableRow", das Tablemodel "STableModel"
und den Runnable "STableLoad".


----------



## zilti (19. Okt 2007)

Ich hab jetzt versucht, mit dem internen Debugger von Eclipse zu debuggen, aber der ist die reinste Katastrophe, das ist der lausigste Debugger von den wenigen, die ich je gesehen habe!!
Der findet nach dem Debuggen nicht mal den Quellcode.
Was muss ich denn da angeben, wenn er sagt:"Edit source lookup path..."?


----------



## André Uhres (19. Okt 2007)

zilti hat gesagt.:
			
		

> ..Was muss ich denn da angeben, wenn er sagt:"Edit source lookup path..."?


Ich denke mal, dass du deine Logik wesentlich vereinfachen könntest. Dabei hilft auch kein Debuggen. 
Du hast ein funktionierendes Beispiel bekommen. Davon ausgehend, würde ich erstmal die Logik neu überdenken :wink:


----------



## zilti (19. Okt 2007)

Aber wie funzt denn nun das mit dem Debugger?


----------



## NTB (19. Okt 2007)

Du setzt irgendwo im Code einen Breakpoint, wo Du ihn haben möchtest, also etwa da, wo der Nullpointer kommt. Und dann startest Du per Debugger (F11). Dann bleibt er beim Breakpoint stehen und Du kannst schrittweise weitergehen (F6). Dabei kannst Du Dir dann die Inhalte der Variablen anschauen.

Alternativ kannst Du auch "Studentendebug" machen: Überall per System.out oder Loggingframework (z.B. Log4j) alle Variablen ausgeben.


----------



## maki (20. Okt 2007)

> Alternativ kannst Du auch "Studentendebug" machen: Überall per System.out oder Loggingframework (z.B. Log4j) alle Variablen ausgeben.


log4j ist einem Debugger in den meisten Fällen weit überlegen, in einem Debugger verliert man sich ganz schnell in den Details, vor allem, wenn es sich um komplexere Systeme handelt (zB Webanwendungen).

Auch kann mann nicht immer debuggen, EJBs zum Beispiel.
Mit log4j kann ich die Ausgabe genau steuern, anders als beim System.out.println, ich kann entscheiden welchen logginglevel ich von welcher Klasse sehen will, oder nicht.

Auch ist log4j richtig angewendet um einiges Performanter als ein System.out.

log4j kann man auch zur Laufzeit steuern, d.h. in der Produktivumgebung mal schnell die Debuggingausgaben einschalten 

Seit dem ich log4j verwende(5 Jahre), hab ich weniger als 10 mal Debuggen müssen 

Die meisten Fragen im Anfängerforum ("ich bekomme eine Exception..", "Mein Code funktionert nicht richtig...") würden einfach nicht gestellt werden, da die Leute selber in de lage wären ihre Fehler zu finden.

log4j ist eine gute Sache  und vor allem simpel, sollte eigentlich jeder verwenden  :toll:


----------



## zilti (21. Okt 2007)

Verdammt, ich gebs auf, das ist der reinste Horror, ich hab das ganze Programm neu geschrieben und hab den verdammten Müll immer noch.


----------



## zilti (21. Okt 2007)

```
/**
 * 
 */
package mainlayout;
import functions.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import java.util.*;
import java.util.Timer;

/**
 * @author Daniel Ziltener
 *
 */
public class Login extends JFrame implements ActionListener {

	JPasswordField password;
	JTextField username;
	JLabel infotext;
	/**
	 * 
	 */
	public Login() {
		// GridBagLayout erstellen
		JPanel content = new JPanel(new GridBagLayout());
		this.add(content);
		GridBagConstraints c = new GridBagConstraints();
		
		// ZEILE 1
		// Text, Zeile 1, Spalten 1 und 2
		infotext = new JLabel();
		infotext.setText("Bitte gib deine Login-Daten ein");
		c = new GridBagConstraints();
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 2;
		content.add(infotext, c);
		
		// ZEILE 2
		// Label "Username:", Zeile 2, Spalte 1
		c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 1;
		content.add(new JLabel("Username: "), c);
		
		// Textfeld username, Zeile 2, Spalte 2
		username = new JTextField(10);
		c = new GridBagConstraints();
		c.gridx = 1;
		c.gridy = 1;
		content.add(username, c);
		
		// ZEILE 3
		// Label "Passwort:", Zeile 3, Spalte 1
		c= new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 2;
		content.add(new JLabel("Passwort: "), c);
		
		// Passwortfeld password, Zeile 3, Spalte 2
		password = new JPasswordField(10);
		c = new GridBagConstraints();
		c.gridx = 1;
		c.gridy = 2;
		content.add(password, c);
		
		// ZEILE 4 (y = 3)
		// Loginknopf, Zeile 4, Spalte 1
		JButton login = new JButton("Login");
		login.setMnemonic(KeyEvent.VK_L);
		login.setActionCommand("Login");
		login.addActionListener(this);
		c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 3;
		content.add(login, c);
		
		// "Cancel"-Knopf, Zeile 4, Spalte 2
		JButton cancel = new JButton("Abbrechen");
		cancel.setMnemonic(KeyEvent.VK_A);
		cancel.setActionCommand("Cancel");
		cancel.addActionListener(this);
		c = new GridBagConstraints();
		c.gridx = 1;
		c.gridy = 3;
		content.add(cancel, c);
		
		// Abschliessen
		this.setPreferredSize(new Dimension(250, 150));
		this.setTitle("LyrionGameChannel - Login");
		this.pack();
		this.setVisible(true);
	}
	
	// Aktionsabfang
	public void actionPerformed(ActionEvent e)
	{
		if(e.getActionCommand() == "Login")
		{
			String convertedPass = null;
			// Passwort umwandeln
			infotext.setText("Passwort umwandeln");
			MD5 md5 = new MD5();
			convertedPass = md5.createHash(password.getText());

			// Verbindung zur Datenbank aufbauen
			infotext.setText("Mit Datenbank verbinden...");
			String connStr = "jdbc:mysql://217.26.52.18:3306/lyrionch_user?user=********&password=******";
			Connection conn = null;
			// Klasse registrieren und Verbindung öffnen
			infotext.setText("Verbinden und Treiber laden...");
			try {
				Class.forName("com.mysql.jdbc.Driver");
				conn = DriverManager.getConnection(connStr);
			} 
			catch (ClassNotFoundException e1) { e1.printStackTrace(); }
			catch (SQLException e1) { e1.printStackTrace(); }
			// Logindaten abrufen
			// Statement vorbereiten
			ResultSet rs = null;
			String getpw = null;
			String getclan = null;
			try
			{
				infotext.setText("Daten abrufen");
				PreparedStatement stmt = conn.prepareStatement("SELECT * FROM user WHERE Username=?");
				String stmt_add_1 = username.getText();
				stmt.setString(1, stmt_add_1);
				rs = stmt.executeQuery();
				rs.next();
				getpw = rs.getString("Passwort");
				getclan = rs.getString("Clan");
				conn.close();
			}
			catch(SQLException e1) { e1.printStackTrace(); }
			// Daten vergleichen
			if(getpw.equals(convertedPass))
			{
				infotext.setText("Passwort korrekt.");
				
				//		USER IN USERLISTE EINFÜGEN
				String[] raeume = { "lgc", "sat", "cantaria", "battleisle", "siedler4" };
				Statement stmt;
				for(String u : raeume)
				{
					connStr = new String("jdbc:mysql://217.26.52.18:3306/lyrionch_chat?user=lyrionch_zilti&password=tilsinow");
					try {
						conn = DriverManager.getConnection(connStr);
					} catch (SQLException e2) {
						// TODO Auto-generated catch block
						e2.printStackTrace();
					}
					rs = null;
					stmt = null;
					String statement = "SELECT * FROM online_" + u + " WHERE Username='" + username.getText() + "'";
					try {
						stmt = conn.createStatement();
						rs = stmt.executeQuery(statement);
						if(rs.next() == false)
						{
							statement = "INSERT INTO online_" + u + " (username, clan) VALUES ('" + username.getText() + "', '" + getclan + "')";
							stmt = conn.createStatement();
							stmt.executeUpdate(statement);
							conn.close();
						}
					} catch (SQLException e1) {	e1.printStackTrace(); }
				}
				//		TIMER ANLEGEN
				// Thread-Instanz anlegen
				Thread writeuserliste;
				WriteUserlist WriteUserlist = new WriteUserlist();
				WriteUserlist.set(username.getText(), getclan);
				// Ausführungszeiten festlegen
				writeuserliste = new Thread(WriteUserlist);
				writeuserliste.start();
				
				// 		FENSTER AUFRUFEN
				MainWindow MainWindow = new MainWindow(username.getText());
				this.setVisible(false);
				
			}
			else
			{
				infotext.setText("Falsche Benutzerdaten.");
			}
			// Login
		}
		else
		{
			System.exit(0);
		}
	}
	
	// TODO Auto-generated constructor stub


	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		/* try { 
			  UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() ); 
			} catch( Exception e ) { e.printStackTrace(); } */
		Login Login = new Login();
	}

}
```


```
package mainlayout;

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;
import chat.*;
import functions.DataBase;
import functions.ReadUserlist;
import sublobbys.*;

public class MainWindow extends JFrame {

	String username = null;
	JLabel gamename;
	JToolBar gamelist;
	JButton lgc;
	JButton exit;
	JButton sat;
	JButton battleisle;
	JButton cantaria;
	JScrollPane lobby;
	JScrollPane chat;
	JSplitPane splitpane;
	
	public MainWindow(String username) {
		LgcChat LgcChat = new LgcChat();
		UserDataClass UserDataClass = new UserDataClass();
		LgcChat.setUserDataClass(UserDataClass);
		// Threads starten
		Thread userlist;
		ReadUserlist ReadUserlist = new ReadUserlist();
		ReadUserlist.setRoom("lgc");
		ReadUserlist.setComponent(LgcChat);
		ReadUserlist.setUserDataClass(UserDataClass);
		userlist = new Thread(ReadUserlist);
		userlist.start();
		
		
		DataBase DataBase = new DataBase();
		// TODO Auto-generated constructor stub
		// Neues Panel definieren
		JPanel content = new JPanel(new GridBagLayout());
		this.setTitle("Lyrion Game Channel Lobby - User " + username);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setPreferredSize(new Dimension(800, 600));
		this.add(content);
		GridBagConstraints c = new GridBagConstraints();
		// Inhalte
		//		MENÜLEISTE EINFÜGEN
		gamelist = new JToolBar("GameListe");
		gamelist.setRollover(true);
		// Knöpfe definieren
		lgc = new JButton("Main");
		sat = new JButton("Hiebe für Diebe!");
		battleisle = new JButton("Battle Isle");
		cantaria = new JButton("Cantaria");
		exit = new JButton("Beenden");
		// Knöpfe einfügen
		gamelist.add(lgc);
		gamelist.addSeparator();
		gamelist.add(sat);
		gamelist.add(battleisle);
		gamelist.add(cantaria);
		gamelist.addSeparator();
		gamelist.add(exit);
		// MENÜLEISTE WIRD EINGEFÜGT, ZEILE 1, SPALTE 1
		c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 0;
		content.add(gamelist, c);
		//		LABEL MIT DEM SPIELNAMEN EINFÜGEN, ZEILE 1, SPALTE 2
		gamename = new JLabel("Lyrion Game Channel");
		c = new GridBagConstraints();
		c.gridx = 1;
		c.gridy = 0;
		c.weightx = 1.0;
		c.anchor = GridBagConstraints.CENTER;
		c.fill = GridBagConstraints.HORIZONTAL;
		content.add(gamename, c);
		//		SPLIT PANE: DEFINIEREN
		LgcLobby LgcLobby = new LgcLobby();
		lobby = new JScrollPane(LgcLobby.LgcLobbyContent());
		
		//		SPLIT PANE: EINFÜGEN, ZEILE 2, SPALTEN 1 UND 2
		splitpane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, lobby, LgcChat.LgcChatContent());
		c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 1;
		c.gridwidth = 2;
		c.fill = GridBagConstraints.BOTH;
		c.weightx = 1.0;
		c.weighty = 1.0;
		content.add(splitpane, c);
		
		// Abschliessen
		this.pack();
		this.setVisible(true);
		
	}

	/**
	 * @param args
	 */
	public static void main(String username) {
		// TODO Auto-generated method stub
		MainWindow MainWindow = new MainWindow(username);

	}

}
```


```
package functions;
import java.sql.*;
import java.lang.System;
import java.util.*;
import java.text.SimpleDateFormat;

public class DataBase {
	
	String connStr;
	Connection conn;
	ResultSet rs;
	
	public void connect(String database)
	{
		// Verbindung zur Datenbank aufbauen
		connStr = "jdbc:mysql://217.26.52.18:3306/lyrionch_" + database + "?user=*******&password=*******";
		// Klasse registrieren und Verbindung öffnen
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection(connStr);
		} 
		catch (ClassNotFoundException e1) { e1.printStackTrace(); }
		catch (SQLException e1) { e1.printStackTrace(); }
	}
	
	public ArrayList getUserlist(String room, String type)
	{
		ArrayList userlist = new ArrayList();
		ArrayList username = new ArrayList();
		ArrayList clan = new ArrayList();
		ArrayList time2 = new ArrayList();
		// Verbindung herstellen
		connect("chat");
		long time = System.currentTimeMillis() - 5000;
		String statement = "SELECT * FROM online_" + room + " WHERE time > " + time;
		try {
			Statement stmt = conn.createStatement();
			rs = stmt.executeQuery(statement);
		}
		catch(SQLException e) { e.printStackTrace(); }
				int i = 0;
				try {
					while(rs.next())
					{
						username.add(rs.getString("username"));
						clan.add(rs.getString("clan"));
						time2.add(rs.getString("time"));
						i++;
					}
					conn.close();
				} catch (SQLException e) { e.printStackTrace(); }
				userlist.add(username);
				userlist.add(clan);
				
		if(type.equals("username"))
		{
			return username;
		}
		else if(type.equals("clan"))
		{
			return clan;
		}
		else
		{
			return time2;
		}
	}

}
```


```
package functions;
import java.sql.*;
import java.util.*;

public class WriteUserlist implements Runnable {

	String connStr;
	Connection conn;
	String username;
	String room;
	String clan;
	
	public void run()
	{
		while(true)
		{
			String statement = "UPDATE online_" + room + " SET clan='" + clan + "', time = '" + System.currentTimeMillis() + "' where username='" + username + "'";
			Statement stmt;
			try {
				stmt = conn.createStatement();
				stmt.executeUpdate(statement);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try
			{
				Thread.sleep(4500);
			}
			catch (InterruptedException e) { e.printStackTrace(); }
		}
	}
	
	public void setRoom(String rm)
	{
		room = rm;
	}
	
	public void set(String usr, String cl)
	{
		room = "lgc";
		username = usr;
		clan = cl;
		// Verbindung zur Datenbank aufbauen
		connStr = "jdbc:mysql://217.26.52.18:3306/lyrionch_chat?user=********&password=*******";
		// Klasse registrieren und Verbindung öffnen
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection(connStr);
		} 
		catch (ClassNotFoundException e1) { e1.printStackTrace(); }
		catch (SQLException e1) { e1.printStackTrace(); }
	}
	
	public static void main(String username)
	{
		
	}
}
```


```
package functions;
import java.sql.*;
import java.util.*;
import chat.*;

public class ReadUserlist implements Runnable {
	
	String connStr;
	Connection conn;
	String room;
	String[][] content;
	LgcChat LgcChat;
	UserDataClass daten;
	DataBase DataBase = new DataBase();
	
	public void run()
	{
	      //--- Daten holen
	      List names = DataBase.getUserlist("lgc", "username");
	      List clans = DataBase.getUserlist("lgc", "clan");
	      List time = DataBase.getUserlist("lgc", "time");
	      String[] namestring = new String[names.size() + 1];
	      String[] clanstring = new String[clans.size() + 1];
	      long[] timestring = new long[time.size() + 1];
	      for(int i = 0; i<names.size(); i++)
	      {
	    	  namestring[i] = names.get( i).toString();
	    	  clanstring[i] = clans.get( i).toString();
	    	  timestring[i] = Long.valueOf(time.get( i).toString());
	      }
	      daten.userdata(namestring, clanstring, timestring);
	      LgcChat.setUserlist(daten);
	      try
	      {
	    	  Thread.sleep(2000);
	      }
	      catch (InterruptedException e) { e.printStackTrace(); }
	}
	
	public void setRoom(String rm)
	{
		room = rm;
	}
	
	public void setComponent(LgcChat LgcCh)
	{
		LgcChat = LgcCh;
	}
	
	public String[][] getData()
	{
		return content;
	}
	
	public void setUserDataClass(UserDataClass usrdata)
	{
		daten = usrdata;
	}
	
}
```


```
package chat;
import javax.swing.*;

import functions.*;

import java.awt.*;
import java.awt.event.*;
import java.util.List;

public class LgcChat {

	JScrollPane chatscroll;
	JScrollPane userscroll;
	JTextField input;
	JButton send;
	JTable userliste;
	JPanel content;
	UserDataClass UserDataClass;
	final UserListModel UserListModel = new UserListModel();
	public LgcChat() {
		// TODO Auto-generated constructor stub
	}
	
	public void setUserDataClass(UserDataClass Usrdataclass)
	{
		UserDataClass = Usrdataclass;
	}
	
	public Component LgcChatContent()
	{
		
		content = new JPanel(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		// Zeile 1, Spalten 1 und 2, Ausgabe-Scrollpane
		c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 0;
		c.fill = GridBagConstraints.BOTH;
		c.weightx = 0.9;
		c.weighty = 1.0;
		c.gridwidth = 2;
		chatscroll = new JScrollPane(chatbereich());
		content.add(chatscroll, c);
		
		// Zeile 2, Spalte 1, Eingabezeile
		c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 1;
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0.9;
		input = new JTextField();
		content.add(input, c);
		
		// Zeile 2, Spalte 2, Absendeknopf
		c = new GridBagConstraints();
		c.gridx = 1;
		c.gridy = 1;
		send = new JButton("Senden");
		content.add(send, c);
		
		// Definieren der JTable
		UserListModel.setUserDataClass(UserDataClass);
		userliste = new JTable(UserListModel);
		
		// Zeilen 1 und 2, Spalte 3, Userliste
		c = new GridBagConstraints();
		c.gridx = 2;
		c.gridy = 0;
		c.fill = GridBagConstraints.BOTH;
		c.gridheight = 2;
		c.weighty = 1.0;
		c.weightx = 0.2;
		userscroll = new JScrollPane(userliste);
		content.add(userscroll, c);
		content.setVisible(true);
		return content;
		
	}
	
	public Component chatbereich()
	{
		JPanel content = new JPanel();
		for(int i=1; i<20; i++)
		{
			content.add(new JLabel("Zeile nummer " +i));
		}
		return content;
	}
	
	public void setUserlist(UserDataClass data)
	{
		UserListModel.updateUserlist(data);
	}
	

	

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	}

}
```


```
package chat;

import java.util.Vector;

import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

public class UserListModel implements TableModel {
	private Vector userdaten = new Vector();
	private Vector listeners = new Vector();
	private UserDataClass userdata;

	public void updateUserlist(UserDataClass userdata)
	{
		// Usernamen einfügen
		userdaten.clear();
		int ind = userdata.getUsername().length;
		for(int i = 0; i<ind; i++)
		{
			if(userdata.getRow(i) == null)
			{
				System.out.print("Rückgabe null");
			}
			else
			{
				userdaten.add(userdata.getRow(i));
			}
		}
		int index = userdaten.size() - 1;
		// Event erstellen
		TableModelEvent e = new TableModelEvent(this, 0, index, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT);
		// Nun das Event verschicken
	      for( int i = 0, n = listeners.size(); i<n; i++ ){
	    	  ((TableModelListener)listeners.get( i )).tableChanged( e );
	      }
		
	}
	
	@Override
	public void addTableModelListener(TableModelListener arg0) {
		listeners.add( arg0 );
		// TODO Auto-generated method stub
		
	}

	@Override
	public Class<?> getColumnClass(int arg0) {
		// TODO Auto-generated method stub
		switch(arg0)
		{
		case 0: return String.class;
		case 1: return String.class;
		case 2: return int.class;
		default: return null;
		}
	}

	@Override
	public int getColumnCount() {
		// TODO Auto-generated method stub
		return 3;
	}

	@Override
	public String getColumnName(int column) {
		// TODO Auto-generated method stub
		switch( column ){
        case 0: return "Username";
        case 1: return "Clan";
        case 2: return "Time";
        default: return null;
		}
	}

	@Override
	public int getRowCount() {
		// TODO Auto-generated method stub
		return userdaten.size();
	}

	@Override
	public Object getValueAt(int arg0, int arg1) {
		// TODO Auto-generated method stub
		if (userdata== null || userdata.getRow(arg0) == null || userdata.getRow(arg0).length <= arg1) {
			return null;
			}
		else
			{ return userdata.getRow(arg0)[arg1]; }
	}

	@Override
	public boolean isCellEditable(int arg0, int arg1) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void removeTableModelListener(TableModelListener arg0) {
		listeners.remove( arg0 );
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setValueAt(Object arg0, int arg1, int arg2) {
		// TODO Auto-generated method stub
		
	}
	
	public void setUserDataClass(UserDataClass usrdata)
	{
		userdata = usrdata;
	}
	
}
```


```
package chat;

public class UserDataClass {
	private String[] username, clan;
	private long[] time;
	
	public void userdata(String[] username, String[] clan, long[] time)
	{
		this.username = username;
		this.clan = clan;
		this.time = time;
	}
	public String[] getUsername() { return username; }
	public String[] getClan() { return clan; }
	public long[] getTime() { return time; }
	public String[] getRow(int row)
	{
		String[] ret = null; 
		if (username.length < row) 
		{
			ret = new String[] { "", "", "" };
			System.out.print("Zu hohe row-Angabe:");
			System.out.print(ret);
			return ret;
		} 
		else
		{
			ret = new String[] { username[row], clan[row], ""+time[row] };
			System.out.print("Rückgabe:");
			System.out.print(username[row]);
			System.out.print(clan[row]);
			System.out.print(""+time[row]);
			return ret;
		}
	}
}
```


----------



## Murray (21. Okt 2007)

Und was genau sind jetzt die Probleme? Compile-Fehler, Laufzeitfehler, unerwartetes Verhalten?


----------



## zilti (21. Okt 2007)

Immer noch der selbe Fehler wie ganz oben geschrieben.


----------



## maki (21. Okt 2007)

Ob es ein gute Idee ist, die IP samt Benutzername und Password zu seiner DB einfach so in einem Forum zu posten..


----------



## Murray (21. Okt 2007)

Du bekommst also eine NullPointerException irgendwo in diesem Code

```
public String[] getRow(int row)
   {
      String[] ret = null;
      if (username.length < row)
      {
         ret = new String[] { "", "", "" };
         System.out.print("Zu hohe row-Angabe:");
         System.out.print(ret);
         return ret;
      }
      else
      {
         ret = new String[] { username[row], clan[row], ""+time[row] };
         System.out.print("Rückgabe:");
         System.out.print(username[row]);
         System.out.print(clan[row]);
         System.out.print(""+time[row]);
         return ret;
      }
   }
```
?


----------



## zilti (21. Okt 2007)

Das weiss ich eben nicht so genau... 
Ach, das ist doch alles eine ver********* sch********!!!!


----------



## maki (21. Okt 2007)

http://logging.apache.org/log4j/1.2/index.html


----------



## zilti (21. Okt 2007)

Der bringt doch nix, den zu benutzen ist aufwändiger als System.out.println .


----------



## maki (21. Okt 2007)

> Der bringt doch nix, den zu benutzen ist aufwändiger als System.out.println .


Ach ja?

Seit wann ist 

```
log.debug("Debugmeldung...");
```
aufwändiger als

```
System.out.println("Debugmeldung..");
```
Die Konfigdatei musst du nur ein einziges mal anlegen, und auch das ist einfach.

Kannst du einfach so alle deine System.out.println abschalten?
Oder kannst du einfach sagen, dass du nur errors sehen möchtest?
Oder kannst du einfach sagen, das du nur das System.out.println von ein paar bestimmten Klassen sehen möchtest und die anderen nicht?

log4j kann das, und es nicht aufwändig oder kompliziert.

Hättest du es benutzt, würdest du jetzt nicht frustriert sein, sondern hättest deinen fehler schon längst gefunden, anstatt darauf zu hoffen, dass jemand in einem Forum sich die Arbeit macht deine Fehler zu suchen


----------



## zilti (21. Okt 2007)

Was macht das jetzt für einen Unterschied, ob ich alle SystemOutPrintln sehe oder nicht?
Fakt ist, dass dieser Fehler nicht auffindbar ist. Die Fehlermeldung enthält ja noch nicht mal eine Zeilennummer - und sowas nennt sich eine Fehlermeldung.


----------



## maki (21. Okt 2007)

> Fakt ist, dass dieser Fehler nicht auffindbar ist.


Nein, Fakt ist, dass du deinen Fehler nicht findest.

Versteh mich nicht falsch, ich meine es nur gut.

Es gibt defacto keine komplexeren SW Projekte, in denen nicht geloggt wird.

Du könntest natürlich auch mehr System.out verwenden.

Debuggen ist oft sehr verwirrend, zuviele Details, gute Logausgaben ersparen einem das Debuggen.


----------



## maki (21. Okt 2007)

Tipp:
Schreibe

```
public String[] getRow(int row)
   {
      System.out.print("time grösse:" + time.length);
      System.out.print("clan grösse:" + clan.length);

      String[] ret = null;
      if (username.length < row)
      {
         ret = new String[] { "", "", "" };
         System.out.print("Zu hohe row-Angabe:");
         System.out.print(ret);
         return ret;
      }
      else
      {
         ret = new String[] { username[row], clan[row], ""+time[row] };
         System.out.print("Rückgabe:");
         System.out.print(username[row]);
         System.out.print(clan[row]);
         System.out.print(""+time[row]);
         return ret;
      }
   }
```

Übrigens, man kann auch NPE auslösen mit debugging code welcher versucht null zu derefenzieren.


----------



## zilti (21. Okt 2007)

Ich hab da mal ne "Programm-Rückmeldung":
 UserDataClass: Daten [Ljava.lang.String;@1d4c61c, [Ljava.lang.String;@1a626f, [J@34a1fc gespeichert. 
 UserDataClass-Rückgabe: zilti, lyrion, 1192980959888
 UserDataClass-Rückgabe: zilti, lyrion, 1192980959888
 UserListModel: Rückgabe Row 0gespeichert, Daten: [Ljava.lang.String;@116471f
 UserDataClass-Rückgabe: zilti, lyrion, 1192980959888
 UserDataClass-Rückgabe: null, null, 0
 UserDataClass-Rückgabe: null, null, 0
 UserListModel: Rückgabe Row 1gespeichert, Daten: [Ljava.lang.String;@1975b59
 UserDataClass-Rückgabe: null, null, 0
 UserDataClass-Rückgabe: zilti, lyrion, 1192980959888
 UserDataClass-Rückgabe: zilti, lyrion, 1192980959888
 UserListModel: Ausgabe für Zelle 0,0 abgerufen. 
 UserDataClass-Rückgabe: zilti, lyrion, 1192980959888
 UserDataClass-Rückgabe: zilti, lyrion, 1192980959888
 UserDataClass-Rückgabe: zilti, lyrion, 1192980959888
 UserListModel: Ausgabe für Zelle 0,1 abgerufen. 
 UserDataClass-Rückgabe: zilti, lyrion, 1192980959888
 UserDataClass-Rückgabe: zilti, lyrion, 1192980959888
 UserDataClass-Rückgabe: zilti, lyrion, 1192980959888
 UserListModel: Ausgabe für Zelle 0,2 abgerufen. 
 UserDataClass-Rückgabe: zilti, lyrion, 1192980959888
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at javax.swing.JTable.prepareRenderer(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	at javax.swing.BufferStrategyPaintManager.paint(Unknown Source)
	at javax.swing.RepaintManager.paint(Unknown Source)
	at javax.swing.JComponent._paintImmediately(Unknown Source)
	at javax.swing.JComponent.paintImmediately(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(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)

Mir erscheint das Auftauchen des NullPointerException etwas unerwartet.


----------



## NTB (21. Okt 2007)

Kannst Du alles, was man braucht, um Dein Projekt zu kompilieren und zu starten mal als KSKB in ein Zip File stecken, so dass ich und andere das mal selbst ausprobieren können?


----------



## zilti (21. Okt 2007)

KSKB?


----------



## maki (21. Okt 2007)

zilti hat gesagt.:
			
		

> KSKB?



http://www.java-forum.org/de/viewtopic.php?p=171842#171842


----------



## zilti (21. Okt 2007)

Wer es will, soll mir eine PN schicken wegen der MySQL-Daten...


----------



## Murray (21. Okt 2007)

An den Ausschreibungen sieht man ja, dass gelegentlich null zurückgeliefert wird.
Mach mal

```
public String[] getRow(int row)
   {

      System.out.print( this + ."getRow( row=" + row + ")");

      String[] ret = null;
      if (username.length < row)
      {
         ret = new String[] { "", "", "" };
         System.out.print("Zu hohe row-Angabe:");
         System.out.print(ret);
         return ret;
      }
      else
      {
         ret = new String[] { username[row], clan[row], ""+time[row] };
         System.out.print("Rückgabe:");
         System.out.print(username[row]);
         System.out.print(clan[row]);
         System.out.print(""+time[row]);
         return ret;
      }
   }
```


----------



## André Uhres (21. Okt 2007)

Mach mal in getColumnClass
return *Integer*.class;
statt
return *int*.class;
:wink: Zilti.jar


----------



## NTB (22. Okt 2007)

Vor mehr 12 Stunden hast Du gefragt...
...hättest Du gleich die Forensuche benutzt, hättest Du gleich die Antwort gehabt.

Pack einfach alles, was man braucht, um Dein kurzes, selbständiges, kompilierbare Beispiel auszuführen, in ein Zip und stell es uns zur Verfgügung. Wenn Du magst...


----------



## zilti (8. Nov 2007)

Nochmals vielen (späten) Dank für die Hilfe, André Uhres! Und alle anderen natürlich auch!


----------

