# Tabelle und SQL Daten



## teh_raccoon (18. Apr 2007)

Hallo Zusammen,

Ich möchte gerne Daten aus einer MySQL Datenbank holen, und in einer Tabelle mit mehreren Spalten darstellen.

[DONE] Wenn die Daten mehr Zeilen sind als das Fenster hoch ist, soll man Scrollen können (ScrollPanel)
[PENDENT] Der Benutzer soll in eine Zeile  *doppelklicken *können, um ein Bearbeitungsfenster (BearbeitenGUI) aufzurufen, wo dann ein SQL Statement ausgeführt wird, mit der ID des angeklickten Datensatzes

Ich bin noch in der Ausbildung, und mein Lehrer hat mich gewarnt, dass ich mich auf eine sehr komplexe Komponente vin Swing einlasse (JTable) mit der er selbst kaum Ahnung hat. Trotzdem möchte ich die Daten in einer Tabelle anzeigen und nicht in aneinandergereihte TextFields o.ä.

Was gibt es da für Möglichkeiten? (SimpleTable, JTable)


----------



## EOB (18. Apr 2007)

hi, also dein lehrer scheint ja ne pflaume zu sein. da sieht man mal wieder, dass leute immer zu dem raten, was für sie bequemer ist. wie sähe es wohl aus, wenn du das hinbekommen würdest? ;-)

versuchs mal so:


```
import javax.swing.*; 
	import javax.swing.table.*; 
	import java.sql.*; 
	import java.util.*; 
	import java.io.*;
	public class TestJDBCTable {
		public static void main (String[] args) {
			try {

		/* 
		 driver, url, user, and pass can be passed in as 
		 system properties "jdbctable.driver", 
		 "jdbctable.url", "jdbctable.user", and 
		 "jdbctable.pass", or specified in a file 
		 called "jdbctable.properties" in current 
		 directory
		*/
		Properties testProps = new Properties();
		String ddriver = System.getProperty ("jdbctable.driver");
		String durl = System.getProperty ("jdbctable.url");
		String duser = System.getProperty ("jdbctable.user");
		String dpass = System.getProperty ("jdbctable.pass");

		if (ddriver != null) 
			testProps.setProperty ("jdbctable.driver", ddriver); 
		if (durl != null) 
			testProps.setProperty ("jdbctable.url", durl); 
		if (duser != null) 
			testProps.setProperty ("jdbctable.user", duser);
		if (dpass != null) 
			testProps.setProperty ("jdbctable.pass", dpass);
		try { 
			testProps.load (new FileInputStream (
					new File ("jdbctable.properties"))); 
		} catch (Exception e) {} // ignore FNF, etc. 
		System.out.println ("Test Properties:"); 
		testProps.list (System.out);
		// now get a connection 
		// note care to replace nulls with empty strings 
		Class.forName(testProps.getProperty
				("jdbctable.driver")).newInstance();
		String url = testProps.getProperty ("jdbctable.url");
		url = ((url == null) ? "" : url); 
		String user = testProps.getProperty ("jdbctable.user"); 
		user = ((user == null) ? "" : user); 
		String pass = testProps.getProperty ("jdbctable.pass"); 
		pass = ((pass == null) ? "" : pass);

		Connection conn = 
			DriverManager.getConnection (url, user, pass);
		// create db table to use
		String tableName = createSampleTable(conn);

		// get a model for this db table and add to a JTable
		TableModel mod =
			new JDBCTableModel (conn, tableName);
		JTable jtable = new JTable (mod);
		JScrollPane scroller =
			new JScrollPane (jtable, 
				ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, 
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		JFrame frame = new JFrame ("JDBCTableModel demo");
		frame.getContentPane().add (scroller);
		frame.pack();
		frame.setVisible (true);

		conn.close();

			} catch (Exception e) {
		e.printStackTrace();
			}
		}

		public static String createSampleTable (Connection conn)
			throws SQLException {

			Statement statement = conn.createStatement();
			// drop table if it exists
			try {

		statement.execute ("DROP TABLE EMPLOYEES");
			} catch (SQLException sqle) {
		sqle.printStackTrace(); // if table !exists
			}
			
			statement.execute ("CREATE TABLE EMPLOYEES " + 
				   "(Name CHAR(20), Title CHAR(30), Salary INT)"); 
			statement.execute ("INSERT INTO EMPLOYEES VALUES " + 
				   "('Jill', 'CEO', 200000 )"); 
			statement.execute ("INSERT INTO EMPLOYEES VALUES " + 
				   "('Bob', 'VP', 195000 )"); 
			statement.execute ("INSERT INTO EMPLOYEES VALUES " + 
				       "('Omar', 'VP', 190000 )"); 
			statement.execute ("INSERT INTO EMPLOYEES VALUES " + 
				   "('Amy', 'Software Engineer', 50000 )"); 
			statement.execute ("INSERT INTO EMPLOYEES VALUES " + 
				   "('Greg', 'Software Engineer', 45000 )");

	     statement.close();
		 return "EMPLOYEES"; 
		 }
	}
```

du siehst also, es geht mit nem tablemodel, welches so aussieht:


```
import javax.swing.*; 
	import javax.swing.table.*; 
	import java.sql.*; 
	import java.util.*;
	/** an immutable table model built from getting 
		metadata about a table in a jdbc database 
	*/ 
	public class JDBCTableModel extends AbstractTableModel {
		Object[][] contents;
		String[] columnNames;
		Class[] columnClasses;

		public JDBCTableModel (Connection conn,
				   String tableName)
			throws SQLException {
			super();
			getTableContents (conn, tableName);

		}
		protected void getTableContents (Connection conn,
					 String tableName)
			throws SQLException {

		// get metadata: what columns exist and what
		// types (classes) are they?
		DatabaseMetaData meta = conn.getMetaData();
		System.out.println ("got meta = " + meta);
		ResultSet results =
			meta.getColumns (null, null, tableName, null) ;
		System.out.println ("got column results");
		ArrayList colNamesList = new ArrayList();
		ArrayList colClassesList = new ArrayList();
		while (results.next()) {
			colNamesList.add (results.getString ("COLUMN_NAME")); 
			System.out.println ("name: " + 
				results.getString ("COLUMN_NAME"));
			int dbType = results.getInt ("DATA_TYPE");
			switch (dbType) {
			case Types.INTEGER:
		colClassesList.add (Integer.class); break; 
			case Types.FLOAT:
		colClassesList.add (Float.class); break; 
			case Types.DOUBLE: 
			case Types.REAL:
		colClassesList.add (Double.class); break; 
			case Types.DATE: 
			case Types.TIME: 
			case Types.TIMESTAMP:
		colClassesList.add (java.sql.Date.class); break; 
			default:
		colClassesList.add (String.class); break; 
			}; 
			System.out.println ("type: " +
				results.getInt ("DATA_TYPE"));
			}
			columnNames = new String [colNamesList.size()];
			colNamesList.toArray (columnNames);
			columnClasses = new Class [colClassesList.size()];
			colClassesList.toArray (columnClasses);
			
			// get all data from table and put into
			// contents array

			Statement statement =
		conn.createStatement ();
			results = statement.executeQuery ("SELECT * FROM " +
						  tableName);
			ArrayList rowList = new ArrayList();
			while (results.next()) {
		ArrayList cellList = new ArrayList(); 
		for (int i = 0; i<columnClasses.length; i++) { 
			Object cellValue = null;


			if (columnClasses[i] == String.class) 
		cellValue = results.getString (columnNames[i]); 
			else if (columnClasses[i] == Integer.class) 
		cellValue = new Integer ( 
				results.getInt (columnNames[i])); 
			else if (columnClasses[i] == Float.class) 
		cellValue = new Float ( 
				results.getInt (columnNames[i])); 
			else if (columnClasses[i] == Double.class) 
		cellValue = new Double ( 
				results.getDouble (columnNames[i]));
			else if (columnClasses[i] == java.sql.Date.class) 
		cellValue = results.getDate (columnNames[i]); 
			else 
		System.out.println ("Can't assign " + 
				columnNames[i]);
			cellList.add (cellValue);
		}// for
		Object[] cells = cellList.toArray();
		rowList.add (cells);
		
	} // while
	// finally create contents two-dim array
	contents = new Object[rowList.size()] [];
	for (int i=0; i<contents.length; i++)

		contents[i] = (Object []) rowList.get (i);
	System.out.println ("Created model with " +
			   contents.length + " rows");

	// close stuff
	results.close();
	statement.close();

	}
	// AbstractTableModel methods
	public int getRowCount() {
		return contents.length;
	}

	public int getColumnCount() {
		if (contents.length == 0)
			return 0;
		else
			return contents[0].length;
		}

		public Object getValueAt (int row, int column) {
			return contents [row][column];
		}

		// overrides methods for which AbstractTableModel
		// has trivial implementations

		public Class getColumnClass (int col) {
			return columnClasses [col];
		}

		public String getColumnName (int col) { 
			return columnNames [col]; 
		} 
	}
```

da schreibst du jetzt schön deinen namen rein und haust den lehrer in die pfanne  :shock:   .

grüße
eob

ps: da musst du natürlich jetzt deine funktionalität (fenster öffnen) etc dran hängen durch listener....


----------



## teh_raccoon (19. Apr 2007)

Danke erstmal...

Nun bekomme ich aber eine Fehlermeldung


```
Test Properties:
-- listing properties --
java.lang.NullPointerException
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Unknown Source)
	at archiv.TestJDBCTable.main(TestJDBCTable.java:42)
```

Code bis Zeile 50


```
package archiv;

import javax.swing.*;
import javax.swing.table.*;
import java.sql.*;
import java.util.*;
import java.io.*;

public class TestJDBCTable {
	public static void main(String[] args) {
		try {

			/*
			 * driver, url, user, and pass can be passed in as system properties
			 * "jdbctable.driver", "jdbctable.url", "jdbctable.user", and
			 * "jdbctable.pass", or specified in a file called
			 * "jdbctable.properties" in current directory
			 */
			Properties testProps = new Properties();
			String ddriver = System.getProperty("com.mysql.jdbc.Driver");
			String durl = System.getProperty("srvweb03");
			String duser = System.getProperty("******");
			String dpass = System.getProperty("******");

			if (ddriver != null)
				testProps.setProperty("jdbctable.driver", ddriver);
			if (durl != null)
				testProps.setProperty("jdbctable.url", durl);
			if (duser != null)
				testProps.setProperty("jdbctable.user", duser);
			if (dpass != null)
				testProps.setProperty("jdbctable.pass", dpass);
			try {
				testProps.load(new FileInputStream(new File(
						"jdbctable.properties")));
			} catch (Exception e) {
			} // ignore FNF, etc.
			System.out.println("Test Properties:");
			testProps.list(System.out);
			// now get a connection
			// note care to replace nulls with empty strings
			Class.forName(testProps.getProperty("jdbctable.driver"))
					.newInstance();
			String url = testProps.getProperty("jdbctable.url");
			url = ((url == null) ? "" : url);
			String user = testProps.getProperty("jdbctable.user");
			user = ((user == null) ? "" : user);
			String pass = testProps.getProperty("jdbctable.pass");
			pass = ((pass == null) ? "" : pass);
```


----------



## EOB (19. Apr 2007)

du musst dir noch ne properties datei anlegen, in der das dan drinne steht...also die werte für die connection. die nennst du dann jdbctable.properties.

grüße :toll:


----------



## teh_raccoon (19. Apr 2007)

Hab jetzt ein bisschen gegoogelt. Ist es richtig, dass das Properties-File Benutzer und DB Zugangsdaten enthält??

Weil wir haben bisher immer so auf eine MySQL DB connectet:


```
Class.forName( "com.mysql.jdbc.Driver" );
Connection conn = DriverManager.getConnection( "jdbc:mysql://meinhost:3306/meindbname", "meinusername", "meinpasswort");
```

wo müsste dann das .properties hin? Und was steht da drin. Der Wikipedia Artikel hat mir nicht wirklich weitergeholfen.


----------



## EOB (19. Apr 2007)

das ist hier genauso, nur das die werte aus der prop datei kommen. wenn du das so nicht machen willst, dann weise deine verbindungsdaten den strings direkt zu...sollte auch gehen . wenns fragen gibt, frag ruhig!

grüße


----------



## teh_raccoon (19. Apr 2007)

Das Problem besteht weitehin (Dieselbe Fehlermeldung)

Hier darf man wohl keine Anhänge speichern. Deshalb hier der Inhalt der jdbctable.properties


```
jdbctable.driver = com.mysql.jdbc.Driver
jdbctable.url = srvweb03
jdbctable.user = usrbgza2
jdbctable.pass = geheimespasswort
```

Das File ist im bin und src ordner im richtigen Unterordner (Package)


----------



## EOB (19. Apr 2007)

hm...schwer zu sagen, sollte so stimmen. dann schreib die details mal gleich so in den code und lass dir prop datei weg. nutzt du eine ide, oder machst du das über konsole?

grüße


----------

