<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki.byte-welt.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Beni</id>
	<title>Byte-Welt Wiki - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.byte-welt.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Beni"/>
	<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php/Spezial:Beitr%C3%A4ge/Beni"/>
	<updated>2026-07-07T20:51:35Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=JTable_(Tutorial)%C2%A9&amp;diff=6812</id>
		<title>JTable (Tutorial)©</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=JTable_(Tutorial)%C2%A9&amp;diff=6812"/>
		<updated>2016-02-06T11:25:21Z</updated>

		<summary type="html">&lt;p&gt;Beni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;© August 2004&lt;br /&gt;
Dieses Tutorial unterliegt dem Copyright, Kopien (auch nur von Teilen) sind nur für nicht-komerzielle Zwecke gestattet; Detailfragen (insbesondere bei Unsicherheiten), bitte direkt an die Autoren.&lt;br /&gt;
&lt;br /&gt;
==Einführung==&lt;br /&gt;
Von allen Components in ganz AWT und Swing, ist das [[JTable_(Java_API)|JTable]] wohl die komplexeste überhaupt (allenfalls kann der [http://wiki.byte-welt.net/wiki/JTree_(Tutorial)© JTree] noch mithalten).&lt;br /&gt;
&lt;br /&gt;
Ziel ist es, dem Leser einen Überblick zu verschaffen, und ihn an die wichtigsten Konzepte heranzuführen. Dabei soll hier nur jedes Themengebiet für sich alleine betrachtet werden, die Kombination aller [[TableModel]]s, [[TableCellRenderer]], [[JTableHeader]]s, [[TableColumnModel]]s und [[TableCellEditor]]s können hier nicht behandelt werden, da wir schliesslich kein Buch schreiben wollen.&lt;br /&gt;
&lt;br /&gt;
Dieses Tutorial ist eigentlich eine grosse Sammlung von Beispielen. Am meisten lernt man immer noch, wenn man selbst rumspielen darf, deshalb: kopiere alle Beispiele und führ sie aus. Verändere ein paar Werte, und schau was passiert. Versuch selbst was sinnvolles zu schreiben.&lt;br /&gt;
&lt;br /&gt;
Dabei konnte nicht immer die beste Implementation gewählt werden, wiel dies das Konzept (von vorne beginnen) gründlich durcheinander gebracht hätte.&lt;br /&gt;
&lt;br /&gt;
===1. Die JTable===&lt;br /&gt;
Sollte diese Component wirklich unbekannt sein, von dem hier sprechen wir:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bild:JTableTutorial1.png]]&lt;br /&gt;
&lt;br /&gt;
===2. API===&lt;br /&gt;
Anlaufstelle Nr. 1 ist, wie so oft, die API {{JAPI|JTable}}. &#039;&#039;JTable&#039;&#039; findet man im Package &#039;&#039;javax.swing&#039;&#039;, und eine ganze Reihe von hilfreichen Klassen und Interfaces im Unterpackage &#039;&#039;javax.swing.table&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===3. Tutorials und anderes im WWW===&lt;br /&gt;
- Das [http://docs.oracle.com/javase/tutorial/uiswing/components/table.html How to use JTable] von Oracle bietet einen einfachen Überblick.&lt;br /&gt;
- [http://www.javaworld.com/javaworld/javatips/jw-javatip116.html#resources Javatip 116] bietet ebenfalls eine kleine Einführung.&lt;br /&gt;
- [http://www.javaworld.com/javaworld/javatips/jw-javatip102.html Javatip 102] beschäftigt sich mit dem CellEditor, insbesondere mit verschiedenen CellEditors in derselben Column.&lt;br /&gt;
- Ein weiteres Tutorial und eine thematische Sortierung von Methoden, etc... findet sich in dem Handout des Kurses [http://www.cs.cf.ac.uk/Dave/HCI/HCI_Handout_CALLER/node165.html Human Computer Interaction]&lt;br /&gt;
- Die [https://github.com/donpir/jdyntable/ jDynTable] ist eine Erweiterung der normalen JTable, und erlaubt auch verschmolzene Zellen (Zellen über mehrere Spalten).&lt;br /&gt;
&lt;br /&gt;
===4. Scrolling===&lt;br /&gt;
Keine Tabelle wäre vollständig ohne Scrollbars und Titelleiste ({{JAPI|JTableHeader}}). Diese Funktionalität erhält man erst, wenn man die &#039;&#039;JTable&#039;&#039; mit einem {{JAPI|JScrollPane}} kombiniert. Das macht man am besten mit dem Konstruktor der &#039;&#039;JScrollPane&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
// Das JTable&lt;br /&gt;
JTable table = ...&lt;br /&gt;
&lt;br /&gt;
// Der Container, dem das JTable hinzugefügt wird&lt;br /&gt;
Container content = ...&lt;br /&gt;
&lt;br /&gt;
// Ein JScrollPane erstellen, und zwischen dem Table und dem Container einfügen.&lt;br /&gt;
content.add( new JScrollPane( table ));&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für diejenigen die einfache Lösungen nicht gerne haben, mit &#039;&#039;getTableHeader&#039;&#039; kommt man direkt an die Titelliste und kann sie irgendwohin schieben:&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
// dem Container das [[BorderLayout]] setzen&lt;br /&gt;
content.setLayout(new BorderLayout());&lt;br /&gt;
&lt;br /&gt;
// den Header der JTable holen und ihn in den oberen Bereich des Containers setzen&lt;br /&gt;
content.add(table.getTableHeader(), BorderLayout.PAGE_START);&lt;br /&gt;
&lt;br /&gt;
// das JTable in die Mitte des Containers setzen&lt;br /&gt;
content.add(table, BorderLayout.CENTER);&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man kann unendlich viele Dinge mit einer &#039;&#039;JTable&#039;&#039; tun, aber nicht Alles ist sinnvoll. Im letzten Beispiel hat der Benutzer keine möglichkeit die Tabelle umherzuschieben und verdeckte Zellen in den Sichtbarkeitsbereich zu scrollen.&lt;br /&gt;
&lt;br /&gt;
==Wie kommen Daten in die Tabelle?==&lt;br /&gt;
&#039;&#039; JTable&#039;&#039; selbst hat nur die Aufgabe Daten hübsch darzustellen. Die Tabelle versteht weder woher die Daten kommen, noch was die Daten bedeuten. Wie also kommen die Daten in die Tabelle?&lt;br /&gt;
&lt;br /&gt;
===1. Möglichkeit - 2d Array===&lt;br /&gt;
Die wohl einfachste Methode ist einen 2-dimensionalen Array zu benutzen.&lt;br /&gt;
Das JTable bietet einen entsprechenden Konstruktor:&lt;br /&gt;
&amp;lt;code=java&amp;gt;import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.JScrollPane;&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
&lt;br /&gt;
public class JTableDemo{&lt;br /&gt;
	public static void main( String[] args ){&lt;br /&gt;
		// Die Daten für das Table&lt;br /&gt;
		String[][] data = new String[][]{&lt;br /&gt;
				{&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot;, &amp;quot;d&amp;quot;},&lt;br /&gt;
				{&amp;quot;e&amp;quot;, &amp;quot;f&amp;quot;, &amp;quot;g&amp;quot;, &amp;quot;h&amp;quot;},&lt;br /&gt;
				{&amp;quot;i&amp;quot;, &amp;quot;j&amp;quot;, &amp;quot;k&amp;quot;, &amp;quot;l&amp;quot;}&lt;br /&gt;
		};&lt;br /&gt;
		&lt;br /&gt;
		// Die Column-Titles&lt;br /&gt;
		String[] title = new String[]{&lt;br /&gt;
				&amp;quot;A&amp;quot;, &amp;quot;B&amp;quot;, &amp;quot;C&amp;quot;, &amp;quot;D&amp;quot;&lt;br /&gt;
		};&lt;br /&gt;
		&lt;br /&gt;
		// Das JTable initialisieren&lt;br /&gt;
		JTable table = new JTable( data, title );&lt;br /&gt;
		&lt;br /&gt;
		JFrame frame = new JFrame( &amp;quot;Demo&amp;quot; );&lt;br /&gt;
		frame.getContentPane().add( new JScrollPane( table ) );&lt;br /&gt;
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
		frame.pack();&lt;br /&gt;
		frame.setVisible( true );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:JTableTutorial2.png]]&lt;br /&gt;
Diese Methode ist sehr statisch, es ist später nicht mehr gut möglich, Daten zu ändern.&lt;br /&gt;
&lt;br /&gt;
===2. Möglichkeit - Vectoren===&lt;br /&gt;
Mit ineinander gesetzten Vektoren:&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
import java.util.Vector;&lt;br /&gt;
&lt;br /&gt;
import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.JScrollPane;&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
import javax.swing.table.AbstractTableModel;&lt;br /&gt;
&lt;br /&gt;
public class JTableDemo{&lt;br /&gt;
	public static void main( String[] args ){&lt;br /&gt;
		// Die Daten für das Table&lt;br /&gt;
		Vector data = new Vector();&lt;br /&gt;
			Vector rowA = new Vector();&lt;br /&gt;
				rowA.add(  &amp;quot;1&amp;quot; );&lt;br /&gt;
				rowA.add(  &amp;quot;2&amp;quot; );&lt;br /&gt;
				rowA.add(  &amp;quot;3&amp;quot; );&lt;br /&gt;
				rowA.add(  &amp;quot;4&amp;quot; );&lt;br /&gt;
			Vector rowB = new Vector();&lt;br /&gt;
				rowB.add(  &amp;quot;5&amp;quot; );&lt;br /&gt;
				rowB.add(  &amp;quot;6&amp;quot; );&lt;br /&gt;
				rowB.add(  &amp;quot;7&amp;quot; );&lt;br /&gt;
				rowB.add(  &amp;quot;8&amp;quot; );&lt;br /&gt;
			Vector rowC = new Vector();&lt;br /&gt;
				rowC.add(  &amp;quot;9&amp;quot; );&lt;br /&gt;
				rowC.add( &amp;quot;10&amp;quot; );&lt;br /&gt;
				rowC.add( &amp;quot;11&amp;quot; );&lt;br /&gt;
				rowC.add( &amp;quot;12&amp;quot; );&lt;br /&gt;
		&lt;br /&gt;
			data.add( rowA );&lt;br /&gt;
			data.add( rowB );&lt;br /&gt;
			data.add( rowC );&lt;br /&gt;
				&lt;br /&gt;
		// Die Titel für das Table&lt;br /&gt;
		Vector title = new Vector();&lt;br /&gt;
			title.add( &amp;quot;A&amp;quot; );&lt;br /&gt;
			title.add( &amp;quot;B&amp;quot; );&lt;br /&gt;
			title.add( &amp;quot;C&amp;quot; );&lt;br /&gt;
			title.add( &amp;quot;D&amp;quot; );&lt;br /&gt;
		&lt;br /&gt;
		// Das JTable initialisieren&lt;br /&gt;
		JTable table = new JTable(  data, title );&lt;br /&gt;
		&lt;br /&gt;
		JFrame frame = new JFrame( &amp;quot;Demo&amp;quot; );&lt;br /&gt;
		frame.getContentPane().add( new JScrollPane( table ) );&lt;br /&gt;
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
		frame.pack();&lt;br /&gt;
		frame.setVisible( true );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
[[Bild:JTableTutorial3.png]]&lt;br /&gt;
&lt;br /&gt;
Das hat natürlich den Vorteil, dass man die Vektoren an verschiedenen Orten zusammenbauen kann, doch auch hier gilt: nachdem das JTable initialisiert wurde, kann man nichts mehr verändern.&lt;br /&gt;
&lt;br /&gt;
===3. Möglichkeit - DefaultTableModel===&lt;br /&gt;
Mit einem [[DefaultTableModel (API) | DefaultTableModel]].&lt;br /&gt;
&lt;br /&gt;
Ein DefaultTableModel kann man sich auch als 2-dimensionalen Array vorstellen. Allerdings besitzt es Methoden, um neue Rows/Columns hinzuzufuegen, oder zu entfernen, z.B. addRow.&lt;br /&gt;
&lt;br /&gt;
Was ein TableModel ist, wird im naechsten Teil behandelt.&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
import java.awt.BorderLayout;&lt;br /&gt;
import java.awt.Container;&lt;br /&gt;
import java.awt.event.ActionEvent;&lt;br /&gt;
import java.awt.event.ActionListener;&lt;br /&gt;
import java.util.Vector;&lt;br /&gt;
&lt;br /&gt;
import javax.swing.JButton;&lt;br /&gt;
import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.JScrollPane;&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
import javax.swing.table.DefaultTableModel;&lt;br /&gt;
&lt;br /&gt;
public class JTableDemo{&lt;br /&gt;
	public static void main( String[] args ){&lt;br /&gt;
		// Die Namen der Columns&lt;br /&gt;
		String[] titles = new String[]{ &amp;quot;A&amp;quot;, &amp;quot;B&amp;quot;, &amp;quot;C&amp;quot;, &amp;quot;D&amp;quot; };&lt;br /&gt;
		&lt;br /&gt;
		// Das Model das wir verwenden werden. Hier setzten wir gleich die&lt;br /&gt;
		// Titel, aber es ist später immer noch möglich weitere Columns oder&lt;br /&gt;
		// Rows hinzuzufügen.&lt;br /&gt;
		final DefaultTableModel model = new DefaultTableModel( titles, 0 );&lt;br /&gt;
		&lt;br /&gt;
		// Das JTable initialisieren&lt;br /&gt;
		JTable table = new JTable( model );&lt;br /&gt;
		&lt;br /&gt;
		// Buttons, damit das alles schöner aussieht.&lt;br /&gt;
		final JButton buttonAddRow = new JButton( &amp;quot;add row&amp;quot; );&lt;br /&gt;
		final JButton buttonRemRow = new JButton( &amp;quot;remove row&amp;quot; );&lt;br /&gt;
		final JButton buttonAddCol = new JButton( &amp;quot;add column&amp;quot; );&lt;br /&gt;
		&lt;br /&gt;
		buttonRemRow.setEnabled( false );&lt;br /&gt;
		&lt;br /&gt;
		// Den Buttons ein paar Reaktionen geben&lt;br /&gt;
		buttonAddRow.addActionListener( new ActionListener(){&lt;br /&gt;
			public void actionPerformed(ActionEvent e) {&lt;br /&gt;
				// Die Anzahl Columns (Breite) der Tabelle&lt;br /&gt;
				int size = model.getColumnCount();&lt;br /&gt;
				&lt;br /&gt;
				// einen neuen Vector mit Daten herstellen&lt;br /&gt;
				Vector newDatas = createDataVector( &amp;quot;row&amp;quot;, size );&lt;br /&gt;
				&lt;br /&gt;
				// eine neue Row hinzufügen&lt;br /&gt;
				model.addRow( newDatas );&lt;br /&gt;
				&lt;br /&gt;
				&lt;br /&gt;
				// das Entfernen erlauben&lt;br /&gt;
				buttonRemRow.setEnabled( true );&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		buttonAddCol.addActionListener( new ActionListener(){&lt;br /&gt;
			public void actionPerformed(ActionEvent e) {&lt;br /&gt;
				int size = model.getRowCount();&lt;br /&gt;
				Vector newDatas = createDataVector( &amp;quot;column&amp;quot;, size );&lt;br /&gt;
				String name = String.valueOf( model.getColumnCount() );&lt;br /&gt;
				model.addColumn( name, newDatas );&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		buttonRemRow.addActionListener( new ActionListener(){&lt;br /&gt;
			public void actionPerformed(ActionEvent e) {&lt;br /&gt;
				int size = model.getRowCount();&lt;br /&gt;
				int index = (int)(Math.random() * size);&lt;br /&gt;
				model.removeRow( index );&lt;br /&gt;
				&lt;br /&gt;
				buttonRemRow.setEnabled( size &amp;gt; 1 );&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
		JFrame frame = new JFrame( &amp;quot;Demo&amp;quot; );&lt;br /&gt;
		&lt;br /&gt;
		Container content = frame.getContentPane();&lt;br /&gt;
		&lt;br /&gt;
		content.add( new JScrollPane( table ), BorderLayout.CENTER );&lt;br /&gt;
		content.add( buttonAddRow, BorderLayout.NORTH );&lt;br /&gt;
		content.add( buttonRemRow, BorderLayout.SOUTH );&lt;br /&gt;
		content.add( buttonAddCol, BorderLayout.WEST );&lt;br /&gt;
		&lt;br /&gt;
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
		frame.pack();&lt;br /&gt;
		frame.setVisible( true );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public static Vector createDataVector( String prefix, int size ){&lt;br /&gt;
		Vector vector = new Vector( size );&lt;br /&gt;
		for( int i = 0; i &amp;lt; size; i++ )&lt;br /&gt;
			vector.add( prefix + &amp;quot; : &amp;quot; + size + &amp;quot; : &amp;quot; + i );&lt;br /&gt;
		&lt;br /&gt;
		return vector;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
[[Bild:JTableTutorial4.png]]&lt;br /&gt;
&lt;br /&gt;
Was geschieht hier?&lt;br /&gt;
Es gibt 3 JButtons, welche jeweils eine Row oder Column hinzufügen, oder eine Row entfernen.&lt;br /&gt;
Die seltsame Schreibweise addActionListener( ... ) stellen anonyme Klassen dar.&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Hauptaktion macht das DefaultTableModel &amp;quot;model&amp;quot;, alles andere dient nur dazu, dem Benutzer eine Möglichkeit zu bieten mit der Tabelle zu spielen.&lt;br /&gt;
&lt;br /&gt;
===4. Möglichkeit - TableModel===&lt;br /&gt;
Mit Hilfe eines TableModels.&lt;br /&gt;
Das TableModel ist ein Interface. Das JTable ruft über die Methode TableModel#getValueAt( int rowIndex, int columnIndex) für jede einzelne Zelle den Wert ab.&lt;br /&gt;
Das muss nicht in einer bestimmten Reihenfolge geschehen, das JTable nimmt einfach gerade das, was es benötigt.&lt;br /&gt;
&lt;br /&gt;
Das folgende kleine Beispiel zeigt: die Klasse Vehicel, die eigentlich überhaupt nichts mit einer Tabelle zu tun hat, kann mit Hilfe eines TableModels auf die JTable gebracht werden. Wichtig dabei ist: man muss nicht zuerst &amp;quot;von Hand&amp;quot; die Daten vorsortieren, sondern man gibt sie einfach dann zurück, wenn sie auch tatsächlich benötigt werden.&lt;br /&gt;
&lt;br /&gt;
Was ist nun, falls die Daten veraendert wurden (z.B. eine Row hinzugefuegt)?&lt;br /&gt;
Man muss die Methoden #addTableModelListener und #removeTableModelListener implementieren. Diese Methoden werden von verschiedenen Orten aufgerufen, zum Beispiel von JTable selbst, aber mögleicherweise auch vom Look And Feel.&lt;br /&gt;
All diese Listener interessieren sich fuer Veränderungen des Models. Sobald sich die Daten ändern, muss man bei allen Listenern die Methode tableChanged( TableModelEvent event) aufrufen.&lt;br /&gt;
&lt;br /&gt;
Das TableModelEvent enthält alle Informationen über die Veränderungen. Die Werte für das Event können nur über den Konstruktor gesetzt werden, ein paar einfache Beispiele aus der API:&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
// source Das TableModel, welches verändert wurde&lt;br /&gt;
&lt;br /&gt;
TableModelEvent(source); // Sämtliche Daten von source wurden verändert&lt;br /&gt;
TableModelEvent(source, TableModelEvent.HEADER_ROW); // Die Struktur der Daten wurde verändert, die Columns werden auf den Ursprungszustand gesetzt. &lt;br /&gt;
TableModelEvent(source, 1); // Row 1 wurde verändert&lt;br /&gt;
TableModelEvent(source, 3, 6); // Row 3, 4, 5, 6 wurden verändert&lt;br /&gt;
TableModelEvent(source, 2, 2, 6); // Die Zelle (2, 6) wurde verändert&lt;br /&gt;
TableModelEvent(source, 3, 6, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT); // Es wurden neue Rows hinzugefügt, sie haben nun die Indices 3, 4, 5 und 6&lt;br /&gt;
TableModelEvent(source, 3, 6, TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE); // Die Rows mit den Indices 3, 4, 5 und 6 wurden gelöscht.&lt;br /&gt;
&lt;br /&gt;
TableModelEvent(source, 2, 3, 5, TableModelEvent.INSERTED ) // Fehler: Es ist nicht möglich, dass Zelle (2,5) und (3,5) hinzugefügt werden.&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sicher bekannt ist das Verhältnis zwischen Button und ActionListener.&lt;br /&gt;
Sobald jemand den Button drückt, wird der ActionListener aufgerufen. Der Button ist sozusagen für die Aktion, der ActionListener für die Reaktion zuständig.&lt;br /&gt;
Hier ist es genau umgekehrt: das TableModel startet die Aktion, die TableModelListener reagieren darauf.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt, wie man dem JTable (indirekt) sagen kann, dass eine neue Row hinzugefügt wurde.&lt;br /&gt;
Genau gleich wie hier das Hinzufügen von neuen Vehikeln, kann man auch das Löschen von einzelnen Columns, die Veränderung des Inhalts einer Zelle, etc... implementieren.&lt;br /&gt;
&lt;br /&gt;
mehr zu Listeners.&lt;br /&gt;
&lt;br /&gt;
Zuerst das Frame, wie wir es verwenden möchten:&lt;br /&gt;
&amp;lt;code=java&amp;gt;import java.awt.BorderLayout;&lt;br /&gt;
import java.awt.Container;&lt;br /&gt;
import java.awt.event.ActionEvent;&lt;br /&gt;
import java.awt.event.ActionListener;&lt;br /&gt;
import java.util.Vector;&lt;br /&gt;
&lt;br /&gt;
import javax.swing.JButton;&lt;br /&gt;
import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.JScrollPane;&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
import javax.swing.event.TableModelEvent;&lt;br /&gt;
import javax.swing.event.TableModelListener;&lt;br /&gt;
import javax.swing.table.TableModel;&lt;br /&gt;
&lt;br /&gt;
public class JTableDemo{&lt;br /&gt;
	public static void main( String[] args ){&lt;br /&gt;
		// Unser TableModel (siehe unten)&lt;br /&gt;
		final Model model = new Model();&lt;br /&gt;
		&lt;br /&gt;
		// Das JTable initialisieren&lt;br /&gt;
		JTable table = new JTable( model );&lt;br /&gt;
		&lt;br /&gt;
		// Buttons, damit das alles schöner aussieht.&lt;br /&gt;
		final JButton buttonVehicel = new JButton( &amp;quot;add vehicel&amp;quot; );&lt;br /&gt;
		&lt;br /&gt;
		// Den Buttons ein paar Reaktionen geben&lt;br /&gt;
		buttonVehicel.addActionListener( new ActionListener(){&lt;br /&gt;
			public void actionPerformed(ActionEvent e) {&lt;br /&gt;
				// Die Anzahl Columns (Breite) der Tabelle&lt;br /&gt;
				int size = model.getRowCount();&lt;br /&gt;
				&lt;br /&gt;
				// einen neuen Vector mit Daten herstellen&lt;br /&gt;
				Vehicel vehicel = createVehicel( size );&lt;br /&gt;
				&lt;br /&gt;
				// ein neues Vehikel hinzufügen&lt;br /&gt;
				model.addVehicle( vehicel );&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
				&lt;br /&gt;
		JFrame frame = new JFrame( &amp;quot;Demo&amp;quot; );&lt;br /&gt;
		&lt;br /&gt;
		Container content = frame.getContentPane();&lt;br /&gt;
		&lt;br /&gt;
		content.add( new JScrollPane( table ), BorderLayout.CENTER );&lt;br /&gt;
		content.add( buttonVehicel, BorderLayout.SOUTH );&lt;br /&gt;
		&lt;br /&gt;
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
		frame.pack();&lt;br /&gt;
		frame.setVisible( true );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Stellt einfach eine neue Instanz eines Vehikels her.&lt;br /&gt;
	public static Vehicel createVehicel( int index ){&lt;br /&gt;
		index = index % 5; // Modulo&lt;br /&gt;
		&lt;br /&gt;
		switch( index ){&lt;br /&gt;
			case 0: return new Vehicel( &amp;quot;Fahrrad&amp;quot;, 1, 2, false );&lt;br /&gt;
			case 1: return new Vehicel( &amp;quot;Bus&amp;quot;, 20, 4, true );&lt;br /&gt;
			case 2: return new Vehicel( &amp;quot;Pferd&amp;quot;, 1, 0, false );&lt;br /&gt;
			case 3: return new Vehicel( &amp;quot;Zug&amp;quot;, 1000, 80, true );&lt;br /&gt;
			case 4: return new Vehicel( &amp;quot;Truck&amp;quot;, 2, 10, true );&lt;br /&gt;
			default: return null;	&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Der Code für eine Datenstruktur &amp;quot;Vehicel&amp;quot;:&lt;br /&gt;
&amp;lt;code=java&amp;gt;// Das Vehikel ist eine total unabhängige Klasse, die mit einer&lt;br /&gt;
// Tabelle eigentlich gar nichts zu tun hat.&lt;br /&gt;
class Vehicel{&lt;br /&gt;
	private String name;&lt;br /&gt;
	private int places, wheels;&lt;br /&gt;
	private boolean motor;&lt;br /&gt;
	&lt;br /&gt;
	public Vehicel( String name, int places, int wheels, boolean motor ){&lt;br /&gt;
		this.name = name;&lt;br /&gt;
		this.places = places;&lt;br /&gt;
		this.wheels = wheels;&lt;br /&gt;
		this.motor = motor;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public String getName(){ return name; }&lt;br /&gt;
	public int getPlaces(){ return places; }&lt;br /&gt;
	public int getWheels(){ return wheels; }&lt;br /&gt;
	public boolean hasMotor(){ return motor; }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Das Model, dass die Vehicel in eine Form übersetzt, welche das JTable anzeigen kann:&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
// Unsere Implementation des TableModels&lt;br /&gt;
class Model implements TableModel{&lt;br /&gt;
	private Vector vehicels = new Vector();&lt;br /&gt;
	private Vector listeners = new Vector();&lt;br /&gt;
	&lt;br /&gt;
	public void addVehicle( Vehicel vehicel ){&lt;br /&gt;
		// Das wird der Index des Vehikels werden&lt;br /&gt;
		int index = vehicels.size();&lt;br /&gt;
		vehicels.add( vehicel );&lt;br /&gt;
		&lt;br /&gt;
		// Jetzt werden alle Listeners benachrichtigt&lt;br /&gt;
		&lt;br /&gt;
		// Zuerst ein Event, &amp;quot;neue Row an der Stelle index&amp;quot; herstellen&lt;br /&gt;
		TableModelEvent e = new TableModelEvent( this, index, index, &lt;br /&gt;
				TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT );&lt;br /&gt;
		&lt;br /&gt;
		// Nun das Event verschicken&lt;br /&gt;
		for( int i = 0, n = listeners.size(); i&amp;lt;n; i++ ){&lt;br /&gt;
			((TableModelListener)listeners.get( i )).tableChanged( e );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Die Anzahl Columns&lt;br /&gt;
	public int getColumnCount() {&lt;br /&gt;
		return 4;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Die Anzahl Vehikel&lt;br /&gt;
	public int getRowCount() {&lt;br /&gt;
		return vehicels.size();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Die Titel der einzelnen Columns&lt;br /&gt;
	public String getColumnName(int column) {&lt;br /&gt;
		switch( column ){&lt;br /&gt;
			case 0: return &amp;quot;Name&amp;quot;;&lt;br /&gt;
			case 1: return &amp;quot;Fahrgäste&amp;quot;;&lt;br /&gt;
			case 2: return &amp;quot;Räder&amp;quot;;&lt;br /&gt;
			case 3: return &amp;quot;Besitzt Motor&amp;quot;;&lt;br /&gt;
			default: return null;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Der Wert der Zelle (rowIndex, columnIndex)&lt;br /&gt;
	public Object getValueAt(int rowIndex, int columnIndex) {&lt;br /&gt;
		Vehicel vehicle = (Vehicel)vehicels.get( rowIndex );&lt;br /&gt;
		&lt;br /&gt;
		switch( columnIndex ){&lt;br /&gt;
			case 0: return vehicle.getName();&lt;br /&gt;
			case 1: return new Integer( vehicle.getPlaces() );&lt;br /&gt;
			case 2: return new Integer( vehicle.getWheels() );&lt;br /&gt;
			case 3: return vehicle.hasMotor() ? Boolean.TRUE : Boolean.FALSE; &lt;br /&gt;
			default: return null;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Eine Angabe, welchen Typ von Objekten in den Columns angezeigt werden soll&lt;br /&gt;
	public Class getColumnClass(int columnIndex) {&lt;br /&gt;
		switch( columnIndex ){&lt;br /&gt;
			case 0: return String.class;&lt;br /&gt;
			case 1: return Integer.class;&lt;br /&gt;
			case 2: return Integer.class;&lt;br /&gt;
			case 3: return Boolean.class; &lt;br /&gt;
			default: return null;&lt;br /&gt;
		}	&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public void addTableModelListener(TableModelListener l) {&lt;br /&gt;
		listeners.add( l );&lt;br /&gt;
	}&lt;br /&gt;
	public void removeTableModelListener(TableModelListener l) {&lt;br /&gt;
		listeners.remove( l );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
	public boolean isCellEditable(int rowIndex, int columnIndex) {&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {&lt;br /&gt;
		// nicht beachten&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Bild:JTableTutorial5.png]]&lt;br /&gt;
&lt;br /&gt;
====API - TableModel====&lt;br /&gt;
Ein Überblick aller Methoden, die das Interface TableModel vorschreibt.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;int getColumnCount()&#039;&#039;&lt;br /&gt;
Gibt die Anzahl Columns (Spalten) zurück. Dieser Wert muss natürlich &amp;gt;= 0 sein.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;String getColumnName(int columnIndex)&#039;&#039;&lt;br /&gt;
Gibt den Namen einer Column zurück. Der Name wird als Titel im JTableHeader verwendet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;int getRowCount()&#039;&#039;&lt;br /&gt;
Gibt die Anzahl Rows (Zeilen) zurück. Wie der Wert bei &amp;quot;getColumnCount&amp;quot; muss dieser Wert &amp;gt;= 0 sein.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Object getValueAt(int rowIndex, int columnIndex)&#039;&#039;&lt;br /&gt;
Gibt den Wert der Zelle (rowIndex, columnIndex) zurück.&lt;br /&gt;
Dieses Object wird dem TableCellRenderer (siehe nächstes Kapitel) übergeben. Der Renderer ist eine Component, welche das Object irgendwie darstellen kann (z.B. ein JLabel das einen String als Text anzeigt.)&lt;br /&gt;
&lt;br /&gt;
Primitive Datentypen wie int, double, ... werden am einfachsten in ihrere Wrapperklasse Integer, Double, ... zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Das Object das hier zurückgegeben wird, muss eine Instanc von der Klasse sein, die bei #getColumnClass zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Class getColumnClass(int columnIndex)&#039;&#039;&lt;br /&gt;
Gibt die Klasse (oder Superklasse) aller Zellenwerte der Column columnIndex zurück. Das JTable verwendet diese Klasse, um herauszufinden, wie es diese Column am besten darstellt. z.B. Werden Icons anders dargestellt als Booleans...&lt;br /&gt;
&lt;br /&gt;
z.B. die Klasse von String kann man so herausfinden:&lt;br /&gt;
&amp;lt;code=java&amp;gt;Class string = String.class;&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&#039;&#039;boolean isCellEditable(int rowIndex, int columnIndex)&#039;&#039;&lt;br /&gt;
Gibt an, ob diese Zelle editiert werden kann.&lt;br /&gt;
Falls ja, kann das JTable einen Editor (eine andere Component) in dieser Zelle darstellen, sollte der Benutzer sie selektieren (es gibt also immer höchstens einen sichtbaren Editor pro JTable).&lt;br /&gt;
Wird das Editieren beendet (z.B. durch einen Druck auf ENTER), gibt der Editor ein Object zurueck, welches mit #setValueAt an das TableModel übertragen wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;void setValueAt(Object aValue, int rowIndex, int columnIndex)&#039;&#039;&lt;br /&gt;
Setzt an einer Stelle der Tabelle einen neuen Wert. Dieser neue Wert wird durch den Benutzer eingegeben. Diese Methode wird niemals aufgerufen, wenn #isCellEditable( rowIndex, columnIndex ) false zurueckgibt.&lt;br /&gt;
&lt;br /&gt;
Sollte dem JTable nichts Spezielles gesagt worden sein, und gibt getColumnClass( columnIndex ) weder String, noch Boolean, Integer,..., oder Date zurück, wird aValue ein String sein. Dann muss das TableModel diesen String selbst übersetzen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;void addTableModelListener(TableModelListener l)&#039;&#039;&lt;br /&gt;
Registriert einen TableModelListener bei diesem Model. Dieser Listener muss immer dann aufgerufen werden, sobald die Daten im Model verändert wurden (z.B. eine zusätzliche Row hineingeschoben wurde).&lt;br /&gt;
Listener können vom JTable oder von anderen Klassen kommen, es muss das Model nicht interessieren.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;void removeTableModelListener(TableModelListener l)&#039;&#039;&lt;br /&gt;
Entfernt einen TableModelListener. z.B. muss das JTable ja nicht mehr über Veränderungen informiert werden, falls das Model vom Table entfernt wurde...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====API - TableModelEvent====&lt;br /&gt;
Das TableModelEvent befördert Informationen von einem TableModel zu seinen TableModelListenern.&lt;br /&gt;
&lt;br /&gt;
=====Konstruktoren=====&lt;br /&gt;
Das TableModelEvent hat verschiedene Konstruktoren. Je nach dem welcher mit welchen Argumenten benutzt wurde, bekommt das Event eine andere Bedeutung.&lt;br /&gt;
&lt;br /&gt;
source ist immer das TableModel, in dem etwas passiert ist.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TableModelEvent(TableModel source)&#039;&#039;&lt;br /&gt;
Benutzen, falls die Veränderungen zu komplex für eine Beschreibung sind. Dann verliert das JTable allerdings viele Benutzereinstellungen, wie z.B. die Selektion.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TableModelEvent(TableModel source, int row)&#039;&#039;&lt;br /&gt;
Gibt an, dass eine Row (mit dem Index row) verändert wurde.&lt;br /&gt;
Allerdings kann row auch die Konstante HEADER_ROW sein, falls sich etwas mit der Titelleiste des JTables veraendert hat (z.B. ein Titel).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TableModelEvent(TableModel source, int firstRow, int lastRow)&#039;&#039;&lt;br /&gt;
Gibt an, dass alle Rows von firstRow bis und mit lastRow verändert wurden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TableModelEvent(TableModel source, int firstRow, int lastRow, int column)&#039;&#039;&lt;br /&gt;
Gibt an, dass alle Rows von firstRow bis und mit lastRow verändert wurden.&lt;br /&gt;
column kann der Index einer einzigen Column sein, oder aber die Konstante ALL_COLUMNS falls mehrere Columns verändert wurden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TableModelEvent(TableModel source, int firstRow, int lastRow, int column, int type)&#039;&#039;&lt;br /&gt;
Gibt an, dass alle Rows von firstRow bis und mit lastRow verändert wurden.&lt;br /&gt;
column kann der Index einer einzigen Column sein, oder aber die Konstante ALL_COLUMNS falls mehrere Columns verändert wurden.&lt;br /&gt;
type ist einer von INSERT, DELETE oder UPDATE.&lt;br /&gt;
&lt;br /&gt;
=====Konstanten=====&lt;br /&gt;
&#039;&#039;static int ALL_COLUMNS&#039;&#039;&lt;br /&gt;
Wird für das Argument column verwendet, und gibt an, dass alle Columns betroffen sind.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;static int DELETE&#039;&#039;&lt;br /&gt;
Wird für das Argument type verwendet, und gibt an, dass Rows gelöscht wurden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;static int HEADER_ROW&#039;&#039;&lt;br /&gt;
Gibt an, dass die Titelleiste von irgendwelchen Veränderungen betroffen ist.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;static int INSERT&#039;&#039;&lt;br /&gt;
Wird für das Argument type verwendet, und gibt an, dass Rows eingefügt wurden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;static int UPDATE&#039;&#039;&lt;br /&gt;
Wird für das Argument type verwendet, und gibt an, dass sich der Inhalt der Rows verändert hat.&lt;br /&gt;
&lt;br /&gt;
====Info - Aufruf von getValueAt====&lt;br /&gt;
Es wurde ja schon gesagt: das JTable holt sich die Informationen in keiner bestimmten Reihenfolge. Das kann man sichtbar machen (aber Achtung, der Code nun folgt, sollte nicht so verwendet werden).&lt;br /&gt;
&lt;br /&gt;
Die Tabelle&lt;br /&gt;
&amp;lt;code=java&amp;gt;import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.JScrollPane;&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
import javax.swing.event.TableModelListener;&lt;br /&gt;
import javax.swing.table.TableModel;&lt;br /&gt;
&lt;br /&gt;
public class JTableDemo{&lt;br /&gt;
	public static void main( String[] args ){&lt;br /&gt;
		// Unser TableModel (siehe unten)&lt;br /&gt;
		final Model model = new Model(50, 60);&lt;br /&gt;
		&lt;br /&gt;
		// Das JTable initialisieren&lt;br /&gt;
		JTable table = new JTable( model );&lt;br /&gt;
		&lt;br /&gt;
		JFrame frame = new JFrame( &amp;quot;Demo&amp;quot; );&lt;br /&gt;
		frame.getContentPane().add( new JScrollPane( table ) );&lt;br /&gt;
		&lt;br /&gt;
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
		frame.pack();&lt;br /&gt;
		frame.setVisible( true );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Ein TableModel das Integer ausgiebt, und mitzählt, wieoft &amp;quot;getValueAt&amp;quot; aufgerufen wurde (für jede Zelle einzeln)&lt;br /&gt;
&amp;lt;code=java&amp;gt;class Model implements TableModel{&lt;br /&gt;
	private int width, height;&lt;br /&gt;
	&lt;br /&gt;
	int[][] calls;&lt;br /&gt;
	&lt;br /&gt;
	public Model( int width, int height ){&lt;br /&gt;
		this.width = width;&lt;br /&gt;
		this.height = height;&lt;br /&gt;
		calls = new int[ width ][ height ];&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Die Anzahl Columns&lt;br /&gt;
	public int getColumnCount() {&lt;br /&gt;
		return width;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Die Anzahl Vehikel&lt;br /&gt;
	public int getRowCount() {&lt;br /&gt;
		return height;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Die Titel der einzelnen Columns&lt;br /&gt;
	public String getColumnName(int column) {&lt;br /&gt;
		return String.valueOf( column );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Der Wert der Zelle (rowIndex, columnIndex)&lt;br /&gt;
	public Object getValueAt(int rowIndex, int columnIndex) {&lt;br /&gt;
		// bei jedem Aufruf wird dieser Wert um 1 erhöht&lt;br /&gt;
		return new Integer( calls[ columnIndex ][ rowIndex ]++ );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Eine Angabe, welchen Typ von Objekten in den Columns angezeigt werden soll&lt;br /&gt;
	public Class getColumnClass(int columnIndex) {&lt;br /&gt;
		return Integer.class;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public void addTableModelListener(TableModelListener l) {}&lt;br /&gt;
	public void removeTableModelListener(TableModelListener l) {}&lt;br /&gt;
	public boolean isCellEditable(int rowIndex, int columnIndex) {&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
[[Bild:JTabelTutorial6.png]]&lt;br /&gt;
Dieses TableModel zählt für jede Zelle, wie oft sie aufgerufen wurde.&lt;br /&gt;
&lt;br /&gt;
====Ausblick - Eingeben von Daten====&lt;br /&gt;
Es wäre doch schön, wenn der Benutzer auch Daten eingeben könnte.&lt;br /&gt;
Die JTable und das TableModel sind bereits darauf vorbereitet, und es ist nicht viel vonnöten, bis das Beispiel aus 4. veränderbare Vehikel besitzt:&lt;br /&gt;
&lt;br /&gt;
Das Vehicel benötigt noch neue Methoden:&lt;br /&gt;
&amp;lt;code=java&amp;gt;class Vehicel{&lt;br /&gt;
	... // der ganze Rest&lt;br /&gt;
&lt;br /&gt;
	// Diese 4 Methoden müssen dem Vehikel noch hinzugefügt werden:&lt;br /&gt;
	public void setName( String name ){ this.name = name; }&lt;br /&gt;
	public void setPlaces( int places ){ this.places = places; }&lt;br /&gt;
	public void setWheels( int wheels ){ this.wheels = wheels; }&lt;br /&gt;
	public void setHasMotor( boolean motor ){ this.motor = motor; }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Die letzen beiden Methoden von &amp;quot;Model&amp;quot; müssen angepasst werden, so dass auch Daten gesetzt werden können&lt;br /&gt;
&amp;lt;code=java&amp;gt;class Model implements TableModel{&lt;br /&gt;
&lt;br /&gt;
	... // der ganze Rest&lt;br /&gt;
&lt;br /&gt;
	// Die beiden letzten Methoden (siehe 4.) müssen noch verändert werden.&lt;br /&gt;
&lt;br /&gt;
	// Gibt nun an, dass jede Zelle editierbar ist.&lt;br /&gt;
	public boolean isCellEditable(int rowIndex, int columnIndex) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Wird von der JTable aufgerufen, falls in eine Zelle ein neuer Wert gesetzt werden soll&lt;br /&gt;
	// Praktischerweise ist &amp;quot;aValue&amp;quot; ein Objekt desselben Types, welchen wir bei&lt;br /&gt;
	// &amp;quot;public Class getColumnClass(int columnIndex)&amp;quot; zurückgegeben haben (Also String, Integer oder Boolean)&lt;br /&gt;
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {&lt;br /&gt;
		Vehicel vehicel = (Vehicel)vehicels.get( rowIndex );&lt;br /&gt;
		&lt;br /&gt;
		switch( columnIndex ){&lt;br /&gt;
			case 0: &lt;br /&gt;
				vehicel.setName( (String)aValue );&lt;br /&gt;
				break;&lt;br /&gt;
			case 1: &lt;br /&gt;
				vehicel.setPlaces( ((Integer)aValue).intValue() );&lt;br /&gt;
				break;&lt;br /&gt;
			case 2: &lt;br /&gt;
				vehicel.setWheels( ((Integer)aValue).intValue() );&lt;br /&gt;
				break;&lt;br /&gt;
			case 3: &lt;br /&gt;
				vehicel.setHasMotor( ((Boolean)aValue).booleanValue() );&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
[[Bild:JTableTutorial7.png]]&lt;br /&gt;
&lt;br /&gt;
==Breite der Spalten==&lt;br /&gt;
Die Breite der Spalten lässt sich über die Objekte der Klasse TableColumn, die eine Spalte der JTable repräsentiert, verändern.&lt;br /&gt;
Dabei benutzt man nicht die Methode setWidth, sondern die Methode setPreferredWidth.&lt;br /&gt;
Natürlich kann man die Breite der Spalten erst festlegen, nachdem man das Model mit der Anzahl Spalten übergeben hat.&lt;br /&gt;
&lt;br /&gt;
===1. Möglichkeit - Direkt===&lt;br /&gt;
&lt;br /&gt;
Man kann die TableColumns über ihren Titel abrufen.&lt;br /&gt;
&amp;lt;code=java&amp;gt;import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.JScrollPane;&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
&lt;br /&gt;
public class JTableDemo{&lt;br /&gt;
   public static void main( String[] args ){&lt;br /&gt;
      // Die Daten für das Table&lt;br /&gt;
      String[][] data = new String[][]{&lt;br /&gt;
            {&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot;, &amp;quot;d&amp;quot;},&lt;br /&gt;
            {&amp;quot;e&amp;quot;, &amp;quot;f&amp;quot;, &amp;quot;g&amp;quot;, &amp;quot;h&amp;quot;},&lt;br /&gt;
            {&amp;quot;i&amp;quot;, &amp;quot;j&amp;quot;, &amp;quot;k&amp;quot;, &amp;quot;l&amp;quot;}&lt;br /&gt;
      };&lt;br /&gt;
      &lt;br /&gt;
      // Die Column-Titles&lt;br /&gt;
      String[] title = new String[]{&lt;br /&gt;
            &amp;quot;A&amp;quot;, &amp;quot;B&amp;quot;, &amp;quot;C&amp;quot;, &amp;quot;D&amp;quot;&lt;br /&gt;
      };&lt;br /&gt;
      &lt;br /&gt;
      // Das JTable initialisieren&lt;br /&gt;
      JTable table = new JTable( data, title );&lt;br /&gt;
      &lt;br /&gt;
      // Das automatische Neusetzen der Grösse würde das Vorhaben, die Grösse selbst&lt;br /&gt;
      // zu setzen, stören.&lt;br /&gt;
      table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );&lt;br /&gt;
      &lt;br /&gt;
      table.getColumn( &amp;quot;A&amp;quot; ).setPreferredWidth(  20 );&lt;br /&gt;
      table.getColumn( &amp;quot;B&amp;quot; ).setPreferredWidth(  50 );&lt;br /&gt;
      table.getColumn( &amp;quot;C&amp;quot; ).setPreferredWidth(  80 );&lt;br /&gt;
      table.getColumn( &amp;quot;D&amp;quot; ).setPreferredWidth( 110 );&lt;br /&gt;
      &lt;br /&gt;
      JFrame frame = new JFrame( &amp;quot;Demo&amp;quot; );&lt;br /&gt;
      frame.getContentPane().add( new JScrollPane( table ) );&lt;br /&gt;
      frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
      frame.pack();&lt;br /&gt;
      frame.setVisible( true );&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
[[Bild:JTableTutorial8.png]]&lt;br /&gt;
&lt;br /&gt;
===2. Möglichkeit - Mit Indices über das TableColumnModel===&lt;br /&gt;
&lt;br /&gt;
Nicht immer gibt es ein eindeutiges Objekt, welches eine Column identifiziert. Ein simples Beispiel: es wird zweimal derselbe Titel gewählt, oder die Titel sind dynamisch, und man weiss nicht, wann welcher Titel angezeigt wird.&lt;br /&gt;
&lt;br /&gt;
In diesem Fall muss man tiefer in das JTable hineinlangen, um die Columns zu erreichen. Man muss das TableColumnModel befragen.&lt;br /&gt;
&amp;lt;code=java&amp;gt;import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.JScrollPane;&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
import javax.swing.table.DefaultTableColumnModel;&lt;br /&gt;
import javax.swing.table.TableColumnModel;&lt;br /&gt;
&lt;br /&gt;
public class JTableDemo{&lt;br /&gt;
   public static void main( String[] args ){&lt;br /&gt;
      // Die Daten für das Table&lt;br /&gt;
      String[][] data = new String[][]{&lt;br /&gt;
            {&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot;, &amp;quot;d&amp;quot;},&lt;br /&gt;
            {&amp;quot;e&amp;quot;, &amp;quot;f&amp;quot;, &amp;quot;g&amp;quot;, &amp;quot;h&amp;quot;},&lt;br /&gt;
            {&amp;quot;i&amp;quot;, &amp;quot;j&amp;quot;, &amp;quot;k&amp;quot;, &amp;quot;l&amp;quot;}&lt;br /&gt;
      };&lt;br /&gt;
      &lt;br /&gt;
      // Die Column-Titles&lt;br /&gt;
      String[] title = new String[]{&lt;br /&gt;
            &amp;quot;A&amp;quot;, &amp;quot;A&amp;quot;, &amp;quot;A&amp;quot;, &amp;quot;A&amp;quot;&lt;br /&gt;
      };&lt;br /&gt;
      &lt;br /&gt;
      // Das JTable initialisieren&lt;br /&gt;
      JTable table = new JTable( data, title );&lt;br /&gt;
      &lt;br /&gt;
      // Das automatische Neusetzen der Grösse würde das Vorhaben, die Grösse selbst&lt;br /&gt;
      // zu setzen, stören.&lt;br /&gt;
      table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );&lt;br /&gt;
      &lt;br /&gt;
      // Über das TableColumnModel kommt man an die wichtigen Daten&lt;br /&gt;
      TableColumnModel columnModel = table.getColumnModel();&lt;br /&gt;
            &lt;br /&gt;
      // Die einzelnen Columns ansprechen und die Grösse setzen&lt;br /&gt;
      columnModel.getColumn( 0 ).setPreferredWidth( 20 );&lt;br /&gt;
      columnModel.getColumn( 1 ).setPreferredWidth( 50 );&lt;br /&gt;
      columnModel.getColumn( 2 ).setPreferredWidth( 80 );&lt;br /&gt;
      columnModel.getColumn( 3 ).setPreferredWidth( 110 );&lt;br /&gt;
            &lt;br /&gt;
      JFrame frame = new JFrame( &amp;quot;Demo&amp;quot; );&lt;br /&gt;
      frame.getContentPane().add( new JScrollPane( table ) );&lt;br /&gt;
      frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
      frame.pack();&lt;br /&gt;
      frame.setVisible( true );&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
[[Bild:JTableTutorial8.png]]&lt;br /&gt;
&lt;br /&gt;
===3. Der Auto-Resize-Modus===&lt;br /&gt;
&lt;br /&gt;
In den beiden vorangegangen Beispielen wurd der Autoresize-Modus deaktiviert.&lt;br /&gt;
&amp;lt;code=java&amp;gt;table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Wenn man diese Zeile weglässt, versucht das JTable die Grösse der Spalten anzupassen. Dabei benutzt es die Einstellungen der &amp;quot;preferredWidth&amp;quot;, welche man ja verändert hat:&lt;br /&gt;
&lt;br /&gt;
a) mit dem normalen Resize-Mode:&lt;br /&gt;
&lt;br /&gt;
[[Bild:JTableTutorial9.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
b) zum Vergleich, mit deaktiviertem Resize-Mode:&lt;br /&gt;
&lt;br /&gt;
[[Bild:JTableTutorial8.png]]&lt;br /&gt;
&lt;br /&gt;
==Darstellung der Daten==&lt;br /&gt;
&lt;br /&gt;
Bereits in im vorhergehenden Teil hat man gesehen, dass das JTable offenbar mehr kann als nur Text zu zeichnen:&lt;br /&gt;
&lt;br /&gt;
[[Bild:JTableTutorial12.png]]&lt;br /&gt;
&lt;br /&gt;
===1. Das Standardverhalten===&lt;br /&gt;
Mit Hilfe der Methode TableModel#getColumnClass versucht das JTable herauszufinden, wie diese Column am besten dargestellt werden kann.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den Quellcode von JTable verrät, dass Number, Float, Double, Date, Icon, ImageIcon und Boolean eine Spezialbehandlung erhalten.&lt;br /&gt;
&lt;br /&gt;
Sollte ein Object nicht dazu passen, wird die &amp;quot;toString&amp;quot; Methode benutzt.&lt;br /&gt;
&lt;br /&gt;
Demonstrieren wir mal, wie das aussieht:&lt;br /&gt;
&amp;lt;code=java&amp;gt;import java.awt.Color;&lt;br /&gt;
import java.awt.Component;&lt;br /&gt;
import java.awt.Graphics;&lt;br /&gt;
import java.util.Date;&lt;br /&gt;
&lt;br /&gt;
import javax.swing.Icon;&lt;br /&gt;
import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.JScrollPane;&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
import javax.swing.table.AbstractTableModel;&lt;br /&gt;
&lt;br /&gt;
public class JTableDemo{&lt;br /&gt;
   public static void main( String[] args ){&lt;br /&gt;
      // Unser TableModel (siehe unten)&lt;br /&gt;
      Model model = new Model();&lt;br /&gt;
      &lt;br /&gt;
      // Das JTable initialisieren&lt;br /&gt;
      JTable table = new JTable( model );&lt;br /&gt;
      &lt;br /&gt;
      JFrame frame = new JFrame( &amp;quot;Demo&amp;quot; );&lt;br /&gt;
      frame.getContentPane().add( new JScrollPane( table ) );&lt;br /&gt;
      &lt;br /&gt;
      frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
      frame.pack();&lt;br /&gt;
      frame.setVisible( true );&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Ein einfaches Icon, damit man nicht Bilder laden, etc... muss:&lt;br /&gt;
&amp;lt;code=java&amp;gt;class DemoIcon implements Icon{&lt;br /&gt;
	public int getIconHeight() {&lt;br /&gt;
		return 15;&lt;br /&gt;
	}&lt;br /&gt;
	public int getIconWidth() {&lt;br /&gt;
		return 15;&lt;br /&gt;
	}&lt;br /&gt;
	public void paintIcon(Component c, Graphics g, int x, int y) {&lt;br /&gt;
		g.setColor( Color.DARK_GRAY );&lt;br /&gt;
		g.fillOval( x, y, 10, 10 );&lt;br /&gt;
		g.setColor( Color.GREEN );&lt;br /&gt;
		g.fillOval( x+5, y+5, 10, 10 );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Wiedereinmal ein TableModel. Diesmal wird AbstractTableModel als Basisklasse benutzt, denn so muss man weniger Methoden implementieren:&lt;br /&gt;
&amp;lt;code=java&amp;gt;class Model extends AbstractTableModel{&lt;br /&gt;
	private Object[] objects;&lt;br /&gt;
	private Class[] classes;&lt;br /&gt;
	&lt;br /&gt;
   	public Model(){&lt;br /&gt;
   		objects = new Object[]{&lt;br /&gt;
				&amp;quot;Text&amp;quot;,&lt;br /&gt;
				Float.valueOf( 5.123f ),&lt;br /&gt;
				Boolean.valueOf( true ),&lt;br /&gt;
				new Date( System.currentTimeMillis() ),&lt;br /&gt;
				new DemoIcon(),&lt;br /&gt;
				Color.RED&lt;br /&gt;
   		};&lt;br /&gt;
   		&lt;br /&gt;
   		classes = new Class[]{&lt;br /&gt;
				String.class,&lt;br /&gt;
				Float.class,&lt;br /&gt;
				Boolean.class,&lt;br /&gt;
				Date.class,&lt;br /&gt;
				Icon.class,&lt;br /&gt;
				Color.class&lt;br /&gt;
   		};&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Die Anzahl Columns&lt;br /&gt;
   	public int getColumnCount() {&lt;br /&gt;
   		return objects.length;&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Die Anzahl Rows&lt;br /&gt;
   	public int getRowCount() {&lt;br /&gt;
   		return 1;&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Die Titel der einzelnen Columns (Der Name der Klasse die Dargestellt wird)&lt;br /&gt;
   	public String getColumnName(int column) {&lt;br /&gt;
   		return getColumnClass( column ).getName();&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Der Wert der Zelle (rowIndex, columnIndex)&lt;br /&gt;
   	public Object getValueAt(int rowIndex, int columnIndex) {&lt;br /&gt;
   		return objects[ columnIndex ];&lt;br /&gt;
   	}&lt;br /&gt;
&lt;br /&gt;
   	// Eine Angabe, welchen Typ von Objekten in den Columns angezeigt werden soll&lt;br /&gt;
   	public Class getColumnClass(int columnIndex) {&lt;br /&gt;
   		return classes[columnIndex];&lt;br /&gt;
   	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
[[Bild:JTableTutorial13.png]]&lt;br /&gt;
&lt;br /&gt;
Wie man sieht, wurde das Color-Objekt nicht gerade schön dargestellt. Da das JTable nicht wusste, wie es mit einem Color-Objekt umgehen soll, wurde einfach die &amp;quot;toString&amp;quot;-Methode benutzt.&lt;br /&gt;
&lt;br /&gt;
===2. Ein einfacher TableCellRenderer===&lt;br /&gt;
Tabellenzellen werden standardmäßig quasi von {{JAPI|JLabel}} dargestellt. Ein {{JAPI|DefaultTableCellRenderer}} erbt von JLabel und implementiert neben weiteren Interfaces auch {{JAPI|TableCellRenderer}}, welches die Methode &lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
einführt. In seiner einfachsten Variante braucht ein TableCellRenderer nur die setValue()-Methode zu überschreiben. Das empfiehlt sich, wenn man die o.g. Standarddatentypen, wie String, Boolean, Number usw. in ihrer Darstellung, mit den von JLabel angebotenen Möglichkeiten, anpassen möchte. &lt;br /&gt;
&lt;br /&gt;
Wenn eine Zelle ein Color-Objekt darstellen soll, kann die Farbe direkt dargestellt werden:&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
public class ColorTableCellRenderer extends DefaultTableCellRenderer {&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    protected void setValue(Object value) {&lt;br /&gt;
        if (value instanceof Color) { //Wenn das TableModel für diese Zelle ein Color-Objekt zurück gibt&lt;br /&gt;
	    Color color = (Color)value;		&lt;br /&gt;
            setText( color.getRed() + &amp;quot;, &amp;quot; + color.getBlue() + &amp;quot;, &amp;quot; + color.getGreen() );&lt;br /&gt;
	    setBackground( color );&lt;br /&gt;
            setHorizontalAlignment(JLabel.CENTER);&lt;br /&gt;
        } else {&lt;br /&gt;
            super.setValue(value); //ansonsten möchten wir das Verhalten vom DefaultTableCellRenderer&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine weitere Möglichkeit besteht im Überschreiben der Methode getTableCellRendererComponent(), in der die gewünschten Manipulationen programmiert werden.&lt;br /&gt;
Wie kann man dem JTable also nun sagen, dass Color auch speziell angezeigt werden soll?&lt;br /&gt;
Indem man einen TableCellRenderer implementiert, und dem JTable über die Methode JTable#setDefaultRenderer übergibt.&lt;br /&gt;
&lt;br /&gt;
Der Einfachheit halber, wird für das Beispiel ein DefaultTableCellRenderer genommen, und ein bisschen verändert.&lt;br /&gt;
Die bekannte Tabelle mit einem zusätzlichen Befehl&lt;br /&gt;
&amp;lt;code=java&amp;gt;public class JTableDemo{&lt;br /&gt;
   public static void main( String[] args ){&lt;br /&gt;
      // Unser TableModel (siehe unten)&lt;br /&gt;
      Model model = new Model();&lt;br /&gt;
      &lt;br /&gt;
      // Das JTable initialisieren&lt;br /&gt;
      JTable table = new JTable( model );&lt;br /&gt;
      &lt;br /&gt;
      // Hier wird der JTable gesagt, dass Objekte des Types &amp;quot;Color&amp;quot; vom &amp;quot;ColorTableCellRenderer&amp;quot; dargestellt werden&lt;br /&gt;
      table.setDefaultRenderer( Color.class, new ColorTableCellRenderer() );&lt;br /&gt;
      &lt;br /&gt;
      JFrame frame = new JFrame( &amp;quot;Demo&amp;quot; );&lt;br /&gt;
      frame.getContentPane().add( new JScrollPane( table ) );&lt;br /&gt;
      &lt;br /&gt;
      frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
      frame.pack();&lt;br /&gt;
      frame.setVisible( true );&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Das DemoIcon bleibt unverändert:&lt;br /&gt;
&amp;lt;code=java&amp;gt;class DemoIcon implements Icon{&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Auch an &amp;quot;Model&amp;quot; muss nichts verändert werden:&lt;br /&gt;
&amp;lt;code=java&amp;gt;class Model extends AbstractTableModel{&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Und jetzt kommt der neue TableCellRenderer.&lt;br /&gt;
&amp;lt;code=java&amp;gt;class ColorTableCellRenderer extends DefaultTableCellRenderer{&lt;br /&gt;
	public Component getTableCellRendererComponent(JTable table, Object value,&lt;br /&gt;
			boolean isSelected, boolean hasFocus, int row, int column) {&lt;br /&gt;
		super.getTableCellRendererComponent(table, value, isSelected,&lt;br /&gt;
				hasFocus, row, column);&lt;br /&gt;
		&lt;br /&gt;
		Color color = (Color)value;&lt;br /&gt;
		&lt;br /&gt;
		setText( color.getRed() + &amp;quot;, &amp;quot; + color.getBlue() + &amp;quot;, &amp;quot; + color.getGreen() );&lt;br /&gt;
		setForeground( color );&lt;br /&gt;
		&lt;br /&gt;
		return this;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
[[Bild:JTableTutorial14.png]]&lt;br /&gt;
&lt;br /&gt;
Das JTable erwartet von einem TableCellRenderer eine Component, welche genau eine Zelle darstellt. Allerdings wird diese Component nicht für immer behalten, sondern sie muss nur kurz diese Zelle zeichnen, und wird danach nicht mehr benötigt.&lt;br /&gt;
&lt;br /&gt;
Was macht &amp;quot;ColorTableCellRenderer&amp;quot;?&lt;br /&gt;
Sobald das JTable vom ColorTableCellRenderer eine Component haben möchte, ruft es ersteinmal die entsprechende Methode von DefaultTableCellRenderer auf. Dort werden Hintergrundfarbe und Schriftart gesetzt.&lt;br /&gt;
Danach setzt ColorTableCellRenderer einen Text der zu der Farbe passt (die RGB-Werte), und verändert die Schriftfarbe.&lt;br /&gt;
Und dann gibt er sich selbst zurück, denn betrachtet man die API, so sieht man, dass DefaultTableCellRenderer eine Unterklasse von JLabel (und damit auch von Component) ist, und dies deshalb ohne Probleme geht.&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;Wichtig!&#039;&#039;&#039; Es muss nie eine neue Component hergestellt werden, das Schlüsselwort new hat hier nichts verloren.&lt;br /&gt;
&lt;br /&gt;
===3. Alles zum gleichen TableCellRenderer===&lt;br /&gt;
Manchmal möchte man vielleicht mehr Kontrolle über die Art, wie die Zellen dargestellt werden.&lt;br /&gt;
Eine einfache Variante ist folgende: Das TableModel gibt für alle ColumnClasses an, sie seien vom Typ Object. Und für den Typ Object setzt man einen eigenen TableCellRenderer.&lt;br /&gt;
&lt;br /&gt;
Die Tabelle mit anderem TableCellRenderer:&lt;br /&gt;
&amp;lt;code=java&amp;gt;import java.awt.Color;&lt;br /&gt;
import java.awt.Component;&lt;br /&gt;
import java.awt.Graphics;&lt;br /&gt;
import java.util.Date;&lt;br /&gt;
&lt;br /&gt;
import javax.swing.Icon;&lt;br /&gt;
import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.JLabel;&lt;br /&gt;
import javax.swing.JScrollPane;&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
import javax.swing.table.AbstractTableModel;&lt;br /&gt;
import javax.swing.table.TableCellRenderer;&lt;br /&gt;
&lt;br /&gt;
public class JTableDemo{&lt;br /&gt;
   public static void main( String[] args ){&lt;br /&gt;
      // Unser TableModel (siehe unten)&lt;br /&gt;
      Model model = new Model();&lt;br /&gt;
      &lt;br /&gt;
      // Das JTable initialisieren&lt;br /&gt;
      JTable table = new JTable( model );&lt;br /&gt;
&lt;br /&gt;
      // Den Spezial-CellRenderer übergeben.&lt;br /&gt;
      table.setDefaultRenderer( Object.class, new Renderer() );&lt;br /&gt;
            &lt;br /&gt;
      JFrame frame = new JFrame( &amp;quot;Demo&amp;quot; );&lt;br /&gt;
      frame.getContentPane().add( new JScrollPane( table ) );&lt;br /&gt;
      &lt;br /&gt;
      frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
      frame.pack();&lt;br /&gt;
&lt;br /&gt;
      frame.setVisible( true );&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Das DemoIcon bekommt noch die Möglichkeit, andere Farben zu benutzen:&lt;br /&gt;
&amp;lt;code=java&amp;gt;class DemoIcon implements Icon{&lt;br /&gt;
	private Color top, bottom;&lt;br /&gt;
	&lt;br /&gt;
	public DemoIcon( Color top, Color bottom ){&lt;br /&gt;
		this.top = top;&lt;br /&gt;
		this.bottom = bottom;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public int getIconHeight() {&lt;br /&gt;
		return 15;&lt;br /&gt;
	}&lt;br /&gt;
	public int getIconWidth() {&lt;br /&gt;
		return 15;&lt;br /&gt;
	}&lt;br /&gt;
	public void paintIcon(Component c, Graphics g, int x, int y) {&lt;br /&gt;
		g.setColor( top );&lt;br /&gt;
		g.fillOval( x, y, 10, 10 );&lt;br /&gt;
		g.setColor( bottom );&lt;br /&gt;
		g.fillOval( x+5, y+5, 10, 10 );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Das TableModel gibt nun für jede Column an, dass Object&#039;s angezeigt werden&lt;br /&gt;
&amp;lt;code=java&amp;gt;private Object[][] objects;&lt;br /&gt;
	&lt;br /&gt;
   	public Model(){&lt;br /&gt;
   		objects = new Object[][]{&lt;br /&gt;
   				{&amp;quot;Text&amp;quot;,&lt;br /&gt;
				new Float( 5.123f ),&lt;br /&gt;
				new Boolean( true ),&lt;br /&gt;
				new Date( System.currentTimeMillis() ),&lt;br /&gt;
				new DemoIcon( Color.DARK_GRAY, Color.GREEN ),&lt;br /&gt;
				Color.RED},&lt;br /&gt;
				&lt;br /&gt;
   				{&amp;quot;Hallo&amp;quot;,&lt;br /&gt;
				new Double( 531.45 ),&lt;br /&gt;
				new Boolean( false ),&lt;br /&gt;
				new Date( System.currentTimeMillis() + 50000000 ),&lt;br /&gt;
				new DemoIcon( Color.BLUE, Color.GRAY ),&lt;br /&gt;
				Color.CYAN},&lt;br /&gt;
				&lt;br /&gt;
	   			{&amp;quot;Tschau&amp;quot;,&lt;br /&gt;
				new Integer( 123 ),&lt;br /&gt;
				new Boolean( true ),&lt;br /&gt;
				&amp;quot;unbekannt&amp;quot;,&lt;br /&gt;
				new DemoIcon( Color.LIGHT_GRAY, Color.MAGENTA ),&lt;br /&gt;
				Color.PINK}	&lt;br /&gt;
   		};&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Die Anzahl Columns&lt;br /&gt;
   	public int getColumnCount() {&lt;br /&gt;
   		return 6;&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Die Anzahl Rows&lt;br /&gt;
   	public int getRowCount() {&lt;br /&gt;
   		return 3;&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Die Titel der einzelnen Columns&lt;br /&gt;
   	public String getColumnName(int column) {&lt;br /&gt;
   		return String.valueOf( column );&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Der Wert der Zelle (rowIndex, columnIndex)&lt;br /&gt;
   	public Object getValueAt(int rowIndex, int columnIndex) {&lt;br /&gt;
   		return objects[ rowIndex ][ columnIndex ];&lt;br /&gt;
   	}&lt;br /&gt;
&lt;br /&gt;
   	// Eine Angabe, welchen Typ von Objekten in den Columns angezeigt werden soll&lt;br /&gt;
   	public Class getColumnClass(int columnIndex) {&lt;br /&gt;
   		return Object.class;&lt;br /&gt;
   	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Der neue TableCellRenderer entscheidet für jede Zelle einzeln, wie sie dargestellt werden soll.&lt;br /&gt;
&amp;lt;code=java&amp;gt;class Renderer extends JLabel implements TableCellRenderer{&lt;br /&gt;
	private Color colorSelected = new Color( 200, 255, 200 );&lt;br /&gt;
	private Color colorFocus = new Color( 255, 200, 200 );&lt;br /&gt;
	private Color colorNormal = new Color( 200, 200, 255 );&lt;br /&gt;
&lt;br /&gt;
	public Renderer(){&lt;br /&gt;
		setOpaque( true );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public Component getTableCellRendererComponent(JTable table, Object value,&lt;br /&gt;
			boolean isSelected, boolean hasFocus, int row, int column) {&lt;br /&gt;
		&lt;br /&gt;
		// die normalen Farben&lt;br /&gt;
		setForeground( Color.BLACK );&lt;br /&gt;
		if( hasFocus )&lt;br /&gt;
			setBackground( colorFocus );&lt;br /&gt;
		else if( isSelected )&lt;br /&gt;
			setBackground( colorSelected );&lt;br /&gt;
		else&lt;br /&gt;
			setBackground( colorNormal );&lt;br /&gt;
		&lt;br /&gt;
		setText( null );&lt;br /&gt;
		setIcon( null );&lt;br /&gt;
		&lt;br /&gt;
		if( value instanceof Date )&lt;br /&gt;
			setText( ((Date)value).toGMTString() );&lt;br /&gt;
		else if( value instanceof Icon )&lt;br /&gt;
			setIcon( (Icon)value );&lt;br /&gt;
		else if( value instanceof Color ){&lt;br /&gt;
			Color color = (Color)value;&lt;br /&gt;
			setForeground( color );&lt;br /&gt;
			setText( color.getRed() + &amp;quot;, &amp;quot; + color.getGreen() + &amp;quot;, &amp;quot; + color.getBlue() );&lt;br /&gt;
		}&lt;br /&gt;
		else if( value instanceof Boolean ){&lt;br /&gt;
			if( ((Boolean)value).booleanValue() )&lt;br /&gt;
				setText( &amp;quot;yes&amp;quot; );&lt;br /&gt;
			else&lt;br /&gt;
				setText( &amp;quot;no&amp;quot; );&lt;br /&gt;
		}&lt;br /&gt;
		else&lt;br /&gt;
			setText( value.toString() );&lt;br /&gt;
		&lt;br /&gt;
		return this;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
[[Bild:JTableTutorial15.png]]&lt;br /&gt;
&lt;br /&gt;
Man beachte: in Column 3, ganz unten, ist ein String, und kein Date-Object. Da der Renderer für jede Zelle einzeln entscheiden kann, gibt es hier keine Probleme.&lt;br /&gt;
&lt;br /&gt;
===4. Darstellung auf Zeilen- oder Tabellen-Ebene===&lt;br /&gt;
Normalerweise werden Renderer für eine bestimmte Datenklasse oder Datenspalte geschrieben.&lt;br /&gt;
&lt;br /&gt;
Aber wie kann man Zeilen-abhängige oder Tabellen-abhängige Erfordnisse angehen?&lt;br /&gt;
Z.B. wie kann man:&lt;br /&gt;
&lt;br /&gt;
a) Zeilen abwechselnd in einer Tabelle färben&lt;br /&gt;
b) Den Rand der selektierten Zelle ändern&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Am einfachsten geht das indem man die Methode prepareRenderer() der Klasse JTable überschreibt:&lt;br /&gt;
&amp;lt;code=java&amp;gt;import java.awt.*;&lt;br /&gt;
import java.text.*;&lt;br /&gt;
import java.util.*;&lt;br /&gt;
import javax.swing.*;&lt;br /&gt;
import javax.swing.border.*;&lt;br /&gt;
import javax.swing.table.*;&lt;br /&gt;
public class TableRowRendering extends JFrame{&lt;br /&gt;
    public TableRowRendering(){&lt;br /&gt;
        //  Model:&lt;br /&gt;
        Object[] columnNames = {&amp;quot;Type&amp;quot;, &amp;quot;Date&amp;quot;, &amp;quot;Company&amp;quot;, &amp;quot;Shares&amp;quot;, &amp;quot;Price&amp;quot;};&lt;br /&gt;
        Object[][] data =&lt;br /&gt;
        {&lt;br /&gt;
            {&amp;quot;Buy&amp;quot;, new Date(), &amp;quot;IBM&amp;quot;, new Integer(1000), new Double(80.50)},&lt;br /&gt;
            {&amp;quot;Sell&amp;quot;,new Date(), &amp;quot;MicroSoft&amp;quot;, new Integer(2000), new Double(6.25)},&lt;br /&gt;
            {&amp;quot;Sell&amp;quot;,new Date(), &amp;quot;Apple&amp;quot;, new Integer(3000), new Double(7.35)},&lt;br /&gt;
            {&amp;quot;Buy&amp;quot;, new Date(), &amp;quot;Nortel&amp;quot;, new Integer(4000), new Double(20.00)}&lt;br /&gt;
        };&lt;br /&gt;
        DefaultTableModel model = new DefaultTableModel(data, columnNames) {&lt;br /&gt;
            public Class getColumnClass(int column) {&lt;br /&gt;
                return getValueAt(0, column).getClass();&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
        // prepareRenderer überschreiben:&lt;br /&gt;
        table = new JTable( model ) {&lt;br /&gt;
            public Component prepareRenderer(&lt;br /&gt;
                    TableCellRenderer renderer, int row, int column) {&lt;br /&gt;
                Component c = super.prepareRenderer(renderer, row, column);&lt;br /&gt;
                if (!isRowSelected(row)) {&lt;br /&gt;
                    String type = (String)getModel().getValueAt(row, 0);&lt;br /&gt;
                    c.setBackground(row % 2 == 0 ? null : Color.LIGHT_GRAY );&lt;br /&gt;
                }&lt;br /&gt;
                if (isRowSelected(row) &amp;amp;&amp;amp; isColumnSelected(column))&lt;br /&gt;
                    ((JComponent)c).setBorder(selected);&lt;br /&gt;
                return c;&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
        table.setPreferredScrollableViewportSize(table.getPreferredSize());&lt;br /&gt;
        getContentPane().add(new JScrollPane( table ), BorderLayout.CENTER);&lt;br /&gt;
    }&lt;br /&gt;
    private JTable table;&lt;br /&gt;
    private Border selected = new LineBorder(Color.GREEN);&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        TableRowRendering frame = new TableRowRendering();&lt;br /&gt;
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );&lt;br /&gt;
        frame.pack();&lt;br /&gt;
        frame.setLocationRelativeTo( null );&lt;br /&gt;
        frame.setVisible(true);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===5. Wichtige Bemerkung===&lt;br /&gt;
Man sollte &#039;&#039;niemals&#039;&#039; einen Code schreiben, der so aussieht&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
public class Renderer implements TableCellRenderer {&lt;br /&gt;
&lt;br /&gt;
	[...]&lt;br /&gt;
&lt;br /&gt;
	public Component getTableCellRendererComponent(JTable table, Object value, &lt;br /&gt;
		boolean isSelected, boolean hasFocus, int row, int column) {&lt;br /&gt;
      &lt;br /&gt;
		JLabel label = new JLabel();  // FALSCH&lt;br /&gt;
&lt;br /&gt;
		[...]&lt;br /&gt;
&lt;br /&gt;
		return label;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Wieso nicht? Weil man &#039;&#039;immer wieder dieselbe Component verwenden kann&#039;&#039;. Denn das JTable ruft die getTableCellRendererComponent-Methode auf, und ruft gleich anschliessend den paint-Befehl der erhaltenen Component auf. Erst danach wird die &amp;quot;nächste&amp;quot; Component geholt.&lt;br /&gt;
&lt;br /&gt;
Es ist wie das Tragen von Wasser: entweder läuft man mit einem Eimer zum Fluss, wieder zurück und wirft denn Eimer dann fort (weil er ja gebraucht ist), kauft sich dann einen neuen; &#039;&#039;oder&#039;&#039; man läuft mit demselben Eimer zurück zum Fluss. Ziemlich offensichtlich, dass die zweite Variante die bessere ist.&lt;br /&gt;
&lt;br /&gt;
==Verändern von Daten==&lt;br /&gt;
&lt;br /&gt;
Am Ende des 2. Teils wurde gezeigt, dass man auch Daten eingeben kann. Jetzt soll das nocheinmal vertieft behandelt werden.&lt;br /&gt;
&lt;br /&gt;
Damit eine Zelle editiert werden kann, müssen die folgenden zwei Methoden im TableModel korrekt implementiert werden. Als Beispiel zeigen wir die Implementationen aus dem &amp;quot;DefaultTableModel&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code=java&amp;gt;    public boolean isCellEditable(int row, int column) {&lt;br /&gt;
        return true;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&amp;lt;code=java&amp;gt;    public void setValueAt(Object aValue, int row, int column) {&lt;br /&gt;
        Vector rowVector = (Vector)dataVector.elementAt(row);&lt;br /&gt;
        rowVector.setElementAt(aValue, column);&lt;br /&gt;
        fireTableCellUpdated(row, column);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei dem Versuch, eine Zelle zu editieren, ruft das System zunächst die Methode &amp;quot;TableModel#isCellEditable&amp;quot; auf. Gibt sie &amp;quot;false&amp;quot; zurück, ist ein Editieren dieser Zelle nicht möglich. Gibt sie &amp;quot;true&amp;quot; zurück, kann der Wert der Zelle verändert werden. Wenn das geschehen ist, muss der neue Wert aber noch im TableModel abgespeichert werden. Dazu ruft das System automatisch die Methode &amp;quot;TableModel#setValueAt&amp;quot; auf und übergibt ihr den neuen Wert der Zelle. Die Methode &amp;quot;setValueAt&amp;quot; ist dann dafür verantwortlich, diesen Wert im TableModel abzuspeichern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===1. Der einfache Weg===&lt;br /&gt;
&lt;br /&gt;
Das JTable unterstützt von sich aus das Editieren von Zahlen und von Booleans. Alles andere wird wie ein String behandelt, d.h. da der Benutzer nur einen Text eingeben kann, wird dem Model ein String übergeben, welches es selbst in ein Objekt übersetzen muss.&lt;br /&gt;
&lt;br /&gt;
Die Verwendung der Table-eigenen Editoren ist einfach:&lt;br /&gt;
&lt;br /&gt;
Zuerst die Tabelle&lt;br /&gt;
&amp;lt;code=java&amp;gt;import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.JScrollPane;&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
import javax.swing.table.AbstractTableModel;&lt;br /&gt;
&lt;br /&gt;
public class JTableDemo{&lt;br /&gt;
   public static void main( String[] args ){&lt;br /&gt;
      // Unser TableModel (siehe unten)&lt;br /&gt;
      Model model = new Model();&lt;br /&gt;
      &lt;br /&gt;
      // Das JTable initialisieren&lt;br /&gt;
      JTable table = new JTable( model );&lt;br /&gt;
            &lt;br /&gt;
      JFrame frame = new JFrame( &amp;quot;Demo&amp;quot; );&lt;br /&gt;
      frame.getContentPane().add( new JScrollPane( table ) );&lt;br /&gt;
      &lt;br /&gt;
      frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
      frame.pack();&lt;br /&gt;
      frame.setVisible( true );&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Jetzt das Model. Jede Zelle ist editierbar, doch jede Column wird anders behandelt.&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
class Model extends AbstractTableModel{&lt;br /&gt;
	private String[] strings;&lt;br /&gt;
	private int[] integers;&lt;br /&gt;
	private double[] doubles;&lt;br /&gt;
	private boolean[] booleans;&lt;br /&gt;
	&lt;br /&gt;
   	public Model(){&lt;br /&gt;
   		strings = new String[]{ &amp;quot;hallo&amp;quot;, &amp;quot;ich&amp;quot;, &amp;quot;bin&amp;quot;, &amp;quot;eine&amp;quot;, &amp;quot;Demo&amp;quot; };&lt;br /&gt;
   		integers = new int[]{ 1, 2, 3, 4, 5 };&lt;br /&gt;
   		doubles = new double[]{ 1.2, 3.4, 5.6, 7.8, 9.11 };&lt;br /&gt;
   		booleans = new boolean[]{ true, false, false, true, true };&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Die Anzahl Columns&lt;br /&gt;
   	public int getColumnCount() {&lt;br /&gt;
   		return 4;&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Die Anzahl Rows&lt;br /&gt;
   	public int getRowCount() {&lt;br /&gt;
   		return 5;&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Die Titel der einzelnen Columns&lt;br /&gt;
   	public String getColumnName(int column) {&lt;br /&gt;
   		switch( column ){&lt;br /&gt;
   			case 0: return &amp;quot;String&amp;quot;;&lt;br /&gt;
   			case 1: return &amp;quot;Integer&amp;quot;;&lt;br /&gt;
   			case 2: return &amp;quot;Double&amp;quot;;&lt;br /&gt;
   			case 3: return &amp;quot;Boolean&amp;quot;;&lt;br /&gt;
   			default: return null;&lt;br /&gt;
   		}&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Der Wert der Zelle (rowIndex, columnIndex)&lt;br /&gt;
   	public Object getValueAt(int rowIndex, int columnIndex) {&lt;br /&gt;
   		switch( columnIndex ){&lt;br /&gt;
   			case 0: return strings[ rowIndex ];&lt;br /&gt;
   			case 1: return new Integer( integers[ rowIndex ] );&lt;br /&gt;
   			case 2: return new Double( doubles[ rowIndex ] );&lt;br /&gt;
   			case 3: return new Boolean( booleans[ rowIndex ] );&lt;br /&gt;
   			default: return null;&lt;br /&gt;
   		}&lt;br /&gt;
   	}&lt;br /&gt;
&lt;br /&gt;
   	// Eine Angabe, welchen Typ von Objekten in den Columns angezeigt werden soll&lt;br /&gt;
   	public Class getColumnClass(int columnIndex) {&lt;br /&gt;
   		switch( columnIndex ){&lt;br /&gt;
   			case 0: return String.class;&lt;br /&gt;
   			case 1: return Integer.class;&lt;br /&gt;
   			case 2: return Double.class;&lt;br /&gt;
   			case 3: return Boolean.class;&lt;br /&gt;
   			default: return null;&lt;br /&gt;
   		}&lt;br /&gt;
   	}&lt;br /&gt;
   	&lt;br /&gt;
   	// Jede Zelle ist editierbar&lt;br /&gt;
	public boolean isCellEditable(int rowIndex, int columnIndex) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Wird aufgerufen, falls der Wert einer Zelle verändert wurde&lt;br /&gt;
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {&lt;br /&gt;
		switch( columnIndex ){&lt;br /&gt;
			case 0:&lt;br /&gt;
				strings[ rowIndex ] = aValue.toString();&lt;br /&gt;
				break;&lt;br /&gt;
			case 1:&lt;br /&gt;
				integers[ rowIndex ] = ((Integer)aValue).intValue();&lt;br /&gt;
				break;&lt;br /&gt;
			case 2:&lt;br /&gt;
				doubles[ rowIndex ] = ((Double)aValue).doubleValue();&lt;br /&gt;
				break;&lt;br /&gt;
			case 3:&lt;br /&gt;
				booleans[ rowIndex ] = ((Boolean)aValue).booleanValue();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
[[Bild:JTableTutorial14.png]]&lt;br /&gt;
Es wichtig, dass man nicht vergisst, dass dies ausschliesslich für Strings (oder Objekte die als String dargestellt werden können, z.B. ein Datum), Nummern und Booleans so funktioniert!&lt;br /&gt;
&lt;br /&gt;
===2. Mit Hilfe eines TableCellEditors===&lt;br /&gt;
Es ist möglich, eigene Editoren einzusetzen. Die Editoren werden vom JTable mit allen möglichen Informationen versorgt, welche sie irgendwie darstellen müssen. Die JTable wird dann warten, bis der Editor meldet, dass alle Daten eingegeben wurden.&lt;br /&gt;
&lt;br /&gt;
Zuerst wird ein JTable aufgesetzt. Mit &amp;quot;setDefaultEditor&amp;quot; wird ein Editor mit einem Typ verbunden. Z.B. könnte der IntegerEditor mit &amp;quot;Integer.class&amp;quot; verbunden werden. Der Typ bezieht sich auf die Rückgabe von TableModel.getColumnClass.&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
import java.awt.Color;&lt;br /&gt;
import java.awt.Component;&lt;br /&gt;
import java.awt.event.MouseEvent;&lt;br /&gt;
import java.util.ArrayList;&lt;br /&gt;
import java.util.EventObject;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
&lt;br /&gt;
import javax.swing.*;&lt;br /&gt;
import javax.swing.event.CellEditorListener;&lt;br /&gt;
import javax.swing.event.ChangeEvent;&lt;br /&gt;
import javax.swing.event.DocumentEvent;&lt;br /&gt;
import javax.swing.event.DocumentListener;&lt;br /&gt;
import javax.swing.table.DefaultTableModel;&lt;br /&gt;
import javax.swing.table.TableCellEditor;&lt;br /&gt;
&lt;br /&gt;
public class JTableDemo{&lt;br /&gt;
    public static void main( String[] args ){&lt;br /&gt;
        // Einige Testdaten generieren&lt;br /&gt;
        DefaultTableModel model = new DefaultTableModel( new Object[]{ &amp;quot;A&amp;quot;, &amp;quot;B&amp;quot; }, 0);&lt;br /&gt;
        model.addRow( new Object[]{ &amp;quot;1&amp;quot;, &amp;quot;2&amp;quot; });&lt;br /&gt;
        model.addRow( new Object[]{ &amp;quot;3&amp;quot;, &amp;quot;4&amp;quot; });&lt;br /&gt;
        model.addRow( new Object[]{ &amp;quot;5&amp;quot;, &amp;quot;6&amp;quot; });&lt;br /&gt;
        model.addRow( new Object[]{ &amp;quot;7&amp;quot;, &amp;quot;8&amp;quot; });&lt;br /&gt;
        JTable table = new JTable( model );&lt;br /&gt;
        // Den TestEditor einbinden. Er wird alle Spalten die als Typ&lt;br /&gt;
        // &amp;quot;Object&amp;quot; haben, bearbeiten.&lt;br /&gt;
        table.setDefaultEditor( Object.class, new TestEditor());&lt;br /&gt;
        &lt;br /&gt;
        // Die Tabelle anzeigen&lt;br /&gt;
        JFrame frame = new JFrame();&lt;br /&gt;
        frame.add( new JScrollPane( table ));&lt;br /&gt;
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
        frame.pack();&lt;br /&gt;
        frame.setLocationRelativeTo( null );&lt;br /&gt;
        frame.setVisible( true );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Der Editor selbst ist eine ziemlich unabhängige Komponente. Oft ist es am einfachsten, direkt von einer Component zu erben, und zusätzlich das Interface TableCellEditor zu implementieren.&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
//Der Editor selbst ist ein einfaches JTextField&lt;br /&gt;
class TestEditor extends JTextField implements TableCellEditor, DocumentListener{&lt;br /&gt;
    private List&amp;lt;CellEditorListener&amp;gt; listeners = new ArrayList&amp;lt;CellEditorListener&amp;gt;();&lt;br /&gt;
    &lt;br /&gt;
    public TestEditor(){&lt;br /&gt;
        // Der Editor hört sich selbst ab, so kann er auf jede Benutzereingabe reagieren&lt;br /&gt;
        getDocument().addDocumentListener( this );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column ) {&lt;br /&gt;
        // Diese Methode wird von der JTable aufgerufen, wenn der Editor angezeigt werden soll&lt;br /&gt;
        setText( value.toString() );&lt;br /&gt;
        return this;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void addCellEditorListener( CellEditorListener l ) {&lt;br /&gt;
        listeners.add( l );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void cancelCellEditing() {&lt;br /&gt;
        // Falls abgebrochen wird, werden alle Listeners informiert&lt;br /&gt;
        ChangeEvent event = new ChangeEvent( this );&lt;br /&gt;
        for( CellEditorListener listener : listeners.toArray( new CellEditorListener[ listeners.size() ] ))&lt;br /&gt;
            listener.editingCanceled( event );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public Object getCellEditorValue() {&lt;br /&gt;
        // Gibt den aktuellen Wert des Editors zurück&lt;br /&gt;
        return getText();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public boolean isCellEditable( EventObject anEvent ) {&lt;br /&gt;
        // Im Falle eines MouseEvents, muss ein Doppelklick erfolgen, um den Editor zu aktivieren.&lt;br /&gt;
        // Ansonsten wird der Editor auf jeden Fall aktiviert&lt;br /&gt;
        if( anEvent instanceof MouseEvent )&lt;br /&gt;
            return ((MouseEvent)anEvent).getClickCount() &amp;gt; 1;&lt;br /&gt;
            &lt;br /&gt;
        return true;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void removeCellEditorListener( CellEditorListener l ) {&lt;br /&gt;
        listeners.remove( l );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public boolean shouldSelectCell( EventObject anEvent ) {&lt;br /&gt;
        return true;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public boolean stopCellEditing() {&lt;br /&gt;
        // Sollte die Eingabe falsch sein, darf das editieren nich gestoppt werden&lt;br /&gt;
        if( !isValidText() )&lt;br /&gt;
            return false;&lt;br /&gt;
        &lt;br /&gt;
        // Ansonsten werden die Listener vom stop unterrichtet&lt;br /&gt;
        ChangeEvent event = new ChangeEvent( this );&lt;br /&gt;
        for( CellEditorListener listener : listeners.toArray( new CellEditorListener[ listeners.size() ] ))&lt;br /&gt;
            listener.editingStopped( event );&lt;br /&gt;
        &lt;br /&gt;
        return true;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void changedUpdate( DocumentEvent e ) {&lt;br /&gt;
        update();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void insertUpdate( DocumentEvent e ) {&lt;br /&gt;
        update();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void removeUpdate( DocumentEvent e ) {&lt;br /&gt;
        update();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    private boolean isValidText(){&lt;br /&gt;
        // Bestimmt, was eine gültige Eingabe ist.&lt;br /&gt;
        return getText().matches( &amp;quot;[1-9]+&amp;quot; );&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public void update(){&lt;br /&gt;
        // Verändert die Umrandung des Editors, jenachdem, ob eine gültige&lt;br /&gt;
        // oder eine ungültige Eingabe gemacht wurde&lt;br /&gt;
        Color color;&lt;br /&gt;
        if( isValidText() )&lt;br /&gt;
            color = Color.GREEN;&lt;br /&gt;
        else&lt;br /&gt;
            color = Color.RED;&lt;br /&gt;
        &lt;br /&gt;
        setBorder( BorderFactory.createLineBorder( color ));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
===3. TableCellEditor für eigene Typen===&lt;br /&gt;
Schon in Teil 3 wurde gezeigt, dass das JTable Objekte des Types &amp;quot;Date&amp;quot; nicht richtig unterstützt. Das soll jetzt geändert werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, man beachte, dass ein &amp;quot;DateRenderer&amp;quot; und ein &amp;quot;DateEditor&amp;quot; registriert werden.&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
import java.awt.Component;&lt;br /&gt;
import java.text.DateFormat;&lt;br /&gt;
import java.util.Calendar;&lt;br /&gt;
import java.util.Date;&lt;br /&gt;
import java.util.EventObject;&lt;br /&gt;
import java.util.Vector;&lt;br /&gt;
&lt;br /&gt;
import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.JScrollPane;&lt;br /&gt;
import javax.swing.JSpinner;&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
import javax.swing.SpinnerDateModel;&lt;br /&gt;
import javax.swing.event.CellEditorListener;&lt;br /&gt;
import javax.swing.event.ChangeEvent;&lt;br /&gt;
import javax.swing.table.AbstractTableModel;&lt;br /&gt;
import javax.swing.table.DefaultTableCellRenderer;&lt;br /&gt;
import javax.swing.table.TableCellEditor;&lt;br /&gt;
&lt;br /&gt;
public class JTableDemo{&lt;br /&gt;
   public static void main( String[] args ){&lt;br /&gt;
      // Unser TableModel (siehe unten)&lt;br /&gt;
      Model model = new Model();&lt;br /&gt;
      &lt;br /&gt;
      // Das JTable initialisieren&lt;br /&gt;
      JTable table = new JTable( model );&lt;br /&gt;
      &lt;br /&gt;
      // Renderer und Editor für &amp;quot;Date&amp;quot; werden registriert&lt;br /&gt;
      table.setDefaultRenderer( Date.class, new DateRenderer() );&lt;br /&gt;
      table.setDefaultEditor( Date.class, new DateEditor() );&lt;br /&gt;
            &lt;br /&gt;
      JFrame frame = new JFrame( &amp;quot;Demo&amp;quot; );&lt;br /&gt;
      frame.getContentPane().add( new JScrollPane( table ) );&lt;br /&gt;
      &lt;br /&gt;
      frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
      frame.pack();&lt;br /&gt;
      frame.setVisible( true );&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Tabelle soll was sinnvolles darstellen: Notizen die aus einem Datum und aus einem Ereignis bestehen&lt;br /&gt;
&amp;lt;code=java&amp;gt;// Eine einfache Klasse die Notizen beschreibt&lt;br /&gt;
class Note{&lt;br /&gt;
	private Date date;&lt;br /&gt;
	private String event;&lt;br /&gt;
	&lt;br /&gt;
	public Note( String event, Date date ){&lt;br /&gt;
		setEvent( event );&lt;br /&gt;
		setDate( date );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public String getEvent(){ return event; }&lt;br /&gt;
	public Date getDate(){ return date; }&lt;br /&gt;
	&lt;br /&gt;
	public void setEvent( String event ){ this.event = event; }&lt;br /&gt;
	public void setDate( Date date ){ this.date = date; }&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das TableModel, man beachte, dass es keine Verbindungen zum Renderer oder zum Editor besitzt! Allerdings kann durch das Wissen, dass &amp;quot;Date&amp;quot; nun unterstützt wird, in der Methode &amp;quot;setValueAt&amp;quot; ein Cast &amp;quot;Object -&amp;gt; Date&amp;quot; durchgeführt werden.&lt;br /&gt;
&amp;lt;code=java&amp;gt;class Model extends AbstractTableModel{&lt;br /&gt;
	private Note[] notes;&lt;br /&gt;
	&lt;br /&gt;
   	public Model(){&lt;br /&gt;
   		notes = new Note[]{&lt;br /&gt;
   				new Note( &amp;quot;Mit Hund rausgehen&amp;quot;, new Date(  104, 5, 2, 14, 0 ) ),&lt;br /&gt;
				new Note( &amp;quot;Kino&amp;quot;, new Date( 104, 5, 7, 21, 30 ) ),&lt;br /&gt;
				new Note( &amp;quot;Abschlussprüfung&amp;quot;, new Date( 104, 8, 14, 7, 0 ) ),&lt;br /&gt;
				new Note( &amp;quot;Einkaufen gehen&amp;quot;, new Date( 104, 5, 2, 16, 0 ) ),&lt;br /&gt;
				new Note( &amp;quot;Rechnung bezahlen&amp;quot;, new Date( 110, 11, 30, 23, 59 ) ),&lt;br /&gt;
   		};&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Die Anzahl Columns&lt;br /&gt;
   	public int getColumnCount() {&lt;br /&gt;
   		return 2;&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Die Anzahl Rows&lt;br /&gt;
   	public int getRowCount() {&lt;br /&gt;
   		return 5;&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Die Titel der einzelnen Columns&lt;br /&gt;
   	public String getColumnName(int column) {&lt;br /&gt;
   		if( column == 0 )&lt;br /&gt;
   			return &amp;quot;Ereignis&amp;quot;;&lt;br /&gt;
   		else&lt;br /&gt;
   			return &amp;quot;Datum&amp;quot;;&lt;br /&gt;
   	}&lt;br /&gt;
   &lt;br /&gt;
   	// Der Wert der Zelle (rowIndex, columnIndex)&lt;br /&gt;
   	public Object getValueAt(int rowIndex, int columnIndex) {&lt;br /&gt;
   		if( columnIndex == 0 )&lt;br /&gt;
   			return notes[ rowIndex ].getEvent();&lt;br /&gt;
   		else&lt;br /&gt;
   			return notes[ rowIndex ].getDate();&lt;br /&gt;
   	}&lt;br /&gt;
&lt;br /&gt;
   	// Eine Angabe, welchen Typ von Objekten in den Columns angezeigt werden soll&lt;br /&gt;
   	public Class getColumnClass(int columnIndex) {&lt;br /&gt;
   		if( columnIndex == 0 )&lt;br /&gt;
   			return String.class;&lt;br /&gt;
   		else&lt;br /&gt;
   			return Date.class;&lt;br /&gt;
   	}&lt;br /&gt;
   	&lt;br /&gt;
   	// Jede Zelle ist editierbar&lt;br /&gt;
	public boolean isCellEditable(int rowIndex, int columnIndex) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Wird aufgerufen, falls der Wert einer Zelle verändert wurde&lt;br /&gt;
	// Der Wert kommt entweder als String, oder von dem &lt;br /&gt;
	// DateEditor (und daher als Date). &lt;br /&gt;
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {&lt;br /&gt;
		if( columnIndex == 0 )&lt;br /&gt;
			notes[ rowIndex ].setEvent( (String)aValue );&lt;br /&gt;
		else&lt;br /&gt;
			notes[ rowIndex ].setDate( (Date)aValue );&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Der Renderer, der &amp;quot;Date&amp;quot; auf eine brauchbare Art darstellt ist einfach gehalten:&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
class DateRenderer extends DefaultTableCellRenderer{&lt;br /&gt;
	private DateFormat format; &lt;br /&gt;
	&lt;br /&gt;
	public DateRenderer(){&lt;br /&gt;
		format = DateFormat.getDateTimeInstance();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public Component getTableCellRendererComponent(JTable table, Object value,&lt;br /&gt;
			boolean isSelected, boolean hasFocus, int row, int column) {&lt;br /&gt;
&lt;br /&gt;
		// Date&#039;s werden auf einem einfache Weg in lesbare Texte umgewandelt.&lt;br /&gt;
		String text = format.format( (Date)value );&lt;br /&gt;
		&lt;br /&gt;
		return super.getTableCellRendererComponent(table, text, isSelected,&lt;br /&gt;
				hasFocus, row, column);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Der Editor. Der Editor erbt von JSpinner. Glücklicherweise unterstützt der JSpinner &amp;quot;Date&amp;quot;, und so kann man das meiste an den JSpinner delegieren&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
class DateEditor extends JSpinner implements TableCellEditor{&lt;br /&gt;
	private SpinnerDateModel model;&lt;br /&gt;
	&lt;br /&gt;
	private List listeners = new ArrayList();&lt;br /&gt;
	&lt;br /&gt;
	// Standardkonstruktor&lt;br /&gt;
	public DateEditor(){&lt;br /&gt;
		model = new SpinnerDateModel();&lt;br /&gt;
		model.setCalendarField( Calendar.DAY_OF_YEAR );&lt;br /&gt;
		setModel( model );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Möglicherweise möchte jemand über Ereignisse des Editors&lt;br /&gt;
	// informiert werden&lt;br /&gt;
	public void addCellEditorListener(CellEditorListener l) {&lt;br /&gt;
		listeners.add( l );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Ein CellEditorListener entfernen&lt;br /&gt;
	public void removeCellEditorListener(CellEditorListener l) {&lt;br /&gt;
		listeners.remove( l );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Gibt den aktuellen Wert des Editors zurück.&lt;br /&gt;
	public Object getCellEditorValue() {&lt;br /&gt;
		return model.getDate();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Gibt eine Component zurück, welche auf dem JTable dargestellt wird,&lt;br /&gt;
	// und mit der der Benutzer interagieren kann.&lt;br /&gt;
	public Component getTableCellEditorComponent(JTable table, Object value,&lt;br /&gt;
			boolean isSelected, int row, int column) {&lt;br /&gt;
		&lt;br /&gt;
		model.setValue( value );&lt;br /&gt;
		return this;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Gibt an, ob die Zelle editierbar ist. Das EventObject kann&lt;br /&gt;
	// ein MouseEvent, ein KeyEvent oder sonst was sein.&lt;br /&gt;
	public boolean isCellEditable(EventObject anEvent) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Gibt an, ob die Editor-Component selektiert werden muss, um&lt;br /&gt;
	// sie zu benutzen. Diese Editor soll immer selektiert werden,&lt;br /&gt;
	// deshalb wird hier true zurückgegeben&lt;br /&gt;
	public boolean shouldSelectCell(EventObject anEvent) {&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Bricht das editieren der Zelle ab&lt;br /&gt;
	public void cancelCellEditing() {&lt;br /&gt;
		fireEditingCanceled();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Stoppt das editieren der Zelle, sofern möglich.&lt;br /&gt;
	// Da der JSpinner immer einen gültigen Wert anzeigt, kann auch &lt;br /&gt;
	// jederzeit gestoppt werden (return-Wert = true)&lt;br /&gt;
	public boolean stopCellEditing() {&lt;br /&gt;
		fireEditingStopped();&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Benachrichtig alle Listener, dass das Editieren abgebrochen wurde&lt;br /&gt;
	protected void fireEditingCanceled(){&lt;br /&gt;
		ChangeEvent e = new ChangeEvent( this );&lt;br /&gt;
		for( int i = 0, n = listeners.size(); i&amp;lt;n; i++ )&lt;br /&gt;
			((CellEditorListener)listeners.get( i )).editingCanceled( e );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Benachrichtig alle Listener, dass das Editieren beendet wurde&lt;br /&gt;
	protected void fireEditingStopped(){&lt;br /&gt;
		ChangeEvent e = new ChangeEvent( this );&lt;br /&gt;
		for( int i = 0, n = listeners.size(); i&amp;lt;n; i++ )&lt;br /&gt;
			((CellEditorListener)listeners.get( i )).editingStopped( e );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
[[Bild:JTableTutorial15.png]]&lt;br /&gt;
Also: der Editor ist eine Component die auf das JTable gesetzt wird, einen bestimmten Wert zugewiesen bekommt, und diesen Wert verändern darf. Klickt der Benutzer an eine andere Stelle, wird das Editieren entweder abgebrochen (cancelCellEditing) oder beendet (stopCellEditing), und der Wert dem TableModel über die Methode setValueAt überwiesen.&lt;br /&gt;
&lt;br /&gt;
==JTableHeader, TableColumn und das TableColumnModel==&lt;br /&gt;
&lt;br /&gt;
===JTableHeader===&lt;br /&gt;
Der JTableHeader ist ein Component, der die Darstellung der Tabellenspalten einer JTable übernimmt. Meistens braucht an diesen Component nicht, da JTable ihn standardmäßig mitinstantiiert. Die beiden Methoden getTableHeader() und setTableHeader() in JTable bieten an mit dem JTableHeader zu arbeiten. JTableHeader ist nicht dazu da um Spalten hinzuzufügen oder zu entfernen, sondern nur für die Darstellung zuständig. Für die Daten der Spalten ist das TableColumnModel zuständig, welches man wahlweise der JTable oder dem JTableHeader übergeben kann.&lt;br /&gt;
&lt;br /&gt;
JTableHeader, in javax.swing.table, bietet einige interessante Methode an um die Spalten zu manipulieren. Die gebräuchlichsten beiden Methoden sind, finde ich, setReorderingAllowed(boolean reorderingAllowed) und setResizingAllowed(boolean resizingAllowed). Sie sollten selbsterklärend sein. Hier ein kleiens Beispielprogramm:&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
import javax.swing.*;&lt;br /&gt;
import javax.swing.table.JTableHeader;&lt;br /&gt;
import javax.swing.table.DefaultTableColumnModel;&lt;br /&gt;
import javax.swing.table.TableColumnModel;&lt;br /&gt;
import javax.swing.table.TableColumn;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class TableHeaderTest {&lt;br /&gt;
	&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		// JTable initialisieren und mit Inhalt füllen; siehe dazu Teil 2&lt;br /&gt;
		JTable table = new JTable(new String[][]{{&amp;quot;1&amp;quot;, &amp;quot;2&amp;quot;, &amp;quot;3&amp;quot;},{&amp;quot;4&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;6&amp;quot;}}, new String[]{&amp;quot;A&amp;quot;, &amp;quot;B&amp;quot;, &amp;quot;C&amp;quot;});&lt;br /&gt;
		&lt;br /&gt;
		// JTableHeader holen&lt;br /&gt;
		JTableHeader header = table.getTableHeader();&lt;br /&gt;
		&lt;br /&gt;
		// ColumnModel holen:&lt;br /&gt;
		TableColumnModel columnModel = header.getColumnModel();&lt;br /&gt;
		&lt;br /&gt;
		// TableColumn erstellen&lt;br /&gt;
		TableColumn aColumn = new TableColumn();&lt;br /&gt;
		// setHeaderValue() setzt den Titel&lt;br /&gt;
		aColumn.setHeaderValue(&amp;quot;D&amp;quot;);&lt;br /&gt;
		// modelIndex zeigt an von welcher Spalte im DatenModel die neue Spalte ihre Werte holen soll&lt;br /&gt;
		aColumn.setModelIndex(1); // Index 1 im Model sind also &amp;quot;2&amp;quot; und &amp;quot;5&amp;quot;&lt;br /&gt;
		columnModel.addColumn(aColumn);&lt;br /&gt;
		&lt;br /&gt;
		// eine spalte verschieben&lt;br /&gt;
		columnModel.moveColumn(0, 2); // Spalte 0 (mit Titel &amp;quot;A&amp;quot;) verschieben an Position 2 im Model&lt;br /&gt;
		&lt;br /&gt;
		// Spalten nicht resizable machen, nicht zulassen dass die Spaltenreihenfolge geändert werden kann&lt;br /&gt;
		header.setResizingAllowed(false);&lt;br /&gt;
		header.setReorderingAllowed(false);&lt;br /&gt;
		&lt;br /&gt;
		// JFrame konstruieren&lt;br /&gt;
		JFrame frame = new JFrame(&amp;quot;JTableHeader test&amp;quot;);&lt;br /&gt;
		// Table in JScrollPane einfügen und dem Frame hinzufügen&lt;br /&gt;
		frame.getContentPane().add(new JScrollPane(table));&lt;br /&gt;
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);&lt;br /&gt;
		frame.pack();&lt;br /&gt;
		frame.setVisible(true);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
[[Bild:JTableTutorial15.png]]&lt;br /&gt;
Erklärung:&lt;br /&gt;
Zuerst wird die Tabelle ganz normal angelegt, dann holt sich das Programm den JTableHeader der Tabelle. Vom TableHeader das DolumnModel, was aber auch direkt über die JTable gehen würde. Dann wird eine Spalte hinzugefügt, mit dem Model Index 1 (Das TableModel ist in Teil 2 erklärt). Danach wird die Spalte an position 0 (&amp;quot;A&amp;quot;) vershcoben an position 2. Man muss immer daran denken dass das Zählen bei 0 anfängt, also sind mit den Zahlen immer die Positionen im Model gemeint. Letztendlich wird noch verboten die Spaltengröße, und die Spaltenreihenfolge zu ändern.&lt;br /&gt;
&lt;br /&gt;
===Header selber zeichnen===&lt;br /&gt;
&lt;br /&gt;
Eine weitere Möglichkeit von JTableHeader und TableColumn ist, wie auch bei JTable möglich, den Renderer für die Spalte zu setzen.&lt;br /&gt;
Es wird das gleiche Renderer Interface benutzt wie bei der JTable: javax.swing.table.TableCellRenderer. Zugewiesen wird der Renderer mit setDefaultRenderer(TableCellRenderer defaultRenderer);&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
import java.awt.Component;&lt;br /&gt;
import java.awt.Color;&lt;br /&gt;
import javax.swing.*;&lt;br /&gt;
import javax.swing.table.JTableHeader;&lt;br /&gt;
import javax.swing.table.DefaultTableColumnModel;&lt;br /&gt;
import javax.swing.table.TableColumnModel;&lt;br /&gt;
import javax.swing.table.TableColumn;&lt;br /&gt;
import javax.swing.table.TableCellRenderer;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class TableHeaderTest {&lt;br /&gt;
	&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		// JTable initialisieren und mit Inhalt füllen; siehe dazu Teil 2&lt;br /&gt;
		JTable table = new JTable(new String[][]{{&amp;quot;1&amp;quot;, &amp;quot;2&amp;quot;, &amp;quot;3&amp;quot;},{&amp;quot;4&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;6&amp;quot;}}, new String[]{&amp;quot;A&amp;quot;, &amp;quot;B&amp;quot;, &amp;quot;C&amp;quot;});&lt;br /&gt;
		&lt;br /&gt;
		// JTableHeader holen&lt;br /&gt;
		JTableHeader header = table.getTableHeader();&lt;br /&gt;
		&lt;br /&gt;
		// ColumnModel holen:&lt;br /&gt;
		TableColumnModel columnModel = header.getColumnModel();&lt;br /&gt;
		&lt;br /&gt;
		// TableColumn erstellen&lt;br /&gt;
		TableColumn aColumn = new TableColumn();&lt;br /&gt;
		// setHeaderValue() setzt den Titel&lt;br /&gt;
		aColumn.setHeaderValue(&amp;quot;D&amp;quot;);&lt;br /&gt;
		// modelIndex zeigt an von welcher Spalte im DatenModel die neue Spalte ihre Werte holen soll&lt;br /&gt;
		aColumn.setModelIndex(1); // Index 1 im Model sind also &amp;quot;2&amp;quot; und &amp;quot;5&amp;quot;&lt;br /&gt;
		columnModel.addColumn(aColumn);&lt;br /&gt;
		&lt;br /&gt;
		// eine spalte verschieben&lt;br /&gt;
		columnModel.moveColumn(0, 2); // spalte 0 (mit Tiel &amp;quot;A&amp;quot;) verschieben an position 2 im model&lt;br /&gt;
		&lt;br /&gt;
		// spalten nicht resizable machen, nicht zulassen dass die spaltenreihenfolge geändert werden kann&lt;br /&gt;
		header.setResizingAllowed(false);&lt;br /&gt;
		header.setReorderingAllowed(false);&lt;br /&gt;
		&lt;br /&gt;
		// Renderer zuweisen&lt;br /&gt;
		header.setDefaultRenderer(new MyHeaderCellRenderer());&lt;br /&gt;
		&lt;br /&gt;
		// JFrame konstruieren&lt;br /&gt;
		JFrame frame = new JFrame(&amp;quot;JTableHeader test&amp;quot;);&lt;br /&gt;
		// Table in JScrollPane einfügen und dem Frame hinzufügen&lt;br /&gt;
		frame.getContentPane().add(new JScrollPane(table));&lt;br /&gt;
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);&lt;br /&gt;
		frame.pack();&lt;br /&gt;
		frame.setVisible(true);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Eigener CellRenderer für die spaltenköpfe. Liefert immer ein &lt;br /&gt;
// JLabel zurück, und implementiert TableCellRenderer&lt;br /&gt;
class MyHeaderCellRenderer extends JLabel implements TableCellRenderer {&lt;br /&gt;
	&lt;br /&gt;
	// einzig wichtige methode&lt;br /&gt;
	public Component getTableCellRendererComponent(JTable table, Object value, &lt;br /&gt;
			boolean isSelected, boolean hasFocus, int row, int column) {&lt;br /&gt;
		// text&lt;br /&gt;
		setText(value.toString());&lt;br /&gt;
		// normale schriftart&lt;br /&gt;
		setFont(table.getFont());&lt;br /&gt;
		// der standard rahmen für spaltenköpfe&lt;br /&gt;
		setBorder(UIManager.getBorder(&amp;quot;TableHeader.cellBorder&amp;quot;));&lt;br /&gt;
		// text zentiriert darstellen&lt;br /&gt;
		setHorizontalAlignment(SwingConstants.CENTER);&lt;br /&gt;
		// tooltip&lt;br /&gt;
		setToolTipText(&amp;quot;Colum No. &amp;quot;+(column+1));&lt;br /&gt;
		// undurchsichtig damit man die hintergrundfarbe sieht.&lt;br /&gt;
		setOpaque(true);&lt;br /&gt;
		// je nach spalte die hintergrundfarbe setzen&lt;br /&gt;
		switch(column) {&lt;br /&gt;
			case 0:  setBackground(Color.GREEN); break;&lt;br /&gt;
			case 1:  setBackground(Color.BLUE); break;&lt;br /&gt;
			case 2:  setBackground(Color.YELLOW); break;&lt;br /&gt;
			case 3:  setBackground(Color.RED); break;&lt;br /&gt;
			default: setBackground(Color.LIGHT_GRAY);&lt;br /&gt;
		}&lt;br /&gt;
		return this;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
[[Bild:JTableTutorial16.png]]&lt;br /&gt;
Hier wird zwar nur die Hintergrundfarbe geändert, Aber es gibt noch sehr viel mehr Möglichkeiten Die Spaltenköpfe zu manipulieren mithilfe des CellRenderers. Genau wie in Teil 3 beschrieben kann man auch andere komponenten die Darstellung der Header übernehmen lassen. Dazu muss man allerdings den CellRenderer anpassen (siehe auch Teil:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code=java&amp;gt;class MyHeaderCellRenderer implements TableCellRenderer {&lt;br /&gt;
	&lt;br /&gt;
	// einzig wichtige methode&lt;br /&gt;
	public Component getTableCellRendererComponent(JTable table, Object value, &lt;br /&gt;
			boolean isSelected, boolean hasFocus, int row, int column) {&lt;br /&gt;
		JComponent c = null;&lt;br /&gt;
		if(value instanceof String ) {&lt;br /&gt;
			c = new JLabel((String)value);&lt;br /&gt;
			((JLabel)c).setHorizontalAlignment(SwingConstants.CENTER);&lt;br /&gt;
		} else if(value instanceof JCheckBox) {&lt;br /&gt;
			c = (JCheckBox) value;&lt;br /&gt;
		} else if(value instanceof JComboBox) {&lt;br /&gt;
			c = (JComboBox) value;&lt;br /&gt;
		} else {&lt;br /&gt;
			c = new JLabel(value.toString());&lt;br /&gt;
			((JLabel)c).setHorizontalAlignment(SwingConstants.CENTER);&lt;br /&gt;
		}&lt;br /&gt;
		c.setEnabled(true);&lt;br /&gt;
		// normale schriftart&lt;br /&gt;
		c.setFont(table.getFont());&lt;br /&gt;
		// der standard rahmen für spaltenköpfe&lt;br /&gt;
		c.setBorder(UIManager.getBorder(&amp;quot;TableHeader.cellBorder&amp;quot;));&lt;br /&gt;
		// text zentiriert darstellen&lt;br /&gt;
		c.setToolTipText(&amp;quot;Colum No. &amp;quot;+(column+1));&lt;br /&gt;
		// undurchsichtig damit man die hintergrundfarbe sieht.&lt;br /&gt;
		c.setOpaque(true);&lt;br /&gt;
		// je nach spalte die hintergrundfarbe setzen&lt;br /&gt;
		switch(column) {&lt;br /&gt;
			case 0:  c.setBackground(Color.GREEN); break;&lt;br /&gt;
			case 1:  c.setBackground(Color.BLUE); break;&lt;br /&gt;
			case 2:  c.setBackground(Color.YELLOW); break;&lt;br /&gt;
			case 3:  c.setBackground(Color.RED); break;&lt;br /&gt;
			default: c.setBackground(Color.LIGHT_GRAY);&lt;br /&gt;
		}&lt;br /&gt;
		return c;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Jetzt gibt es aber das Problem dass man die Komponenten nicht ändern kann. Das ist auch etwas komplizierter, aber gute Tutorials,&lt;br /&gt;
die sich damit eingehender beschäftigen findet man z.B. hier:&lt;br /&gt;
http://www.objects.com.au/java/examples/swing/EditableTableHeader.do&lt;br /&gt;
Dort sind auch andere mehrere tiefergehende Beispiele zu JTableHeader und TableColumn.&lt;br /&gt;
&lt;br /&gt;
==Ein Header für die Rows==&lt;br /&gt;
Standartmässig unterstützt das JTable nur einen Header, der über den Spalten steht.&lt;br /&gt;
&lt;br /&gt;
Es ist aber kein grosses Problem eine Component - TableRowHeader - zu erstellen, welche dem JScrollPane übergeben werden kann auf dem das JTable sitzt.&lt;br /&gt;
Dazu wird die Methode JScrollPane#setRowHeader benutzt.&lt;br /&gt;
&lt;br /&gt;
Da man es sich nicht leisten kann, bei jedem Aufruf von paint den gesammten Header neu darzustellen (sobald die Tabelle viele Einträge kriegt (1000 oder mehr), würde enorm viel Zeit in das Zeichnen investiert werden), zeichnet die der Header nur gerade die &amp;quot;Knöpfe&amp;quot;, welche auch sichtbar sind.&lt;br /&gt;
&lt;br /&gt;
Da die Spalten einer JTable nicht immer gleichhoch sein müssen, muss der Header jede Spalte einzeln beachten, und nicht einfach eine Rechnung machen, um herauszufinden wo gezeichnet, und wo nicht gezeichnet werden muss.&lt;br /&gt;
&lt;br /&gt;
Das Demoframe. Man beachte, dass der Header dem ScrollPane übergeben werden muss.&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
public class JTableDemo {&lt;br /&gt;
	public static void main( String[] args ) {&lt;br /&gt;
		// Das JTable initialisieren&lt;br /&gt;
		Vector title = new Vector();&lt;br /&gt;
		title.add( &amp;quot;A&amp;quot; );&lt;br /&gt;
		title.add( &amp;quot;B&amp;quot; );&lt;br /&gt;
		title.add( &amp;quot;C&amp;quot; );&lt;br /&gt;
		title.add( &amp;quot;D&amp;quot; );&lt;br /&gt;
		&lt;br /&gt;
		JTable table = new JTable( createData(), title );&lt;br /&gt;
&lt;br /&gt;
		// Jede 10. Reihe wird vergrössert, um zu demonstrieren, wie sich der TableRowHeader anpasst.&lt;br /&gt;
		int rows = table.getRowCount();&lt;br /&gt;
		for( int i = 0; i &amp;lt; rows; i += 10 )&lt;br /&gt;
			table.setRowHeight( i, 2*table.getRowHeight( i ) );&lt;br /&gt;
		&lt;br /&gt;
		JFrame frame = new JFrame( &amp;quot;Demo&amp;quot; );&lt;br /&gt;
		JScrollPane pane = new JScrollPane( table );&lt;br /&gt;
		&lt;br /&gt;
		// mit diesem Befehl wird die Leiste links angesetzt.&lt;br /&gt;
		pane.setRowHeader( new TableRowHeader( table, pane ) );&lt;br /&gt;
		&lt;br /&gt;
		frame.getContentPane().add( pane );&lt;br /&gt;
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
		frame.pack();&lt;br /&gt;
		frame.setVisible( true );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Produziert genug Daten, dass man scrollen kann.&lt;br /&gt;
	private static Vector createData(){&lt;br /&gt;
		Vector data = new Vector();&lt;br /&gt;
		&lt;br /&gt;
		for( int i = 0; i &amp;lt; 10000; i++ ){&lt;br /&gt;
			Vector temp = new Vector();&lt;br /&gt;
			for( int j = 0; j &amp;lt; 4; j++ )&lt;br /&gt;
				temp.add( String.valueOf( Math.random() ) );&lt;br /&gt;
			&lt;br /&gt;
			data.add( temp );&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		return data;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Der TableRowHeader. Eigentlich nichts weiter als eine ganz normale Component.&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
public class TableRowHeader extends JViewport implements AdjustmentListener{&lt;br /&gt;
	private JTable	table;&lt;br /&gt;
	private Cell cell;&lt;br /&gt;
&lt;br /&gt;
	public TableRowHeader( JTable table, JScrollPane parent ) {&lt;br /&gt;
		this.table = table;&lt;br /&gt;
		cell = new Cell();&lt;br /&gt;
		setView( new Dummy() );&lt;br /&gt;
		setPreferredSize( new Dimension( 100, 0 ) );&lt;br /&gt;
		&lt;br /&gt;
		parent.getVerticalScrollBar().addAdjustmentListener( this );&lt;br /&gt;
		parent.getHorizontalScrollBar().addAdjustmentListener( this );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public void adjustmentValueChanged( AdjustmentEvent e ) {&lt;br /&gt;
		repaint();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	protected void paintComponent(Graphics g){&lt;br /&gt;
		super.paintComponent( g );&lt;br /&gt;
		Rectangle rec = TableRowHeader.this.getViewRect();&lt;br /&gt;
&lt;br /&gt;
		int y = 0;&lt;br /&gt;
		int rows = table.getRowCount();&lt;br /&gt;
		int index = 0;&lt;br /&gt;
&lt;br /&gt;
		if( rows == 0 )&lt;br /&gt;
			return;&lt;br /&gt;
&lt;br /&gt;
		if( y + table.getRowHeight( 0 ) &amp;lt; rec.y ){&lt;br /&gt;
			while( index &amp;lt; rows ){&lt;br /&gt;
				int height = table.getRowHeight( index );&lt;br /&gt;
&lt;br /&gt;
				if( y + height &amp;lt; rec.y ){&lt;br /&gt;
					y += height;&lt;br /&gt;
					index++;&lt;br /&gt;
				}&lt;br /&gt;
				else&lt;br /&gt;
					break;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		int max = rec.y + rec.height;&lt;br /&gt;
		int width = getWidth();&lt;br /&gt;
&lt;br /&gt;
		while( y &amp;lt; max &amp;amp;&amp;amp; index &amp;lt; rows ){&lt;br /&gt;
			int height = table.getRowHeight( index );&lt;br /&gt;
			cell.set( index );&lt;br /&gt;
			SwingUtilities.paintComponent( g, cell, this, 0, y-rec.y, width, height );&lt;br /&gt;
            &lt;br /&gt;
			y += height;&lt;br /&gt;
			index++;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Nur eine leere Hülle, damit eine &amp;quot;Simulation&amp;quot; aufgebaut werden kann.&lt;br /&gt;
	private static class Dummy extends JComponent{&lt;br /&gt;
		public void paint( Graphics g ){&lt;br /&gt;
			// do nothing&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		public void update( Graphics g ) {&lt;br /&gt;
			// do nothing&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Stellt den Knopf für eine Reihe dar.&lt;br /&gt;
	private class Cell extends JLabel {&lt;br /&gt;
		public void set( int row ) {&lt;br /&gt;
			setHorizontalAlignment( CENTER );&lt;br /&gt;
			setForeground( TableRowHeader.this.getForeground() );&lt;br /&gt;
			setBackground( TableRowHeader.this.getBackground() );&lt;br /&gt;
			setFont( TableRowHeader.this.getFont() );&lt;br /&gt;
			setText( &amp;quot;Row &amp;quot; + row );&lt;br /&gt;
			setBorder( UIManager.getBorder( &amp;quot;TableHeader.cellBorder&amp;quot; ) );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Und daraus ergibt sich schliesslich dieses Bild:&lt;br /&gt;
[[Bild:JTableTutorial15.png]]&lt;br /&gt;
Selbstverständlich könnte man den Header ausbauen. So wäre vielleicht ein verschieben von Zeilen möglich... Ein Beispiel das die Möglichkeiten zeigt gibt es ja: den JTableHeader.&lt;br /&gt;
&lt;br /&gt;
==Weitere Links==&lt;br /&gt;
[[JTable sortieren]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Java]]&lt;br /&gt;
[[Kategorie:Tutorials (Java)]]&lt;br /&gt;
[[Kategorie:Swing]]&lt;br /&gt;
[[Kategorie:JTable]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Beni | Beni]] (© Benjamin Sigg, 04.06.2004, 20:30)&lt;/div&gt;</summary>
		<author><name>Beni</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=Reflection_(Java)&amp;diff=1635</id>
		<title>Reflection (Java)</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=Reflection_(Java)&amp;diff=1635"/>
		<updated>2007-02-27T22:42:44Z</updated>

		<summary type="html">&lt;p&gt;Beni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Reflection in [[Java_(Programmiersprache)|Java]] ist eine Möglichkeit, Informationen über [[Klasse_(Java)|Klassen]], [[Methode_(Java)|Methoden]] und andere Sprachelemente zu erhalten, ohne diese Elemente während dem Programmieren zu kennen.&lt;br /&gt;
&lt;br /&gt;
Eine kleine Auswahl von Informationen:&lt;br /&gt;
* Eine Liste aller Methoden einer Klasse&lt;br /&gt;
* Die Argumente einer Methode&lt;br /&gt;
* Die [[Modifier_(Java)|Sichtbarkeit]] einer [[Variable]]&lt;br /&gt;
* Die [[Annotation_(Java)|Annotationen]] eines Elementes&lt;br /&gt;
&lt;br /&gt;
Diese Informationen können auch dazu verwendet werden, [[Objekt|Objekte]] einer bestimmten Klasse herzustellen, die Methoden des Objektes aufzurufen, oder Felder des Objektes abzuändern. Der Typ des Objektes muss wiederum nicht im vornherein bekannt sein.&lt;br /&gt;
&lt;br /&gt;
= Arbeiten mit Reflection =&lt;br /&gt;
Um mit Reflection zu arbeiten, benötigt man ein [[Class_(Java_API)|Class]]-Objekt desjenigen Typen, mit dem man arbeiten will. Dieses Objekt erhält man üblicherweise auf einem der folgenden Wege:&lt;br /&gt;
* Mittels dem Syntax &amp;quot;x.class&amp;quot;, wobei &amp;quot;x&amp;quot; ein beliebiger Typ sein kann.&lt;br /&gt;
&amp;lt;code=java&amp;gt;Class&amp;lt;?&amp;gt; classString = String.class;&lt;br /&gt;
Class&amp;lt;?&amp;gt; classInt = int.class;&lt;br /&gt;
Class&amp;lt;?&amp;gt; classFloatArray = float[].class;&amp;lt;/code=java&amp;gt;&lt;br /&gt;
* Mit der Methode &amp;quot;getClass&amp;quot;, welche jedes Objekt besitzt.&lt;br /&gt;
&amp;lt;code=java&amp;gt;Object unknown = ...&lt;br /&gt;
Class&amp;lt;?&amp;gt; classUnknown = unknown.getClass();&amp;lt;/code=java&amp;gt;&lt;br /&gt;
* Über einen [[ClassLoader_(Java_API)|ClassLoader]], der diesen Typ kennt.&lt;br /&gt;
&amp;lt;code=java&amp;gt;ClassLoader loader = ClassLoader.getSystemClassLoader();&lt;br /&gt;
Class&amp;lt;?&amp;gt; classFrame = loader.loadClass( &amp;quot;javax.swing.JFrame&amp;quot; );&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zugriff auf Informationen == &lt;br /&gt;
Die Klasse &#039;&#039;Class&#039;&#039; bietet verschiedene Methoden mehr über die dargestellte Klasse herauszufinden. Das geht von dem Namen der Klasse (&amp;quot;getName&amp;quot;), über die Klasse von der geerbt wurde (&amp;quot;getSuperclass&amp;quot;) bis zu allen Methoden (&amp;quot;getDeclaredMethods&amp;quot;), [[Konstruktor_(Java)|Konstruktoren]] (&amp;quot;getConstructors&amp;quot;) und Feldern (&amp;quot;getFields&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Über einzelne Felder, Methoden, ... lassen sich dann wiederum zusätzliche Informationen abrufen, z.B. die Argumente eines Konstruktors.&lt;br /&gt;
&lt;br /&gt;
== Objekte generieren ==&lt;br /&gt;
Besitzt man erstmal die Klasse, will man meist auch ein Objekt dieser Klasse haben.&lt;br /&gt;
&lt;br /&gt;
Dazu gibt es zwei einfache Wege:&lt;br /&gt;
* Direkt über die Methode &amp;quot;newInstance&amp;quot; von &#039;&#039;Class&#039;&#039; kann ein Objekt erzeugt werden. Das entspricht genau dem Verhalten, wie wenn man den [[Defaultkonstruktor_(Java)|Defaultkonstruktor]] aufrufen würde. Wenn kein solcher Konstruktor vorhanden ist, wird eine [[Exception_(Java)|Exception]] geworfen.&lt;br /&gt;
* Über ein [[Constructor_(Java)|Constructor]]-Objekt, indem die Methode &amp;quot;newInstance&amp;quot; mit passenden Argumenten aufgerufen wird.&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel wird ein Punkt erzeugt, und ausgegeben:&lt;br /&gt;
&amp;lt;code=java&amp;gt;Class&amp;lt;?&amp;gt; point = Class.forName( &amp;quot;java.awt.Point&amp;quot; );&lt;br /&gt;
Constructor&amp;lt;?&amp;gt; constructor = point.getConstructor( &lt;br /&gt;
  new Class[]{ int.class, int.class });&lt;br /&gt;
Object object = constructor.newInstance( new Object[]{ 45, 97 });&lt;br /&gt;
&lt;br /&gt;
System.out.println( object );&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aufrufe tätigen ==&lt;br /&gt;
Mit Reflection kann man auch Methoden aufrufen oder Felder ändern.&lt;br /&gt;
* Anstelle des normalen Methodenaufrufes &amp;quot;object.x( y, z )&amp;quot; benutzt man das [[Method_(Java_API)|Method]]-Objekt, welches die Methode &amp;quot;x&amp;quot; darstellt, und ruft &amp;quot;x.invoke( object, x, y )&amp;quot; auf.&lt;br /&gt;
* Anstelle einer Zuweisung &amp;quot;object.x = y&amp;quot; benutzt man das [[Field_(Java_API)|Field]]-Objekt, welches &amp;quot;x&amp;quot; darstellt, und ruft &amp;quot;x.set( object, y )&amp;quot; auf.&lt;br /&gt;
&lt;br /&gt;
= Beispiele =&lt;br /&gt;
== Restriktionen aushebeln ==&lt;br /&gt;
Das folgende Beispiel benutzt Reflection um auf den, eigentlich geschützten, char-[[Array]] eines [[String_(Java_API)|Strings]] zuzugreiffen.&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
import java.lang.reflect.Field;&lt;br /&gt;
&lt;br /&gt;
public class Evil {&lt;br /&gt;
    public static void main( String[] args ) throws Exception{&lt;br /&gt;
        // Die Ausgabe dieses Programmes ist...&lt;br /&gt;
        System.out.println( &amp;quot;Hallo Welt&amp;quot; );&lt;br /&gt;
        // ... jedenfalls nicht &amp;quot;Hallo Welt&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    static{&lt;br /&gt;
        try{&lt;br /&gt;
            // Repräsentation der String-Klasse abrufen&lt;br /&gt;
            Class&amp;lt;String&amp;gt; clazz = String.class;&lt;br /&gt;
            &lt;br /&gt;
            String object = &amp;quot;Hallo Welt&amp;quot;;&lt;br /&gt;
            String text = &amp;quot;Ich bin böse!&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
            // Zugriff auf die Felder &amp;quot;value&amp;quot; und &amp;quot;count&amp;quot; erlangen&lt;br /&gt;
            Field value = clazz.getDeclaredField( &amp;quot;value&amp;quot; );&lt;br /&gt;
            Field count = clazz.getDeclaredField( &amp;quot;count&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
            // Die Sichtbarkeit der Felder von private auf public erhöhen&lt;br /&gt;
            value.setAccessible( true );&lt;br /&gt;
            count.setAccessible( true );&lt;br /&gt;
&lt;br /&gt;
            // Den Feldern neue Werte zuweisen&lt;br /&gt;
            value.set( object, text.toCharArray() );&lt;br /&gt;
            count.setInt( object, text.length() );&lt;br /&gt;
        }&lt;br /&gt;
        catch( Exception ex ){&lt;br /&gt;
            ex.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Objekt herstellen und Methoden aufrufen ==&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt, wie eine Klasse, von der man nur den Namen kennt, und die garantiert noch nicht im System existiert, geladen wird. Danach wird eine [[Instanz]] dieser Klasse angelegt, und eine Methode aufgerufen.&lt;br /&gt;
&amp;lt;code=java&amp;gt;package hidden;&lt;br /&gt;
&lt;br /&gt;
import java.lang.reflect.Method;&lt;br /&gt;
&lt;br /&gt;
public class Hidden {&lt;br /&gt;
    public static void main( String[] args ) throws Exception{&lt;br /&gt;
        Loader loader = new Loader();&lt;br /&gt;
        Class&amp;lt;?&amp;gt; clazz = loader.loadClass( &amp;quot;hidden.Riddle&amp;quot; );&lt;br /&gt;
        &lt;br /&gt;
        Object object = clazz.newInstance();&lt;br /&gt;
        Method run = clazz.getMethod( &amp;quot;run&amp;quot;, new Class[0] );&lt;br /&gt;
        run.invoke( object, new Object[0] );&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    private static class Loader extends ClassLoader{&lt;br /&gt;
        @Override&lt;br /&gt;
        protected Class&amp;lt;?&amp;gt; findClass( String name ) throws ClassNotFoundException {&lt;br /&gt;
            if( name.equals( &amp;quot;hidden.Riddle&amp;quot; )){&lt;br /&gt;
                return defineClass( &amp;quot;hidden.Riddle&amp;quot;, CODE, 0, CODE.length );&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
                return super.findClass( name );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public static final byte[] CODE = {&lt;br /&gt;
        -54, -2, -70, -66, 0, 0, 0, 49, 0, 78, 7, &lt;br /&gt;
        0, 2, 1, 0, 13, 104, 105, 100, 100, 101, 110, &lt;br /&gt;
        47, 82, 105, 100, 100, 108, 101, 7, 0, 4, 1, &lt;br /&gt;
        0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, &lt;br /&gt;
        47, 79, 98, 106, 101, 99, 116, 1, 0, 5, 118, &lt;br /&gt;
        97, 108, 117, 101, 1, 0, 1, 73, 1, 0, 6, &lt;br /&gt;
        60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, &lt;br /&gt;
        86, 1, 0, 4, 67, 111, 100, 101, 10, 0, 3, &lt;br /&gt;
        0, 11, 12, 0, 7, 0, 8, 10, 0, 13, 0, &lt;br /&gt;
        15, 7, 0, 14, 1, 0, 14, 106, 97, 118, 97, &lt;br /&gt;
        47, 108, 97, 110, 103, 47, 77, 97, 116, 104, 12, &lt;br /&gt;
        0, 16, 0, 17, 1, 0, 6, 114, 97, 110, 100, &lt;br /&gt;
        111, 109, 1, 0, 3, 40, 41, 68, 6, 64, 89, &lt;br /&gt;
        0, 0, 0, 0, 0, 0, 9, 0, 1, 0, 21, &lt;br /&gt;
        12, 0, 5, 0, 6, 1, 0, 15, 76, 105, 110, &lt;br /&gt;
        101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, &lt;br /&gt;
        101, 1, 0, 18, 76, 111, 99, 97, 108, 86, 97, &lt;br /&gt;
        114, 105, 97, 98, 108, 101, 84, 97, 98, 108, 101, &lt;br /&gt;
        1, 0, 4, 116, 104, 105, 115, 1, 0, 15, 76, &lt;br /&gt;
        104, 105, 100, 100, 101, 110, 47, 82, 105, 100, 100, &lt;br /&gt;
        108, 101, 59, 1, 0, 3, 114, 117, 110, 7, 0, &lt;br /&gt;
        28, 1, 0, 17, 106, 97, 118, 97, 47, 117, 116, &lt;br /&gt;
        105, 108, 47, 83, 99, 97, 110, 110, 101, 114, 9, &lt;br /&gt;
        0, 30, 0, 32, 7, 0, 31, 1, 0, 16, 106, &lt;br /&gt;
        97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 121, &lt;br /&gt;
        115, 116, 101, 109, 12, 0, 33, 0, 34, 1, 0, &lt;br /&gt;
        2, 105, 110, 1, 0, 21, 76, 106, 97, 118, 97, &lt;br /&gt;
        47, 105, 111, 47, 73, 110, 112, 117, 116, 83, 116, &lt;br /&gt;
        114, 101, 97, 109, 59, 10, 0, 27, 0, 36, 12, &lt;br /&gt;
        0, 7, 0, 37, 1, 0, 24, 40, 76, 106, 97, &lt;br /&gt;
        118, 97, 47, 105, 111, 47, 73, 110, 112, 117, 116, &lt;br /&gt;
        83, 116, 114, 101, 97, 109, 59, 41, 86, 9, 0, &lt;br /&gt;
        30, 0, 39, 12, 0, 40, 0, 41, 1, 0, 3, &lt;br /&gt;
        111, 117, 116, 1, 0, 21, 76, 106, 97, 118, 97, &lt;br /&gt;
        47, 105, 111, 47, 80, 114, 105, 110, 116, 83, 116, &lt;br /&gt;
        114, 101, 97, 109, 59, 8, 0, 43, 1, 0, 38, &lt;br /&gt;
        71, 105, 98, 32, 101, 105, 110, 101, 32, 90, 97, &lt;br /&gt;
        104, 108, 32, 122, 119, 105, 115, 99, 104, 101, 110, &lt;br /&gt;
        32, 48, 32, 117, 110, 100, 32, 49, 48, 48, 32, &lt;br /&gt;
        101, 105, 110, 58, 32, 10, 0, 45, 0, 47, 7, &lt;br /&gt;
        0, 46, 1, 0, 19, 106, 97, 118, 97, 47, 105, &lt;br /&gt;
        111, 47, 80, 114, 105, 110, 116, 83, 116, 114, 101, &lt;br /&gt;
        97, 109, 12, 0, 48, 0, 49, 1, 0, 5, 112, &lt;br /&gt;
        114, 105, 110, 116, 1, 0, 21, 40, 76, 106, 97, &lt;br /&gt;
        118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, &lt;br /&gt;
        105, 110, 103, 59, 41, 86, 10, 0, 27, 0, 51, &lt;br /&gt;
        12, 0, 52, 0, 53, 1, 0, 10, 104, 97, 115, &lt;br /&gt;
        78, 101, 120, 116, 73, 110, 116, 1, 0, 3, 40, &lt;br /&gt;
        41, 90, 10, 0, 27, 0, 55, 12, 0, 56, 0, &lt;br /&gt;
        57, 1, 0, 7, 110, 101, 120, 116, 73, 110, 116, &lt;br /&gt;
        1, 0, 3, 40, 41, 73, 8, 0, 59, 1, 0, &lt;br /&gt;
        7, 82, 105, 99, 104, 116, 105, 103, 10, 0, 45, &lt;br /&gt;
        0, 61, 12, 0, 62, 0, 49, 1, 0, 7, 112, &lt;br /&gt;
        114, 105, 110, 116, 108, 110, 8, 0, 64, 1, 0, &lt;br /&gt;
        16, 70, 97, 108, 115, 99, 104, 44, 32, 122, 117, &lt;br /&gt;
        32, 107, 108, 101, 105, 110, 8, 0, 66, 1, 0, &lt;br /&gt;
        16, 70, 97, 108, 115, 99, 104, 44, 32, 122, 117, &lt;br /&gt;
        32, 103, 114, 111, 115, 115, 8, 0, 68, 1, 0, &lt;br /&gt;
        24, 68, 97, 115, 32, 115, 111, 108, 108, 32, 101, &lt;br /&gt;
        105, 110, 101, 32, 90, 97, 104, 108, 32, 115, 101, &lt;br /&gt;
        105, 110, 63, 10, 0, 27, 0, 70, 12, 0, 71, &lt;br /&gt;
        0, 72, 1, 0, 4, 110, 101, 120, 116, 1, 0, &lt;br /&gt;
        20, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, &lt;br /&gt;
        110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, &lt;br /&gt;
        0, 1, 115, 1, 0, 19, 76, 106, 97, 118, 97, &lt;br /&gt;
        47, 117, 116, 105, 108, 47, 83, 99, 97, 110, 110, &lt;br /&gt;
        101, 114, 59, 1, 0, 5, 99, 104, 101, 99, 107, &lt;br /&gt;
        1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, &lt;br /&gt;
        108, 101, 1, 0, 11, 82, 105, 100, 100, 108, 101, &lt;br /&gt;
        46, 106, 97, 118, 97, 0, 33, 0, 1, 0, 3, &lt;br /&gt;
        0, 0, 0, 1, 0, 2, 0, 5, 0, 6, 0, &lt;br /&gt;
        0, 0, 2, 0, 1, 0, 7, 0, 8, 0, 1, &lt;br /&gt;
        0, 9, 0, 0, 0, 67, 0, 5, 0, 1, 0, &lt;br /&gt;
        0, 0, 17, 42, -73, 0, 10, 42, -72, 0, 12, &lt;br /&gt;
        20, 0, 18, 107, -114, -75, 0, 20, -79, 0, 0, &lt;br /&gt;
        0, 2, 0, 22, 0, 0, 0, 14, 0, 3, 0, &lt;br /&gt;
        0, 0, 5, 0, 4, 0, 6, 0, 16, 0, 5, &lt;br /&gt;
        0, 23, 0, 0, 0, 12, 0, 1, 0, 0, 0, &lt;br /&gt;
        17, 0, 24, 0, 25, 0, 0, 0, 1, 0, 26, &lt;br /&gt;
        0, 8, 0, 1, 0, 9, 0, 0, 0, -33, 0, &lt;br /&gt;
        3, 0, 3, 0, 0, 0, 105, -69, 0, 27, 89, &lt;br /&gt;
        -78, 0, 29, -73, 0, 35, 76, -78, 0, 38, 18, &lt;br /&gt;
        42, -74, 0, 44, 43, -74, 0, 50, -103, 0, 65, &lt;br /&gt;
        43, -74, 0, 54, 61, 28, 42, -76, 0, 20, -96, &lt;br /&gt;
        0, 14, -78, 0, 38, 18, 58, -74, 0, 60, -89, &lt;br /&gt;
        0, 57, 28, 42, -76, 0, 20, -94, 0, 14, -78, &lt;br /&gt;
        0, 38, 18, 63, -74, 0, 60, -89, -1, -55, 28, &lt;br /&gt;
        42, -76, 0, 20, -92, -1, -63, -78, 0, 38, 18, &lt;br /&gt;
        65, -74, 0, 60, -89, -1, -74, -78, 0, 38, 18, &lt;br /&gt;
        67, -74, 0, 60, 43, -74, 0, 69, 87, -89, -1, &lt;br /&gt;
        -90, -79, 0, 0, 0, 2, 0, 22, 0, 0, 0, &lt;br /&gt;
        62, 0, 15, 0, 0, 0, 9, 0, 11, 0, 11, &lt;br /&gt;
        0, 19, 0, 12, 0, 26, 0, 13, 0, 31, 0, &lt;br /&gt;
        14, 0, 39, 0, 15, 0, 47, 0, 16, 0, 50, &lt;br /&gt;
        0, 18, 0, 58, 0, 19, 0, 69, 0, 21, 0, &lt;br /&gt;
        77, 0, 22, 0, 88, 0, 26, 0, 96, 0, 27, &lt;br /&gt;
        0, 101, 0, 30, 0, 104, 0, 31, 0, 23, 0, &lt;br /&gt;
        0, 0, 32, 0, 3, 0, 0, 0, 105, 0, 24, &lt;br /&gt;
        0, 25, 0, 0, 0, 11, 0, 94, 0, 73, 0, &lt;br /&gt;
        74, 0, 1, 0, 31, 0, 57, 0, 75, 0, 6, &lt;br /&gt;
        0, 2, 0, 1, 0, 76, 0, 0, 0, 2, 0, 77 };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Java]]&lt;/div&gt;</summary>
		<author><name>Beni</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=Array&amp;diff=1669</id>
		<title>Array</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=Array&amp;diff=1669"/>
		<updated>2007-02-27T21:03:54Z</updated>

		<summary type="html">&lt;p&gt;Beni: Fehler im Beispielcode korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein Array ist ein Konstrukt in dem mehrere Objekte eins Datentyps hintereinander aufgereiht stehen. (Es wird hier immer von Objekten geredet egal ob es in der Programmiersprache Objekte gibt oder nicht)&lt;br /&gt;
Diese Konstrukte werden oft verwendet wenn man eine große Ansammlung von gleichen Daten eines Objekts hat, durch die Verwendung von Arrays muss man nicht viele Variablen anlegen und hat so alles übersichtlicher. In den meisten Sprachen haben Arrays jedoch den Nachteil das sie statisch sind, d.h. man legt einmal ihre Größe fest und danach kann man es nicht mehr ändern, will man mehr Objekte ablegen dann muss man sich einen neuen Array anlegen. Daher haben Arrays in diesen Sprachen aber auch einen Vorteil gegen über den dynamischen Strukturen wie Listen, da sie eine fest definierte Größe haben kann man sie über einen Index anlegen und so über den Index darauf zugreifen, dies ist meistens eine schnellere Möglichkeit als bei anderen Strukturen möglich ist. &lt;br /&gt;
&lt;br /&gt;
Für die Erzeugung von Arrays gibt es unterschiedliche Wege, jedoch haben sie meistens gemeinsam das eckige Klammern([]) einen Array symbolisieren. So wird in C und C++ ein Array mit &amp;lt;code&amp;gt;typ name[];&amp;lt;/code&amp;gt; deklariert und die Initialisierung kann auf zwei unterschiedliche Wege erfolgen, &amp;lt;code&amp;gt; name = typ[anzahl]&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;name = malloc(sizeof(typ)*anzahl)&amp;lt;/code&amp;gt;, bzw. &amp;lt;code&amp;gt;name = new typ[anzahl]&amp;lt;/code&amp;gt;. Der Unterschied zwischen den beiden Arten ist, dass bei der ersten Möglichkeit der Speicher vom Compiler festgelegt wird und so nicht mehr freigegeben werden muss und bei der zweiten Art zur Laufzeit angelegt wird, welchen man dann auch selbst freigeben muss. Will nab in C# oder Java einen Array anlegen geschied dies mit &amp;lt;code&amp;gt;typ[] name;&amp;lt;/code&amp;gt; und die Initialisierung erfolgt über &amp;lt;code&amp;gt;name = new typ[anzahl]()&amp;lt;/code&amp;gt;. In Java ist es auch möglich die Arrays wie in C++ anzulegen. &lt;br /&gt;
&lt;br /&gt;
Bei der Sprache C# wurde noch ein weiterer Arraytyp eingeführt. Hier sind in jeder Zeile immer gleich viele Objekte, diese werden mit &amp;lt;code&amp;gt;typ[,] name = new typ[anzahl,anzahl]();&amp;lt;/code&amp;gt; angelegt. In allen anderen Sprachen lassen sich Arrays auch mit mehreren Dimensionen anlegen, hierzu muss nur ein weiteres Klammerpaar hinzugefügt werden. Diese neuen Arrays in dem bestehenden Array müssen auch nicht gleich initialisiert werden sondern können auch erst später angelegt werden um so besser auf die Gegebenheiten angepasst zu sein. Daher ist es möglich das eine Zeile mal 4 Objekte enhält und eine mal garkeine, dies muss dann im Programm alles gesondert behandelt werden.&lt;br /&gt;
&lt;br /&gt;
Neben der Möglichkeit des Anlegen von leeren Arrays ist es auch Möglich Arrays gleich mit vorhandenen Daten anzulegen. In den meisten Sprachen ist dies einfach möglich indem man nach der normalen Syntax für die Initialisierung des Arrays gleich in geschweiften Klammern die Objekte durch Kommas getrennt einfügt, z.B. in Java:&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
String s = new String[]{&amp;quot;Hallo&amp;quot;,&amp;quot; &amp;quot;,&amp;quot;Hallo&amp;quot;,&amp;quot;!!!&amp;quot;};&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
In einigen Sprachen ist es auch möglich bei der Deklaration der Variablen gleich die Werte zuzuweisen ohne die übliche Initialisierungssyntax, z.B. in Java:&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
String[] s = {&amp;quot;Hallo&amp;quot;,&amp;quot; &amp;quot;,&amp;quot;Hallo&amp;quot;,&amp;quot;!!!&amp;quot;};&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Programmiersprachen]]&lt;/div&gt;</summary>
		<author><name>Beni</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=Annotation_(Java)&amp;diff=1605</id>
		<title>Annotation (Java)</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=Annotation_(Java)&amp;diff=1605"/>
		<updated>2007-02-27T18:29:21Z</updated>

		<summary type="html">&lt;p&gt;Beni: Die Seite wurde neu angelegt: In Java kann mit einer &amp;#039;&amp;#039;Annotation&amp;#039;&amp;#039; Metainformation in den Quellcode eines Programmes eingefügt werden.  Annotation können von untersc...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In [[Java_(Programmiersprache)|Java]] kann mit einer &#039;&#039;Annotation&#039;&#039; Metainformation in den Quellcode eines Programmes eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
Annotation können von unterschiedlichsten Tools ausgelesen werden. So kann bereits ein [[Compiler]] einige Annotationen verwenden, z.B. um Warnungen zu unterdrücken oder zu generieren.&lt;br /&gt;
&lt;br /&gt;
= Eigene Annotationen =&lt;br /&gt;
Es ist möglich, eigene Annotationen zu schreiben. Der Syntax einer Annotation gleicht dem Syntax eines [[Interface_(Java)|Interfaces]]. Wie ein Interface muss auch eine Annotation in einer eigenen Java-Datei gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
== Annotation definieren ==&lt;br /&gt;
Verglichen mit einem Interface hat eine Annotation folgende Unterschiede:&lt;br /&gt;
* Dem Schlüsselwort &amp;quot;interface&amp;quot; wird ein @ vorangestellt.&lt;br /&gt;
* Lediglich Methoden ohne Argumente und ohne [[Exception_(Java)|throws-Klauseln]] sind erlaubt&lt;br /&gt;
* Rückgabewert der Methoden dürfen alle [[Primitiv_(Java)|primitiven Datentypen]], [[String_(Java_API)|String]], [[Class_(Java_API)|Class]], [[Enumeration_(Java)|Enumerationen]], Annotationen und [[Array_(Java)|Arrays]] der eben gennanten sein.&lt;br /&gt;
* Methoden können einen &amp;quot;default&amp;quot;-Wert besitzen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&amp;lt;code=java&amp;gt;&lt;br /&gt;
@Retention( RetentionPolicy.RUNTIME )&lt;br /&gt;
@Target( ElementType.METHOD )&lt;br /&gt;
public @interface IntegerSetter {&lt;br /&gt;
    int min();&lt;br /&gt;
    int max();&lt;br /&gt;
    int start() default 1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Die hier definierte Annotation &#039;&#039;IntegerSetter&#039;&#039; besitzt drei Elemente: &amp;quot;min&amp;quot;, &amp;quot;max&amp;quot; und &amp;quot;start&amp;quot;. Alle drei sind vom Typ &amp;quot;int&amp;quot;. Das Element &amp;quot;start&amp;quot; besitzt einen Default-Wert von 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Retention&#039;&#039; und &#039;&#039;Target&#039;&#039; sind andere Annotationen, welche eine Aussage über den Gültigkeitsbereich der Annotation &#039;&#039;IntegerSetter&#039;&#039; machen. Hier wird gesagt, dass die Annotation &#039;&#039;IntegerSetter&#039;&#039; zur Laufzeit sichtbar ist, und nur für Methoden verwenden werden kann.&lt;br /&gt;
&lt;br /&gt;
== Annotation anwenden ==&lt;br /&gt;
Annotationen werden vor das zu markierende Element geschrieben, einfach indem nach einem @ der Name der Annotation ausgeschrieben wird. Falls die Annotation Elemente besitzt, müssen die Elemente noch gesetzt werden. Dazu schreibt man, in runden Klammern, &amp;quot;Element = Wert&amp;quot;-Paare.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;code=java&amp;gt;public class Point {&lt;br /&gt;
    private int x, y;&lt;br /&gt;
    &lt;br /&gt;
    @IntegerSetter( min=0, max=5 )&lt;br /&gt;
    public void setX( int x ){&lt;br /&gt;
        this.x = x;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    @IntegerSetter( min=0, max=20, start=5 )&lt;br /&gt;
    public void setY( int y ){&lt;br /&gt;
        this.y = y;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public static void main( String[] args ) throws Exception{&lt;br /&gt;
        list( Point.class );&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Hier werden die beiden Methoden &amp;quot;setX&amp;quot; und &amp;quot;setY&amp;quot; mit &#039;&#039;IntegerSetter&#039;&#039; markiert. Da das Element &amp;quot;start&amp;quot; einen Default-Wert besitzt, ist es nicht notwendig, das Element jedesmal neu zu definieren.&lt;br /&gt;
&lt;br /&gt;
== Annotation zur Laufzeit auslesen ==&lt;br /&gt;
Selbstgeschriebene Annotation werden oft zur Laufzeit benötigt. Mit [[Reflection_(Java)|Reflection]] können die Annotation ausgelesen werden. Die meisten Reflection-Klassen bieten eine entsprechende [[Methode_(Java)|Methode]] &amp;quot;getAnnotation(s)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;code=java&amp;gt;    public static void main( String[] args ) throws Exception{&lt;br /&gt;
        list( Point.class );&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public static void list( Class&amp;lt;?&amp;gt; clazz ) throws Exception{&lt;br /&gt;
        for( Method method : clazz.getMethods() ){&lt;br /&gt;
            IntegerSetter value = method.getAnnotation(&lt;br /&gt;
                IntegerSetter.class );&lt;br /&gt;
            if( value != null ){&lt;br /&gt;
                System.out.printf( &lt;br /&gt;
                        &amp;quot;%s: min=%d, max=%d, start=%d\n&amp;quot;,&lt;br /&gt;
                        method.getName(), value.min(),&lt;br /&gt;
                        value.max(), value.start() );&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Die Ausgabe dieses Programmes ist:&lt;br /&gt;
&amp;lt;pre&amp;gt;setX: min=0, max=5, start=1&lt;br /&gt;
setY: min=0, max=20, start=5&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie man an dem Beispiel sieht, können Annotationen wie normale Objekte behandelt werden.&lt;br /&gt;
&lt;br /&gt;
= Vordefinierte Annotationen =&lt;br /&gt;
Es gibt bereits einige vordefinierte Annotationen, dieser Abschnitt präsentiert eine Auswahl aus verschiedenen [[Package_(Java)|Packages]].&lt;br /&gt;
&lt;br /&gt;
== java.lang ==&lt;br /&gt;
{| width=&amp;quot;100%&amp;quot; align=&amp;quot;left&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
 ! width=&amp;quot;20%&amp;quot; | Name&lt;br /&gt;
 ! width=&amp;quot;80%&amp;quot; | Zweck&lt;br /&gt;
 |-&lt;br /&gt;
 | @Deprecated&lt;br /&gt;
 | Markiert Elemente (Klassen, Methoden, ...), die veraltet sind, oder aus anderen Gründen nicht benutzt werden sollten. Siehe auch [[Deprecated]].&lt;br /&gt;
 |-&lt;br /&gt;
 | @SuppressWarnings&lt;br /&gt;
 | Veranlasst den [[Compiler]] einen oder mehrere Typen Warnungen nicht zu melden.&lt;br /&gt;
 |-&lt;br /&gt;
 | @Override&lt;br /&gt;
 | Markiert eine Methode, die eine andere Methode [[Überschreiben_(Java)|überschreibt]]. Ein Compiler kann dank dieser Annotation sicher sein, dass der Programmierer eine Methode absichtlich überschrieben hat.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== java.lang.annotation ==&lt;br /&gt;
{| width=&amp;quot;100%&amp;quot; align=&amp;quot;left&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
 ! width=&amp;quot;20%&amp;quot; | Name&lt;br /&gt;
 ! width=&amp;quot;80%&amp;quot; | Zweck&lt;br /&gt;
 |-&lt;br /&gt;
 | @Retention &lt;br /&gt;
 | Regelt die Sichtbarkeit einer Annotation. Dazu wird eine &#039;&#039;RetentionPolicy&#039;&#039; gesetzt.&lt;br /&gt;
* &#039;&#039;&#039;Source&#039;&#039;&#039;: Die Annotation ist nur im Quellcode sichtbar.&lt;br /&gt;
* &#039;&#039;&#039;Class&#039;&#039;&#039;: Die Annotation ist auch in der Class-Datei, also im Kompilat, vorhanden.&lt;br /&gt;
* &#039;&#039;&#039;Runtime&#039;&#039;&#039;: Die Annotation wird während der Laufzeit von der [[JVM]] geladen. Nur mit dieser Policy kann eine Annotation per Reflection ausgelesen werden.&lt;br /&gt;
 |-&lt;br /&gt;
 | @Target &lt;br /&gt;
 | Wird ebenfalls für Annotationen angewandt. Das &#039;&#039;@Target&#039;&#039; sagt dem Compiler, welche Elemente eine Annotation markieren darf. &#039;&#039;@Target&#039;&#039; erwartet ein Array von &#039;&#039;ElementType&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Eine Annotation die für Methoden und Typen verwendet werden kann:&lt;br /&gt;
&amp;lt;code=java&amp;gt;@Target( {ElementType.TYPE, ElementType.METHOD} )&lt;br /&gt;
public @interface Something{&lt;br /&gt;
 ...&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 |-&lt;br /&gt;
 | @Documented&lt;br /&gt;
 | Wird für Annotationen verwendet, die von [[Javadoc_(Java)|Javadoc]], und ähnlichen Programmen, dokumentiert werden sollen. Das ist insbesondere wünschenswert für Annotationen, deren Vorhandensein einen direkten Einfluss auf das Programm haben.&lt;br /&gt;
 |-&lt;br /&gt;
 | @Inherited&lt;br /&gt;
 | Markiert eine Annotation, welche vererbt werden soll. Damit ist gemeint: wenn die Annotation eine [[Klasse_(Java)|Klasse]] markiert, sind automatisch alle Unterklassen ebenfalls markiert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Java]]&lt;/div&gt;</summary>
		<author><name>Beni</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=Methode_(Java)&amp;diff=1629</id>
		<title>Methode (Java)</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=Methode_(Java)&amp;diff=1629"/>
		<updated>2007-02-27T10:33:27Z</updated>

		<summary type="html">&lt;p&gt;Beni: /* finale Methoden */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In [[Java_(Programmiersprache)|Java]] ist eine Methode eine sequenzielle Sammlung von ausführbaren Befehlen.&lt;br /&gt;
&lt;br /&gt;
Methoden müssen stets in einer [[Klasse_(Java)|Klasse]] oder einem [[Interface_(Java)|Interface]] definiert werden. Zur [[Laufzeit]] gehört eine normale Methode dann zu einem [[Objekt]], und hat lesenden und schreibenden Zugriff auf das Objekt. Ausnahme sind sog. &amp;quot;statische Methoden&amp;quot; welche zu keinem Objekt gehören.&lt;br /&gt;
&lt;br /&gt;
= Syntax =&lt;br /&gt;
Eine Methode besteht aus einem Kopf und einem Rumpf. Der Kopf stellt die Schnittstelle zur Aussenwelt dar, der Rumpf hingegen ist der Code, der tatsächlich ausgeführt wird.&lt;br /&gt;
&amp;lt;code=java&amp;gt;Kopf{&lt;br /&gt;
  Rumpf&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Der Kopf ist stets vor dem Rumpf, der Rumpf stets durch geschweifte Klammern gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
== Methodenkopf ==&lt;br /&gt;
Der Kopf besteht, von links nach rechts, aus folgenden Elementen:&lt;br /&gt;
* verschiedene Modifier (optional)&lt;br /&gt;
* Definitionen lokaler [[Generics_(Java)|Generics]] (optional)&lt;br /&gt;
* Typ der Rückgabe (erforderlich)&lt;br /&gt;
* Name der Methode (erforderlich)&lt;br /&gt;
* Liste der Argumente (erforderlich)&lt;br /&gt;
* Liste von Ausnahmen (optional)&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&amp;lt;code=java&amp;gt;public static &amp;lt;X&amp;gt; X getRandom( List&amp;lt;X&amp;gt; list ) throws ListEmptyException;&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Modifier sind hier &amp;quot;public static&amp;quot;, es gibt ein Generic &amp;quot;X&amp;quot;, die Rückgabe der Methode ist ein [[Objekt]] des Types &amp;quot;X&amp;quot;, die Methode heisst &amp;quot;getRandom&amp;quot;, erwartet wird ein Argument &amp;quot;list&amp;quot; vom Typ &amp;quot;List&amp;lt;X&amp;gt;&amp;quot;, und die Methode kann eine &amp;quot;ListEmptyException&amp;quot; werfen, falls die Liste leer ist.&lt;br /&gt;
&lt;br /&gt;
=== Modifier ===&lt;br /&gt;
Als Modifier sind die bekannten [[Modifier_(Java)|Sichtbarkeits-Modifier]] &amp;quot;public&amp;quot;, &amp;quot;protected&amp;quot; und &amp;quot;private&amp;quot; erlaubt.&lt;br /&gt;
Die Effekte von &amp;quot;static&amp;quot;, &amp;quot;final&amp;quot; und &amp;quot;abstract&amp;quot; sind weiter unten in diesem Artikel erklärt.&lt;br /&gt;
Mit &amp;quot;synchronized&amp;quot; kann dem aufrufenden [[Thread_(Java)|Thread]] exklusiver Zugriff auf das Objekt, auf dem die Methode aufsetzt, gegeben werden.&lt;br /&gt;
&lt;br /&gt;
=== Lokale Generics ===&lt;br /&gt;
In spitzen Klammern geschrieben, und mit Komma getrennt, können beliebige [[Generics_(Java)|Generics]] definiert werden. Diese Generics können dann in der gesammten Methode verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== Rückgabetypen ===&lt;br /&gt;
Eine Methode kann einen Wert an den Aufrufer zurückgeben. Dabei ist jeder Typ erlaubt, egal ob Klasse, Generic oder [[Primitiv_(Java)|primitiver Datentyp]].&lt;br /&gt;
Falls eine Methode kein Rückgabe hat, wird dies mit dem Schlüsselwort &amp;quot;void&amp;quot; angezeigt:&lt;br /&gt;
&amp;lt;code=java&amp;gt;public void hide();&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Methodennamen ===&lt;br /&gt;
Der Name einer Methode muss mit einem Buchstaben beginnen, danach können Buchstaben, Ziffern und einige Sonderzeichen folgen.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise beginnen Namen mit einem Kleinbuchstaben, und sind Verben.&lt;br /&gt;
&lt;br /&gt;
=== Argumente ===&lt;br /&gt;
Die Argumente sind [[Variable|Variablen]] die der Aufrufer der Methode ausfüllen muss. Die Argumente werden durch eine Komma-getrennte Liste von &amp;quot;Typ&amp;quot;-&amp;quot;Namen&amp;quot;-Paaren angegeben. Diese Argument-Liste wird in runden Klammern geschrieben.&lt;br /&gt;
&lt;br /&gt;
Falls eine Methode keine Argumente benötigt, so schreibt man einfach &amp;quot;()&amp;quot; als Argumentliste.&lt;br /&gt;
&lt;br /&gt;
Argumente werden stets bei [[call-by-value]] übergeben.&lt;br /&gt;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
Eine Methode die zwei int-Argumente benötigt:&lt;br /&gt;
&amp;lt;code=java&amp;gt;public int max( int a, int b );&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Methode ohne Argumente:&lt;br /&gt;
&amp;lt;code=java&amp;gt;public int max();&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ausnahmen ===&lt;br /&gt;
Methoden können [[Exception_(Java)|Exceptions]] werfen. Die checked-Exceptions müssen aufgelistet werden, dazu wird das Schlüsselwort &amp;quot;throws&amp;quot; verwendet.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Eine Methode die zwei unterschiedliche Exceptions werfen kann:&lt;br /&gt;
&amp;lt;code=java&amp;gt;public void writeFile( String path ) &lt;br /&gt;
    throws NoSuchFileException, ReadOnlyFileException;&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Methodenrumpf ==&lt;br /&gt;
=== Variablen ===&lt;br /&gt;
Innerhalb des Rumpfes kann man jederzeit neue Variablen definieren, und ihnen Werte zuweisen.&lt;br /&gt;
&amp;lt;code=java&amp;gt;// neue Variablen&lt;br /&gt;
int x;&lt;br /&gt;
int y = 4;&lt;br /&gt;
&lt;br /&gt;
// Zuweisung&lt;br /&gt;
x = y + 1;&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Die Variablen sind ausserhalb der Methode nicht sichtbar.&lt;br /&gt;
=== Verzweigungen ===&lt;br /&gt;
Mit [[if_(Java)|if-else]] können Verzweigungen in den ausgeführten Code eingebaut werden.&lt;br /&gt;
Beispiel: hier wird der Variable &amp;quot;z&amp;quot; stehts der kleinere Wert der beiden Variablen &amp;quot;x&amp;quot; und &amp;quot;y&amp;quot; zugewiesen:&lt;br /&gt;
&amp;lt;code=java&amp;gt;if( x &amp;lt; y ){&lt;br /&gt;
  z = x;&lt;br /&gt;
}&lt;br /&gt;
else{&lt;br /&gt;
  z = y;&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
=== Schleifen ===&lt;br /&gt;
Die verschiedenen [[Schleife|Schleifen]] von Java können benutzt werden. Dies sind [[While-Schleife|while]], [[do-while_(Java)|do-while]], [[For-Schleife|for]] und [[For each-Schleife|for-each]].&lt;br /&gt;
=== Ausnahmen ===&lt;br /&gt;
Sollte eine Ausnahme, ein Ereignis, das die korrekte Beendingung der Methode verhindert, auftreten, so kann eine Exception geworfen werden. Hierzu wird das Schlüsselwort &amp;quot;throw&amp;quot; benutzt:&lt;br /&gt;
&amp;lt;code=java&amp;gt;if( !file.exists() )&lt;br /&gt;
  throw new NoSuchFileException( file.getPath() );&lt;br /&gt;
&amp;lt;/code=java&amp;gt;&lt;br /&gt;
=== Klassen / Interfaces ===&lt;br /&gt;
Innerhalb einer Methode können auch ganze Klassen oder Interfaces definiert werden. Mit Ausnahme der [[anonyme_Klasse_(Java)|anonymen Klassen]] ist es aber höchst ungewöhnlich, so etwas zu tun.&lt;br /&gt;
=== Rücksprung ===&lt;br /&gt;
Sofern ein Rückgabewert definiert wurde (also nicht &amp;quot;void&amp;quot; ist), und die Methode keine [[Endlosschleife]] besitzt, muss mit &amp;quot;return&amp;quot; ein Wert an den Aufrufer zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel: hier wird der Wert der Variable &amp;quot;x&amp;quot; zurückgegeben:&lt;br /&gt;
&amp;lt;code=java&amp;gt;return x;&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Methode kann auch mehrere return-Befehle besitzen, allerdings wird immer nur einer ausgeführt. Der return-Befehl ist stets der letzte Befehl der ausgeführt wird, sämtliche nachfolgenden Befehle werden ignoriert.&lt;br /&gt;
&lt;br /&gt;
Falls der Rückgabetyp &amp;quot;void&amp;quot; ist, kann man return einfach verwenden, um aus der Methode zu springen:&lt;br /&gt;
&amp;lt;code=java&amp;gt;return;&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aufruf ==&lt;br /&gt;
Beim Aufruf einer Methode müssen alle Argumente der Methode ausgefüllt werden. Lokale Generics werden vom Compiler automatisch berechnet, und der Rückgabewert kann ignoriert werden.&lt;br /&gt;
&lt;br /&gt;
Ein Aufruf kann z.B. so aussehen:&lt;br /&gt;
&amp;lt;code=java&amp;gt;int summe = plus( 23, 47 );&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Hier wird die Methode &amp;quot;plus&amp;quot; mit den Argumenten &amp;quot;32&amp;quot; und &amp;quot;47&amp;quot; aufgerufen. Die Rückgabe von &amp;quot;plus&amp;quot; wird in der Variable &amp;quot;summe&amp;quot; gespeichert.&lt;br /&gt;
&lt;br /&gt;
Da normale Methoden zu einem Objekt gehören, muss man oft das Objekt angeben, auf dem die Methode laufen wird:&lt;br /&gt;
&amp;lt;code=java&amp;gt;File file = ... // Eine Datei&lt;br /&gt;
String name = file.getName();&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Hier wird die Methode &amp;quot;getName&amp;quot; eines &#039;&#039;File&#039;&#039;-Objektes aufgerufen.&lt;br /&gt;
&lt;br /&gt;
= Spezielle Typen =&lt;br /&gt;
Nebst den &amp;quot;normalen Methoden&amp;quot; gibt es einige Methoden die sich etwas speziell verhalten.&lt;br /&gt;
&lt;br /&gt;
== statische Methoden ==&lt;br /&gt;
Statische Methoden, mit dem Modifier &amp;quot;static&amp;quot; markiert, gehören nicht zu einem Objekt, sondern zu einer Klasse. Diese Methoden haben deshalb keinen direkten Zugriff auf irgendwelche Variablen eines Objektes, da für sie schlicht kein Objekt existiert. Sie haben aber immernoch privilegierte Zugriffsrechte für alle Objekte, deren Typ der Klasse entspricht, in der die statische Methode definiert wurde.&lt;br /&gt;
&lt;br /&gt;
Beispiel, folgendes funktioniert nicht:&lt;br /&gt;
&amp;lt;code=java&amp;gt;public class Point{&lt;br /&gt;
  private int x, y;&lt;br /&gt;
&lt;br /&gt;
  public static String asString(){&lt;br /&gt;
    // FEHLER: x und y gehören zu einem Objekt, die&lt;br /&gt;
    // statische Methode hingegen zu einer Klasse&lt;br /&gt;
    return &amp;quot;X=&amp;quot; + x + &amp;quot;, Y=&amp;quot; + y;&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aber eine statische Methode kann sogar private Felder lesen:&lt;br /&gt;
&amp;lt;code=java&amp;gt;public class Point{&lt;br /&gt;
  private int x, y;&lt;br /&gt;
&lt;br /&gt;
  public static Point max( Point a, Point b ){&lt;br /&gt;
    Point result = new Point();&lt;br /&gt;
    &lt;br /&gt;
    // Zugriff auf die privaten Felder x und y:&lt;br /&gt;
    result.x = a.x &amp;gt; b.x ? a.x : b.x;&lt;br /&gt;
    result.y = a.y &amp;gt; b.y ? a.y : b.y;&lt;br /&gt;
&lt;br /&gt;
    return result;&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da statische Methoden zu Klassen gehören, müssen sie anders aufgerufen werden, als normale Methoden:&lt;br /&gt;
&amp;lt;code=java&amp;gt;Point a = ...&lt;br /&gt;
Point b = ...&lt;br /&gt;
&lt;br /&gt;
// Aufruf einer normalen Methode: das Objekt wird angesprochen&lt;br /&gt;
int x = a.getX();&lt;br /&gt;
&lt;br /&gt;
// Aufruf einer statischen Methode: die Klasse wird angesprochen&lt;br /&gt;
Point m = Point.max( a, b );&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== abstrakte Methoden ==&lt;br /&gt;
Als abstrakte Methoden bezeichnet man Methoden, die keinen Rumpf besitzen (anstelle des Rumpfes wird ein Semikolon geschrieben). Abstrakte Methoden können nur in [[abstrakte_Klasse_(Java)|abstrakten Klassen]] oder [[Interface_(Java)|Interfaces]] vorkommen. Sie müssen stets von einer erbenden Klasse Implementiert werden.&lt;br /&gt;
&amp;lt;code=java&amp;gt;public abstract int operation( int a, int b );&amp;lt;/code=java&amp;gt;&lt;br /&gt;
Abstrakte Methoden können nicht statisch oder private sein, da sie sonst nicht überschreibbar wären.&lt;br /&gt;
&lt;br /&gt;
== finale Methoden ==&lt;br /&gt;
Finale Methoden lassen sich nicht überschreiben. Das kann theoretisch Geschwindigkeitsvorteile ergeben, macht aber die Verwendung der Klasse, in der die finale Methode ist, mühselig.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort &amp;quot;final&amp;quot; wird verwendet, um eine finale Methode zu definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code=java&amp;gt;public final double min( double a, double b ){&lt;br /&gt;
  if( a &amp;lt; b )&lt;br /&gt;
    return a;&lt;br /&gt;
  else&lt;br /&gt;
    return b;&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Java]]&lt;/div&gt;</summary>
		<author><name>Beni</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=API_Dokumentation_(Java)&amp;diff=1603</id>
		<title>API Dokumentation (Java)</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=API_Dokumentation_(Java)&amp;diff=1603"/>
		<updated>2007-02-26T21:35:35Z</updated>

		<summary type="html">&lt;p&gt;Beni: Links korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Java Runtime Environment (kurz [[JRE]]) bietet viele tausend [[Klasse_(Java)|Klassen]], und nochmehr [[Methode_(Java)|Methoden]]. Es ist nur schwer möglich, den Überblick über soviele Informationen zu behalten, wenn man nur den Quellcode zur verfügung hat.&lt;br /&gt;
&lt;br /&gt;
Deshalb wurde die &amp;quot;API Dokumentation&amp;quot; geschrieben.&lt;br /&gt;
&lt;br /&gt;
Die API Dokumentation, kurz API, kann man bei Sun [http://java.sun.com/] herunterladen, für Java 1.5 gibt es auch eine Onlineversion [http://java.sun.com/j2se/1.5.0/docs/api/index.html].&lt;br /&gt;
&lt;br /&gt;
== Aufbau der API Dokumentation ==&lt;br /&gt;
Die API besteht aus 3 Fenstern:&lt;br /&gt;
* Oben links sind sämtliche [[Package_(Java)|Packages]] aufgeführt&lt;br /&gt;
* Unten links sind die [[Klasse_(Java)|Klassen]] des aktuell gewählten Packages aufgelistet&lt;br /&gt;
* Rechts ist ein Multifunktionsfenster&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es einige Demonstrationen und Tutorials [http://java.sun.com/j2se/1.5.0/docs/#demos] in der API Dokumentation zu finden.&lt;br /&gt;
&lt;br /&gt;
== Das Multifunktionsfenster ==&lt;br /&gt;
Das Fenster auf der rechten Seite der API hat 8 Funktionen, welche in den Leisten oben und unten ausgewählt werden können. Die Funktionen sind:&lt;br /&gt;
===Overview===&lt;br /&gt;
Eine Liste aller verfübgarer Packages. Auf der linken Seite der Tabelle befindet sich der Name des Packages, rechts eine Beschreibung, für was die Klassen des Packages verwendet werden.&lt;br /&gt;
&lt;br /&gt;
===Package===&lt;br /&gt;
Eine Liste aller Elemente welche in einem Package sind. Für jedes Element gibt es eine kurze Beschreibung, wofür es verwendet wird.&lt;br /&gt;
Elemente können [[Interface_(Java)|Interfaces]], [[Klasse_(Java)|Klassen]], [[Exception_(Java)|Exceptions]], [[Error_(Java)|Errors]], [[Enum_(Java)|Enumerationen]] oder [[Annotation_(Java)|Annotations]] sein.&lt;br /&gt;
&lt;br /&gt;
===Class===&lt;br /&gt;
Diese Ansicht wird verwendet um Elemente eines Packages genauer zu beschreiben. Hauptsächlich sind dies Klassen, aber auch Interfaces, Enumerationen o.ä. wird hier angezeigt.&lt;br /&gt;
&lt;br /&gt;
Diese Ansicht besteht aus 3 Sektionen:&lt;br /&gt;
* &#039;&#039;&#039;Beschreibung&#039;&#039;&#039;: Eine Beschreibung des aktuellen Elementes. Dies beinhaltet die Vererbungshierarchie und einen längeren Text.&lt;br /&gt;
* &#039;&#039;&#039;Zusammenfassung&#039;&#039;&#039;: Eine Liste aller [[Innere_Klasse_(Java)|inneren Klassen]], [[Variable|Variablen]], [[Konstruktor_(Java)|Konstruktoren]] und Methoden.&lt;br /&gt;
* &#039;&#039;&#039;Details&#039;&#039;&#039;: Für jeden Eintrag in der Zusammenfassung gibt es noch eine detailierte Beschreibung.&lt;br /&gt;
&lt;br /&gt;
===Use===&lt;br /&gt;
Use zeigt an, wo ein Element (Klasse, Interface, Enumeration, etc.) benutzt wird. Sortiert nach Packages wird gezeigt, wer von dem Element erbt, wer das Element als Variable benutzt, wo das Element als Argument oder Rückgabewert einer Methode vorkommt, etc.&lt;br /&gt;
&lt;br /&gt;
===Tree===&lt;br /&gt;
Hier wird die komplette Vererbungshierarchie entweder aller Klassen überhaupt, oder aller Klasen eines Packages, angezeigt.&lt;br /&gt;
&lt;br /&gt;
===Deprecated===&lt;br /&gt;
Eine Liste aller Klassen, Interfaces, Methoden, etc. welche [[Deprecated]] (veraltet) sind.&lt;br /&gt;
&lt;br /&gt;
===Index===&lt;br /&gt;
Index ist eine alphabetische Liste aller Elemente welche in der API Dokumentation gefunden werden können.&lt;br /&gt;
&lt;br /&gt;
===Help===&lt;br /&gt;
Eine Hilfe welche dasselbe erzählt, was auch auf dieser Page steht.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Java]]&lt;/div&gt;</summary>
		<author><name>Beni</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=TableRowSorter_(Java_API)&amp;diff=1663</id>
		<title>TableRowSorter (Java API)</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=TableRowSorter_(Java_API)&amp;diff=1663"/>
		<updated>2007-02-25T13:09:26Z</updated>

		<summary type="html">&lt;p&gt;Beni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Der &#039;&#039;TableRowSorter&#039;&#039; ist ein [[RowSorter_(Java_API)|RowSorter]] der speziell für die Verwendung mit einem [[JTable_(Java_API)|JTable]] geschrieben wurde.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird die Methode &#039;&#039;&#039;getColumnClass&#039;&#039;&#039; vom zu sortierenden [[TableModel_(Java_API)|TableModel]] benutzt, um herauszufinden, welcher Typ Objekte in einer Spalte angezeigt werden. Besitzt der Typ eine natürliche Sortierung (durch das [[Interface_(Java)|Interface]] [[Comparable_(Java_API)|Comparable]] angezeigt), so wird diese Sortierung verwendet. Andernfalls werden die Zellen in [[String_(Java_API)|Strings]] umgewandelt, und alphabetisch geordnet.&lt;br /&gt;
&lt;br /&gt;
Man kann allerdings mit der Methode &#039;&#039;&#039;setComparator&#039;&#039;&#039; für jede einzelne Spalte angeben, welcher [[Comparator_(Java_API)|Comparator]] verwendet werden soll, um zwei Zellen zu vergleichen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich kann man einen &#039;&#039;TableStringConverter&#039;&#039; setzen, der jede Zelle der Tabelle in einen &#039;&#039;String&#039;&#039; umwandeln kann, dabei aber nicht denselben &#039;&#039;String&#039;&#039; produzieren muss, wie in der &#039;&#039;JTable&#039;&#039; angezeigt wird.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Java_API]]&lt;/div&gt;</summary>
		<author><name>Beni</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=JTableHeader_(Java_API)&amp;diff=1647</id>
		<title>JTableHeader (Java API)</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=JTableHeader_(Java_API)&amp;diff=1647"/>
		<updated>2007-02-25T13:09:21Z</updated>

		<summary type="html">&lt;p&gt;Beni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Der &#039;&#039;JTableHeader&#039;&#039; ist eine [[Component_(Java_API)|Component]] die oberhalb eines [[JTable_(Java_API)|JTables]] angezeigt wird. Für jede Spalte der Tabelle zeichnet der &#039;&#039;JTableHeader&#039;&#039; einen Titel. Diesen Titel kann der Benutzer mit der Maus ergreiffe, hin- und herschieben, oder die Breite der Spalte verändern.&lt;br /&gt;
&lt;br /&gt;
Wie die Titel normalerweise gezeichnet werden, kann über die [[Methode_(Java)|Methode]] &#039;&#039;&#039;setDefaultRenderer&#039;&#039;&#039;, die einen [[TableCellRenderer_(Java_API)|TableCellRenderer]] erwartet, bestimmt werden. Der Renderer zeichnet jeden einzelnen Titel unabhängig von den anderen Titeln.&lt;br /&gt;
&lt;br /&gt;
Ist mehr Kontrolle erfoderlich, kann auch der Header-Renderer der Spalte direkt gesetzt werden. Dazu wird die Methode &#039;&#039;&#039;setHeaderRenderer&#039;&#039;&#039; der [[TableColumn_(Java_API)|TableColumn]] benutzt, deren Titel gesetzt werden soll.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Java_API]]&lt;/div&gt;</summary>
		<author><name>Beni</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=RowSorter_(Java_API)&amp;diff=1651</id>
		<title>RowSorter (Java API)</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=RowSorter_(Java_API)&amp;diff=1651"/>
		<updated>2007-02-25T13:09:17Z</updated>

		<summary type="html">&lt;p&gt;Beni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Der &#039;&#039;RowSorter&#039;&#039; wird verwendet, um irgendeine graphische Tabelle (oder Liste) zu sortieren. Der &#039;&#039;RowSorter&#039;&#039; wird derzeit hauptsächlich von der [[JTable_(Java_API)|JTable]] verwendet, um die Zeilen nach einer oder mehreren Spalten zu sortieren, und um Zeilen auszublenden. Entsprechend wird in diesem Artikel immer davon ausgegangen, dass eine &#039;&#039;JTable&#039;&#039; involviert ist.&lt;br /&gt;
Der &#039;&#039;RowSorter&#039;&#039; ändert nicht direkt etwas an der &#039;&#039;JTable&#039;&#039; oder am [[TableModel_(Java_API)|TableModel]], er bietet nur Informationen, welche Zeile mit welcher vertauscht werden soll.&lt;br /&gt;
&lt;br /&gt;
Bevor man einen &#039;&#039;RowSorter&#039;&#039; implementiert, sollte man einen Blick auf die schon existierende Implementation [[TableRowSorter_(Java_API)|TableRowSorter]] werfen. In den meisten Fällen werden alle benötigten Funktionen schon vom &#039;&#039;TableRowSorter&#039;&#039; abgedeckt.&lt;br /&gt;
&lt;br /&gt;
Die [[Methode_(Java)|Methoden]] des &#039;&#039;RowSorters&#039;&#039; lassen sich grob in 3 Gruppen gliedern:&lt;br /&gt;
= Konvertierung =&lt;br /&gt;
* Die Methode &#039;&#039;&#039;convertRowIndexToView&#039;&#039;&#039; bekommt als Argument eine Zeile des Models, und sagt dem Aufrufer, an welcher Position diese Zeile angezeigt werden soll. Wenn die Zeile garnicht gezeigt werden soll, so gibt diese Methode -1 zurück.&lt;br /&gt;
* Die Methode &#039;&#039;&#039;convertRowIndexToView&#039;&#039;&#039; bekommt als Argument die Position an der etwas gezeichnet wird, und sagt dem Aufrufer, welche Zeile dies im Model entspricht.&lt;br /&gt;
&lt;br /&gt;
= Interaktion =&lt;br /&gt;
* Wann immer der Benutzer die Tabelle neu sortieren möchte, wird &#039;&#039;&#039;toggleSortOrder&#039;&#039;&#039; aufgerufen. Das einzige Argument sagt dem &#039;&#039;RowSorter&#039;&#039;, welche Spalte betroffen ist. Nachdem der &#039;&#039;RowSorter&#039;&#039; seine internen Strukturen aktualisiert hat, muss er allfällige [[RowSortListener_(Java_API)|RowSortListener]] über die Veränderung informieren.&lt;br /&gt;
* Die Methoden &#039;&#039;&#039;get/setSortKeys&#039;&#039;&#039; werden benutzt, um die Sortierungen direkt zu setzen oder abzufragen. Der erste Eintrag der Liste ist der wichtigste, der letzte hingegen der unbedeutendste. Eine &#039;&#039;JTable&#039;&#039; zeichnet meist einen kleinen Pfeil über der Spalte, die vom ersten Eintrag betroffen ist.&lt;br /&gt;
&lt;br /&gt;
= Information =&lt;br /&gt;
* Die verschiedenen Methoden &#039;&#039;&#039;rowsInserted/Updated/Removed&#039;&#039;&#039; und &#039;&#039;&#039;allRowsChanged&#039;&#039;&#039; werden automatisch aufgerufen, wenn das benutzte Model verändert wird (der &#039;&#039;RowSorter&#039;&#039; muss also keine Observer beim Model registrieren).&lt;br /&gt;
* &#039;&#039;&#039;add/removeRowSorterListener&#039;&#039;&#039; registriert oder entfernt einen [[RowSorterListener_(Java_API)|RowSorterListener]]. Diese Listener müssen aufgerufen werden, wenn die Sortierreihenfolge verändert wurde.&lt;br /&gt;
* &#039;&#039;&#039;getModel&#039;&#039;&#039;, &#039;&#039;&#039;getView/ModelRowCount&#039;&#039;&#039; liefern schliesslich zusätzliche Informationen über das Model und die Ansicht.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Java_API]]&lt;/div&gt;</summary>
		<author><name>Beni</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=TableColumnModel_(Java_API)&amp;diff=1659</id>
		<title>TableColumnModel (Java API)</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=TableColumnModel_(Java_API)&amp;diff=1659"/>
		<updated>2007-02-18T22:03:16Z</updated>

		<summary type="html">&lt;p&gt;Beni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das &#039;&#039;TableColumnModel&#039;&#039; ist eine Sammlung von [[TableColumn_(Java_API)|TableColumns]], welche von einer [[JTable_(Java_API)|JTable]] verwendet werden. Das &#039;&#039;TableColumnModel&#039;&#039; sorgt für die Reihenfolge, Bewegung und auch die Selektion der Spalten.&lt;br /&gt;
&lt;br /&gt;
Ein &#039;&#039;TableColumnModel&#039;&#039; ist nur ein [[Interface_(Java)|Interface]], das [[Methoden_(Java)|Methoden]] vorschreibt, um Spalten hinzuzufügen, zu entfernen, oder zu verschieben. Ausserdem sollen Implementationen die Möglichkeit bieten, alle Spalten aufzulisten. Die Kommunikation mit der &amp;quot;Aussenwelt&amp;quot; erfolgt über [[TableColumnModelListener_(Java_API)|TableColumnModelListeners]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;TableColumnModel&#039;&#039; wird von [[DefaultTableColumnModel_(Java_API)|DefaultTableColumnModel]] implementiert. Dieses &#039;&#039;DefaultTableColumnModel&#039;&#039; wird auch normalerweise von der &#039;&#039;JTable&#039;&#039; verwendet.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Java_API]]&lt;/div&gt;</summary>
		<author><name>Beni</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=TableColumn_(Java_API)&amp;diff=1657</id>
		<title>TableColumn (Java API)</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=TableColumn_(Java_API)&amp;diff=1657"/>
		<updated>2007-02-18T21:00:54Z</updated>

		<summary type="html">&lt;p&gt;Beni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eine &#039;&#039;TableColumn&#039;&#039; stellt eine einzelne Spalte in einer [[JTable_(Java_API)|JTable]] dar. Eine &#039;&#039;TableColumn&#039;&#039; kann, muss aber nicht, spezielle Informationen zu der repräsentierten Spalte haben:&lt;br /&gt;
* Den [[TableCellRenderer_(Java_API)|TableCellRenderer]] mit dem einzelne Zellen der Spalte gezeichnet werden.&lt;br /&gt;
* Den [[TableCellEditor_(Java_API)|TableCellEditor]] mit dem der Benutzer einzelne Zellen der Spalte verändern kann.&lt;br /&gt;
* Grössenangaben wie minimale/maximale und bevorzugte Grösse&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;JTable&#039;&#039; erzeugt normalerweise &#039;&#039;TableColumns&#039;&#039; automatisch, sobald sie benötigt werden. Man kann dieses Verhalten aber mit der [[Methode_(Java)|Methode]]&#039;&#039; setAutoCreateColumnsFromModel&#039;&#039; abschalten, und jede Spalte selbst erzeugen. Das folgende Beispiel zeigt eine &#039;&#039;JTable&#039;&#039;, deren &#039;&#039;TableModel&#039;&#039; drei Spalten vorgibt, die aber vier Spalten anzeigt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code=java&amp;gt;package demo;&lt;br /&gt;
&lt;br /&gt;
import java.awt.BorderLayout;&lt;br /&gt;
&lt;br /&gt;
import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.JScrollPane;&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
import javax.swing.table.*;&lt;br /&gt;
 &lt;br /&gt;
public class JTableDemo{&lt;br /&gt;
    public static void main( String[] args ){&lt;br /&gt;
        // Die JTable initialisieren&lt;br /&gt;
        JTable table = new JTable();&lt;br /&gt;
        &lt;br /&gt;
        // Spalten sollen nicht automatisch erzeugt werden&lt;br /&gt;
        table.setAutoCreateColumnsFromModel( false );&lt;br /&gt;
        &lt;br /&gt;
        // Daten setzen&lt;br /&gt;
        table.setModel( createModel() );&lt;br /&gt;
        &lt;br /&gt;
        // Spalten bestimmen&lt;br /&gt;
        table.setColumnModel( createColumnModel() );&lt;br /&gt;
         &lt;br /&gt;
        // Tabelle anzeigen&lt;br /&gt;
        JFrame frame = new JFrame( &amp;quot;Demo&amp;quot; );&lt;br /&gt;
        frame.add( new JScrollPane( table ), BorderLayout.CENTER );&lt;br /&gt;
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );&lt;br /&gt;
        frame.pack();&lt;br /&gt;
        frame.setVisible( true );&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public static TableColumnModel createColumnModel(){&lt;br /&gt;
        // Ein Behälter für die Spalten erzeugen&lt;br /&gt;
        TableColumnModel columns = new DefaultTableColumnModel();&lt;br /&gt;
        &lt;br /&gt;
        // Die 4 Spalten erzeugen. Jede Spalte kann verschiedene&lt;br /&gt;
        // Eigenschaften haben.&lt;br /&gt;
        TableColumn c1 = new TableColumn( 0 );&lt;br /&gt;
        c1.setHeaderValue( &amp;quot;ColA&amp;quot; );&lt;br /&gt;
        c1.setPreferredWidth( 35 );&lt;br /&gt;
        c1.setMaxWidth( 50 );&lt;br /&gt;
        &lt;br /&gt;
        TableColumn c2 = new TableColumn( 1 );&lt;br /&gt;
        c2.setHeaderValue( &amp;quot;ColB&amp;quot; );&lt;br /&gt;
        c2.setPreferredWidth( 60 );&lt;br /&gt;
        c2.setMinWidth( 60 );&lt;br /&gt;
        c2.setMaxWidth( 120 );&lt;br /&gt;
        &lt;br /&gt;
        TableColumn c3 = new TableColumn( 2 );&lt;br /&gt;
        c3.setHeaderValue( &amp;quot;ColC&amp;quot; );&lt;br /&gt;
        c3.setPreferredWidth( 10 );&lt;br /&gt;
        c3.setResizable( false );&lt;br /&gt;
        &lt;br /&gt;
        // Die letzte Spalte zeigt stets dasselbe wie die &lt;br /&gt;
        // zweitletzte Spalte, denn beide Spalten benutzen&lt;br /&gt;
        // dieselbe Model-Spalte als Datenquelle&lt;br /&gt;
        TableColumn c4 = new TableColumn( 2 );&lt;br /&gt;
        c4.setHeaderValue( &amp;quot;ColC-2&amp;quot; );&lt;br /&gt;
        c4.setPreferredWidth( 10 );&lt;br /&gt;
        &lt;br /&gt;
        columns.addColumn( c1 );&lt;br /&gt;
        columns.addColumn( c2 );&lt;br /&gt;
        columns.addColumn( c3 );&lt;br /&gt;
        columns.addColumn( c4 );&lt;br /&gt;
        &lt;br /&gt;
        return columns;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public static TableModel createModel(){&lt;br /&gt;
        DefaultTableModel model = new DefaultTableModel( &lt;br /&gt;
                new Object[]{ &amp;quot;A&amp;quot;, &amp;quot;B&amp;quot;, &amp;quot;C&amp;quot; }, 0);&lt;br /&gt;
        &lt;br /&gt;
        model.addRow( new Object[]{ &amp;quot;C1&amp;quot;, &amp;quot;C2&amp;quot;, &amp;quot;C3&amp;quot; });&lt;br /&gt;
        return model;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Java_API]]&lt;/div&gt;</summary>
		<author><name>Beni</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=TableCellEditor_(Java_API)&amp;diff=1653</id>
		<title>TableCellEditor (Java API)</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=TableCellEditor_(Java_API)&amp;diff=1653"/>
		<updated>2007-02-18T20:59:07Z</updated>

		<summary type="html">&lt;p&gt;Beni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein &#039;&#039;TableCellEditor&#039;&#039; wird von einer [[JTable_(Java_API)|JTable]] benutzt, um dem Benutzer die Möglichkeit zu bieten, einzelne Zellen der Tabelle zu bearbeiten. Die &#039;&#039;JTable&#039;&#039; geht dabei immer gleich vor: zuerst wird die [[Methode_(Java)|Methode]] &#039;&#039;getTableCellEditor&#039;&#039; aufgerufen. Diese Methode gibt eine [[Component_(Java_API)|Component]] zurück, welche auf der &#039;&#039;JTable&#039;&#039; angezeigt wird. Der Benutzer kann diesen Editor solange verwenden, bis der &#039;&#039;TableCellEditor&#039;&#039; oder die &#039;&#039;JTable&#039;&#039; die Methode &#039;&#039;stopCellEditing&#039;&#039; oder &#039;&#039;cancelCellEditing&#039;&#039; aufruft. Diese Methoden feuern ein Event in die registrierten [[CellEditorListener_(Java_API)|CellEditorListener]], müssen aber weiter nichts tun.&lt;br /&gt;
Wurde das Stop-Event gefeuert, so wird der Editor nach seinem aktuellen Wert befragt (über die Methode &#039;&#039;getCellEditorValue&#039;&#039;), und dieser Wert wird in das [[TableModel_(Java_API)|TableModel]] geschrieben. Wurde hingegen das Cancel-Event gefeuert, wird die Aktion einfach abgebrochen, und die Veränderungen verworfen.&lt;br /&gt;
&lt;br /&gt;
Ein einfacher &#039;&#039;TableCellEditor&#039;&#039; könnte folgendermassen aussehen:&lt;br /&gt;
&amp;lt;code=java&amp;gt;import java.awt.Component;&lt;br /&gt;
import java.util.ArrayList;&lt;br /&gt;
import java.util.EventObject;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
&lt;br /&gt;
import javax.swing.JTable;&lt;br /&gt;
import javax.swing.JTextField;&lt;br /&gt;
import javax.swing.event.CellEditorListener;&lt;br /&gt;
import javax.swing.event.ChangeEvent;&lt;br /&gt;
import javax.swing.table.TableCellEditor;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Ein einfacher TableCellEditor der ein String in einem&lt;br /&gt;
 * Textfeld darstellt.&lt;br /&gt;
 */&lt;br /&gt;
public class DemoEditor implements TableCellEditor{&lt;br /&gt;
	/** das Textfeld des Editors */&lt;br /&gt;
	private JTextField textField = new JTextField();&lt;br /&gt;
	/** Observer des Editors */&lt;br /&gt;
	private List&amp;lt;CellEditorListener&amp;gt; listeners = new ArrayList&amp;lt;CellEditorListener&amp;gt;();&lt;br /&gt;
	&lt;br /&gt;
	// Prepariert den Editor, so dass ein neuer Wert angezeigt wird.&lt;br /&gt;
	public Component getTableCellEditorComponent( &lt;br /&gt;
			JTable table, Object value, boolean isSelected, int row, int column ){&lt;br /&gt;
&lt;br /&gt;
		textField.setText( String.valueOf( value ) );&lt;br /&gt;
		return textField;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public void addCellEditorListener( CellEditorListener l ){&lt;br /&gt;
		listeners.add( l );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public void removeCellEditorListener( CellEditorListener l ){&lt;br /&gt;
		listeners.remove( l );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Gibt den aktuellen Wert des Editors zurück.&lt;br /&gt;
	public Object getCellEditorValue(){&lt;br /&gt;
		return textField.getText();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public boolean isCellEditable( EventObject anEvent ){&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public boolean shouldSelectCell( EventObject anEvent ){&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Informiert alle Observer, dass die Aktion abgebrochen wurde.&lt;br /&gt;
	public void cancelCellEditing(){&lt;br /&gt;
		ChangeEvent event = new ChangeEvent( this );&lt;br /&gt;
		for( CellEditorListener listener : &lt;br /&gt;
			listeners.toArray( new CellEditorListener[ listeners.size() ] )){&lt;br /&gt;
		&lt;br /&gt;
			listener.editingCanceled( event );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Informiert alle Observer, dass der Wert gespeichert werden soll.&lt;br /&gt;
	public boolean stopCellEditing(){&lt;br /&gt;
		ChangeEvent event = new ChangeEvent( this );&lt;br /&gt;
		for( CellEditorListener listener : &lt;br /&gt;
			listeners.toArray( new CellEditorListener[ listeners.size() ] )){&lt;br /&gt;
			&lt;br /&gt;
			listener.editingStopped( event );&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		// informiert den Aufrufer, dass der Input korrekt ist.&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Java_API]]&lt;/div&gt;</summary>
		<author><name>Beni</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=TableCellRenderer_(Java_API)&amp;diff=1655</id>
		<title>TableCellRenderer (Java API)</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=TableCellRenderer_(Java_API)&amp;diff=1655"/>
		<updated>2007-02-18T20:58:28Z</updated>

		<summary type="html">&lt;p&gt;Beni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;TableCellRenderer&#039;&#039; ist ein [[Interface_(Java)|Interface]] der [[Java]] [[API]]. &#039;&#039;TableCellRenderer&#039;&#039; werden von der [[JTable_(Java_API)|JTable]] benutzt, um einzelne Zellen zu zeichnen.&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;JTable&#039;&#039; fordert den &#039;&#039;TableCellRenderer&#039;&#039; über die Methode &#039;&#039;getTableCellRendererComponent&#039;&#039; auf, eine graphische Darstellung, in Form einer [[Component_(Java_API)|Component]], zu generieren. Diese &#039;&#039;Component&#039;&#039; wird anschliessend in eine Zelle eingepasst, und gezeichnet. Nach dem Zeichenvorgang, wird die &#039;&#039;Component&#039;&#039; von der &#039;&#039;JTable&#039;&#039; nicht mehr benötigt, und kann vom &#039;&#039;TableCellRenderer&#039;&#039; wiederverwertet werden.&lt;br /&gt;
&lt;br /&gt;
Zu beachten ist, dass der Benutzer nur ein Bild des &#039;&#039;TableCellEditors&#039;&#039; sieht, aber nichts anklicken kann. Wenn eine Zelle editiert werden soll, wird ein [[TableCellEditor_(Java_API)|TableCellEditor]] benötigt.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt einen sehr kleinen Renderer, der für boolsche Werte eine [[JCheckBox_(Java_API)|JCheckBox]] zeichnet, für andere Werte nur ein leeres Feld.&lt;br /&gt;
&amp;lt;code=java&amp;gt;public class BooleanRenderer implements TableCellRenderer{&lt;br /&gt;
  // Die zwei graphischen Repräsentationen dieses Renderers&lt;br /&gt;
  private JCheckBox box = new JCheckBox();&lt;br /&gt;
  private JLabel empty = new JLabel();&lt;br /&gt;
&lt;br /&gt;
  public Component getTableCellRendererComponent(&lt;br /&gt;
      JTable table, &lt;br /&gt;
      Object value,  &lt;br /&gt;
      boolean isSelected,&lt;br /&gt;
      boolean hasFocus, &lt;br /&gt;
      int row, &lt;br /&gt;
      int column){&lt;br /&gt;
&lt;br /&gt;
    if( value instanceof Boolean ){&lt;br /&gt;
      // Die Box selektieren&lt;br /&gt;
      box.setSelected( Boolean.TRUE.equals( value ));&lt;br /&gt;
      // Die Box wird nun gezeichnet&lt;br /&gt;
      return box;&lt;br /&gt;
    }&lt;br /&gt;
    else{&lt;br /&gt;
      // Das leere Feld wird nun gezeichnet&lt;br /&gt;
      return empty;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
[[Kategorie:Java_API]]&lt;/div&gt;</summary>
		<author><name>Beni</name></author>
	</entry>
	<entry>
		<id>https://wiki.byte-welt.net/index.php?title=TableModel_(Java_API)&amp;diff=1661</id>
		<title>TableModel (Java API)</title>
		<link rel="alternate" type="text/html" href="https://wiki.byte-welt.net/index.php?title=TableModel_(Java_API)&amp;diff=1661"/>
		<updated>2007-02-18T20:57:26Z</updated>

		<summary type="html">&lt;p&gt;Beni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein TableModel enthält Daten, welche von einer [[JTable_(Java_API)|JTable]] angezeigt werden. Das &#039;&#039;TableModel&#039;&#039; stellt eine Tabelle, eine gitterförmige Datenstruktur, dar.&lt;br /&gt;
&lt;br /&gt;
Ein &#039;&#039;TableModel&#039;&#039; kommuniziert mit seiner Aussenwelt über [[TableModelListener_(Java_API)|TableModelListener]]. In einem [[MVC-Pattern]] entspricht es dem &#039;&#039;M&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Methoden ==&lt;br /&gt;
&#039;&#039;TableModel&#039;&#039; ist ein [[Interface_(Java)|Interface]] welches folgende [[Methode_(Java)|Methoden]] vorschreibt:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;getColumnCount&#039;&#039;&#039; liefert die Anzahl Spalten der Tabelle.&lt;br /&gt;
* &#039;&#039;&#039;getRowCount&#039;&#039;&#039; liefert die Anzahl Zeilen der Tabelle.&lt;br /&gt;
* &#039;&#039;&#039;getColumnName&#039;&#039;&#039; liefert den Namen einer Spalte. Der Name wird über der Spalte in einem speziellen Feld (dem Header) angezeigt.&lt;br /&gt;
* &#039;&#039;&#039;getColumnClass&#039;&#039;&#039; liefert den Typ der Einträge einer Spalte. Je nach Typ kann die JTable die Spalte anders darstellen. [[Boolean_(Java)|Boolsche Werte]] werden z.B. mit einer [[JCheckBox_(Java_API)|JCheckBox]] dargestellt, [[String_(Java_API)|Strings]] hingegen als Text.&lt;br /&gt;
Im folgenden Stück Code wird für die erste Spalte der Typ &#039;&#039;String&#039;&#039;, für die zweite Spalte der Typ [[Integer_(Java_API)|Integer]] angegeben. &lt;br /&gt;
&amp;lt;code=java&amp;gt;public Class&amp;lt;?&amp;gt; getColumnClass( int column ){&lt;br /&gt;
  switch( column ){&lt;br /&gt;
    case 0: return String.class;&lt;br /&gt;
    case 1: return Integer.class;&lt;br /&gt;
    default: throw new IllegalArgumentException( &amp;quot;unknown column: &amp;quot; + column );&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/code=java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;getValueAt&#039;&#039;&#039; liefert den Wert einer Zelle. Der Typ dieses Wertes muss der Angabe von &#039;&#039;getColumnClass&#039;&#039; entsprechen.&lt;br /&gt;
* &#039;&#039;&#039;isCellEditable&#039;&#039;&#039; sagt der Tabelle, ob eine bestimmte Zelle durch den Benutzer bearbeitet werden darf. Die Methode &#039;&#039;getColumnClass&#039;&#039; bestimmt masgeblich, wie die Zelle bearbeitet wird; z.B. wird für eine Spalte mit Strings ein Textfeld angeboten.&lt;br /&gt;
* &#039;&#039;&#039;setValueAt&#039;&#039;&#039; ist das Gegenstück zu &#039;&#039;getValueAt&#039;&#039;, mit dieser Methode wird der Wert einer Zelle gesetzt. Diese Methode wird von der JTable aufgerufen, nachdem ein [[TableCellEditor_(Java_API)|TableCellEditor]] einen Wert verändert hat.&lt;br /&gt;
* &#039;&#039;&#039;addTableModelListener&#039;&#039;&#039; fügt dem Model einen [[TableModelListener_(Java_API)|TableModelListener]] hinzu. Dieser Listener muss immer benachrichtigt werden, wenn sich Daten des Models verändern. Mit Hilfe des [[TableModelEvent_(Java_API)|TableModelEvents]] kann eine genau Angabe gemacht werden, welcher Teil des Models sich verändert hat. z.B. könnte eine Zeile gelöscht worden sein, oder der Wert einer Zelle wurde verändert.&lt;br /&gt;
* &#039;&#039;&#039;removeTableModelListener&#039;&#039;&#039; entfernt einen früher hinzugefügten &#039;&#039;TableModelListener&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Implementationen ==&lt;br /&gt;
Es gibt zwei oft benutze Implementationen:&lt;br /&gt;
* Das &#039;&#039;&#039;AbstractTableModel&#039;&#039;&#039; kann als Grundlage eines eigenen TableModels dienen. Insbesondere bietet es Methoden für Verwaltung der [[TableModelListener]] an.&lt;br /&gt;
* Das &#039;&#039;&#039;DefaultTableModel&#039;&#039;&#039; ist ein einfaches Model, bei dem Zellen verändert, Spalten und Zeilen hinzugefügt oder gelöscht werden können. Für die meisten Anwendungen die nur einige Daten anzeigen möchten, sollte dieses Model vollständig ausreichen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Java_API]]&lt;/div&gt;</summary>
		<author><name>Beni</name></author>
	</entry>
</feed>