JTable - Teil 2 - Wie kommen Daten in die Tabelle?

Status
Nicht offen für weitere Antworten.
B

Beni

Gast
JTable - Teil 2 - Wie kommen Daten in die Tabelle?

Das JTable ist eine sehr anpassungsfähige GUI-Componente. Doch wie kommen eigentlich die Daten in das JTable hinein?

1. Möglichkeit - 2d Array
Die wohl einfachste Methode ist einen 2-dimensionalen Array zu benutzen.
Das JTable bietet einen entsprechenden Konstruktor:

Java:
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;

public class JTableDemo{
	public static void main( String[] args ){
		// Die Daten für das Table
		String[][] data = new String[][]{
				{"a", "b", "c", "d"},
				{"e", "f", "g", "h"},
				{"i", "j", "k", "l"}
		};
		
		// Die Column-Titles
		String[] title = new String[]{
				"A", "B", "C", "D"
		};
		
		// Das JTable initialisieren
		JTable table = new JTable( data, title );
		
		JFrame frame = new JFrame( "Demo" );
		frame.getContentPane().add( new JScrollPane( table ) );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.pack();
		frame.setVisible( true );
	}
}

beni-albums-jtable-picture53-table-01.png


Diese Methode ist sehr statisch, es ist später nicht mehr gut möglich, Daten zu ändern.

2. Möglichkeit - Vectoren
Mit ineinander gesetzten Vektoren:

Java:
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

public class JTableDemo{
	public static void main( String[] args ){
		// Die Daten für das Table
		Vector data = new Vector();
			Vector rowA = new Vector();
				rowA.add(  "1" );
				rowA.add(  "2" );
				rowA.add(  "3" );
				rowA.add(  "4" );
			Vector rowB = new Vector();
				rowB.add(  "5" );
				rowB.add(  "6" );
				rowB.add(  "7" );
				rowB.add(  "8" );
			Vector rowC = new Vector();
				rowC.add(  "9" );
				rowC.add( "10" );
				rowC.add( "11" );
				rowC.add( "12" );
		
			data.add( rowA );
			data.add( rowB );
			data.add( rowC );
				
		// Die Titel für das Table
		Vector title = new Vector();
			title.add( "A" );
			title.add( "B" );
			title.add( "C" );
			title.add( "D" );
		
		// Das JTable initialisieren
		JTable table = new JTable(  data, title );
		
		JFrame frame = new JFrame( "Demo" );
		frame.getContentPane().add( new JScrollPane( table ) );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.pack();
		frame.setVisible( true );
	}
}

beni-albums-jtable-picture54-table-02.png


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.

3. Möglichkeit - DefaultTableModel
Mit einem DefaultTableModel.

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.

Was ein TableModel ist, wird im naechsten Teil behandelt.

Java:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class JTableDemo{
	public static void main( String[] args ){
		// Die Namen der Columns
		String[] titles = new String[]{ "A", "B", "C", "D" };
		
		// Das Model das wir verwenden werden. Hier setzten wir gleich die
		// Titel, aber es ist später immer noch möglich weitere Columns oder
		// Rows hinzuzufügen.
		final DefaultTableModel model = new DefaultTableModel( titles, 0 );
		
		// Das JTable initialisieren
		JTable table = new JTable( model );
		
		// Buttons, damit das alles schöner aussieht.
		final JButton buttonAddRow = new JButton( "add row" );
		final JButton buttonRemRow = new JButton( "remove row" );
		final JButton buttonAddCol = new JButton( "add column" );
		
		buttonRemRow.setEnabled( false );
		
		// Den Buttons ein paar Reaktionen geben
		buttonAddRow.addActionListener( new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				// Die Anzahl Columns (Breite) der Tabelle
				int size = model.getColumnCount();
				
				// einen neuen Vector mit Daten herstellen
				Vector newDatas = createDataVector( "row", size );
				
				// eine neue Row hinzufügen
				model.addRow( newDatas );
				
				
				// das Entfernen erlauben
				buttonRemRow.setEnabled( true );
			}
		});
		
		buttonAddCol.addActionListener( new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				int size = model.getRowCount();
				Vector newDatas = createDataVector( "column", size );
				String name = String.valueOf( model.getColumnCount() );
				model.addColumn( name, newDatas );
			}
		});
		
		buttonRemRow.addActionListener( new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				int size = model.getRowCount();
				int index = (int)(Math.random() * size);
				model.removeRow( index );
				
				buttonRemRow.setEnabled( size > 1 );
			}
		});
		
		JFrame frame = new JFrame( "Demo" );
		
		Container content = frame.getContentPane();
		
		content.add( new JScrollPane( table ), BorderLayout.CENTER );
		content.add( buttonAddRow, BorderLayout.NORTH );
		content.add( buttonRemRow, BorderLayout.SOUTH );
		content.add( buttonAddCol, BorderLayout.WEST );
		
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.pack();
		frame.setVisible( true );
	}
	
	public static Vector createDataVector( String prefix, int size ){
		Vector vector = new Vector( size );
		for( int i = 0; i < size; i++ )
			vector.add( prefix + " : " + size + " : " + i );
		
		return vector;
	}
}

beni-albums-jtable-picture55-table-03.png


Was geschieht hier?
Es gibt 3 JButtons, welche jeweils eine Row oder Column hinzufügen, oder eine Row entfernen.
Die seltsame Schreibweise addActionListener( ... ) stellen anonyme Klassen dar.

Die eigentliche Hauptaktion macht das DefaultTableModel "model", alles andere dient nur dazu, dem Benutzer eine Möglichkeit zu bieten mit der Tabelle zu spielen.
..
 
B

Beni

Gast
4. Möglichkeit - TableModel
Mit Hilfe eines TableModels.
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.
Das muss nicht in einer bestimmten Reihenfolge geschehen, das JTable nimmt einfach gerade das, was es benötigt.

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 "von Hand" die Daten vorsortieren, sondern man gibt sie einfach dann zurück, wenn sie auch tatsächlich benötigt werden.

Was ist nun, falls die Daten veraendert wurden (z.B. eine Row hinzugefuegt)?
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.
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.

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:
// source Das TableModel, welches verändert wurde

TableModelEvent(source); // Sämtliche Daten von source wurden verändert
TableModelEvent(source, TableModelEvent.HEADER_ROW); // Die Struktur der Daten wurde verändert, die Columns werden auf den Ursprungszustand gesetzt.
TableModelEvent(source, 1); // Row 1 wurde verändert
TableModelEvent(source, 3, 6); // Row 3, 4, 5, 6 wurden verändert
TableModelEvent(source, 2, 2, 6); // Die Zelle (2, 6) wurde verändert
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
TableModelEvent(source, 3, 6, TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE); // Die Rows mit den Indices 3, 4, 5 und 6 wurden gelöscht.

TableModelEvent(source, 2, 3, 5, TableModelEvent.INSERTED ) // Fehler: Es ist nicht möglich, dass Zelle (2,5) und (3,5) hinzugefügt werden.

Sicher bekannt ist das Verhältnis zwischen Button und ActionListener.
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.
Hier ist es genau umgekehrt: das TableModel startet die Aktion, die TableModelListener reagieren darauf.

Das folgende Beispiel zeigt, wie man dem JTable (indirekt) sagen kann, dass eine neue Row hinzugefügt wurde.
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.

mehr zu Listeners.

Zuerst das Frame, wie wir es verwenden möchten
Java:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

public class JTableDemo{
	public static void main( String[] args ){
		// Unser TableModel (siehe unten)
		final Model model = new Model();
		
		// Das JTable initialisieren
		JTable table = new JTable( model );
		
		// Buttons, damit das alles schöner aussieht.
		final JButton buttonVehicel = new JButton( "add vehicel" );
		
		// Den Buttons ein paar Reaktionen geben
		buttonVehicel.addActionListener( new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				// Die Anzahl Columns (Breite) der Tabelle
				int size = model.getRowCount();
				
				// einen neuen Vector mit Daten herstellen
				Vehicel vehicel = createVehicel( size );
				
				// ein neues Vehikel hinzufügen
				model.addVehicle( vehicel );
			}
		});
				
		JFrame frame = new JFrame( "Demo" );
		
		Container content = frame.getContentPane();
		
		content.add( new JScrollPane( table ), BorderLayout.CENTER );
		content.add( buttonVehicel, BorderLayout.SOUTH );
		
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.pack();
		frame.setVisible( true );
	}
	
	// Stellt einfach eine neue Instanz eines Vehikels her.
	public static Vehicel createVehicel( int index ){
		index = index % 5; // Modulo
		
		switch( index ){
			case 0: return new Vehicel( "Fahrrad", 1, 2, false );
			case 1: return new Vehicel( "Bus", 20, 4, true );
			case 2: return new Vehicel( "Pferd", 1, 0, false );
			case 3: return new Vehicel( "Zug", 1000, 80, true );
			case 4: return new Vehicel( "Truck", 2, 10, true );
			default: return null;	
		}
		
	}
}

Der Code für eine Datenstruktur "Vehicel"
Java:
// Das Vehikel ist eine total unabhängige Klasse, die mit einer
// Tabelle eigentlich gar nichts zu tun hat.
class Vehicel{
	private String name;
	private int places, wheels;
	private boolean motor;
	
	public Vehicel( String name, int places, int wheels, boolean motor ){
		this.name = name;
		this.places = places;
		this.wheels = wheels;
		this.motor = motor;
	}
	
	public String getName(){ return name; }
	public int getPlaces(){ return places; }
	public int getWheels(){ return wheels; }
	public boolean hasMotor(){ return motor; }
}

Das Model, dass die Vehicel in eine Form übersetzt, welche das JTable anzeigen kann
Java:
// Unsere Implementation des TableModels
class Model implements TableModel{
	private Vector vehicels = new Vector();
	private Vector listeners = new Vector();
	
	public void addVehicle( Vehicel vehicel ){
		// Das wird der Index des Vehikels werden
		int index = vehicels.size();
		vehicels.add( vehicel );
		
		// Jetzt werden alle Listeners benachrichtigt
		
		// Zuerst ein Event, "neue Row an der Stelle index" herstellen
		TableModelEvent e = new TableModelEvent( this, index, index, 
				TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT );
		
		// Nun das Event verschicken
		for( int i = 0, n = listeners.size(); i<n; i++ ){
			((TableModelListener)listeners.get( i )).tableChanged( e );
		}
	}
	
	// Die Anzahl Columns
	public int getColumnCount() {
		return 4;
	}
	
	// Die Anzahl Vehikel
	public int getRowCount() {
		return vehicels.size();
	}
	
	// Die Titel der einzelnen Columns
	public String getColumnName(int column) {
		switch( column ){
			case 0: return "Name";
			case 1: return "Fahrgäste";
			case 2: return "Räder";
			case 3: return "Besitzt Motor";
			default: return null;
		}
	}
	
	// Der Wert der Zelle (rowIndex, columnIndex)
	public Object getValueAt(int rowIndex, int columnIndex) {
		Vehicel vehicle = (Vehicel)vehicels.get( rowIndex );
		
		switch( columnIndex ){
			case 0: return vehicle.getName();
			case 1: return new Integer( vehicle.getPlaces() );
			case 2: return new Integer( vehicle.getWheels() );
			case 3: return vehicle.hasMotor() ? Boolean.TRUE : Boolean.FALSE; 
			default: return null;
		}
	}

	// Eine Angabe, welchen Typ von Objekten in den Columns angezeigt werden soll
	public Class getColumnClass(int columnIndex) {
		switch( columnIndex ){
			case 0: return String.class;
			case 1: return Integer.class;
			case 2: return Integer.class;
			case 3: return Boolean.class; 
			default: return null;
		}	
	}
	
	public void addTableModelListener(TableModelListener l) {
		listeners.add( l );
	}
	public void removeTableModelListener(TableModelListener l) {
		listeners.remove( l );
	}
	

	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return false;
	}
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		// nicht beachten
	}
}

beni-albums-jtable-picture56-table-04.png


API - TableModel
Ein ßberblick aller Methoden, die das Interface TableModel vorschreibt.

int getColumnCount()
Gibt die Anzahl Columns (Spalten) zurück. Dieser Wert muss natürlich >= 0 sein.

String getColumnName(int columnIndex)
Gibt den Namen einer Column zurück. Der Name wird als Titel im JTableHeader verwendet.

int getRowCount()
Gibt die Anzahl Rows (Zeilen) zurück. Wie der Wert bei "getColumnCount" muss dieser Wert >= 0 sein.

Object getValueAt(int rowIndex, int columnIndex)
Gibt den Wert der Zelle (rowIndex, columnIndex) zurück.
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.)

Primitive Datentypen wie int, double, ... werden am einfachsten in ihrere Wrapperklasse Integer, Double, ... zurückgegeben.

Das Object das hier zurückgegeben wird, muss eine Instanc von der Klasse sein, die bei #getColumnClass zurückgegeben wird.

Class getColumnClass(int columnIndex)
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...

z.B. die Klasse von String kann man so herausfinden:
Java:
Class string = String.class;

boolean isCellEditable(int rowIndex, int columnIndex)
Gibt an, ob diese Zelle editiert werden kann.
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).
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.

void setValueAt(Object aValue, int rowIndex, int columnIndex)
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.

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.

void addTableModelListener(TableModelListener l)
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).
Listener können vom JTable oder von anderen Klassen kommen, es muss das Model nicht interessieren.

void removeTableModelListener(TableModelListener l)
Entfernt einen TableModelListener. z.B. muss das JTable ja nicht mehr über Veränderungen informiert werden, falls das Model vom Table entfernt wurde...

API - TableModelEvent
Das TableModelEvent befördert Informationen von einem TableModel zu seinen TableModelListenern.

Konstruktoren
Das TableModelEvent hat verschiedene Konstruktoren. Je nach dem welcher mit welchen Argumenten benutzt wurde, bekommt das Event eine andere Bedeutung.

source ist immer das TableModel, in dem etwas passiert ist.

TableModelEvent(TableModel source)
Benutzen, falls die Veränderungen zu komplex für eine Beschreibung sind. Dann verliert das JTable allerdings viele Benutzereinstellungen, wie z.B. die Selektion.

TableModelEvent(TableModel source, int row)
Gibt an, dass eine Row (mit dem Index row) verändert wurde.
Allerdings kann row auch die Konstante HEADER_ROW sein, falls sich etwas mit der Titelleiste des JTables veraendert hat (z.B. ein Titel).

TableModelEvent(TableModel source, int firstRow, int lastRow)
Gibt an, dass alle Rows von firstRow bis und mit lastRow verändert wurden.

TableModelEvent(TableModel source, int firstRow, int lastRow, int column)
Gibt an, dass alle Rows von firstRow bis und mit lastRow verändert wurden.
column kann der Index einer einzigen Column sein, oder aber die Konstante ALL_COLUMNS falls mehrere Columns verändert wurden.

TableModelEvent(TableModel source, int firstRow, int lastRow, int column, int type)
Gibt an, dass alle Rows von firstRow bis und mit lastRow verändert wurden.
column kann der Index einer einzigen Column sein, oder aber die Konstante ALL_COLUMNS falls mehrere Columns verändert wurden.
type ist einer von INSERT, DELETE oder UPDATE.

Konstanten
static int ALL_COLUMNS
Wird für das Argument column verwendet, und gibt an, dass alle Columns betroffen sind.

static int DELETE
Wird für das Argument type verwendet, und gibt an, dass Rows gelöscht wurden.

static int HEADER_ROW
Gibt an, dass die Titelleiste von irgendwelchen Veränderungen betroffen ist.

static int INSERT
Wird für das Argument type verwendet, und gibt an, dass Rows eingefügt wurden.

static int UPDATE
Wird für das Argument type verwendet, und gibt an, dass sich der Inhalt der Rows verändert hat.

Info - Aufruf von getValueAt
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).

Die Tabelle
Java:
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

public class JTableDemo{
	public static void main( String[] args ){
		// Unser TableModel (siehe unten)
		final Model model = new Model(50, 60);
		
		// Das JTable initialisieren
		JTable table = new JTable( model );
		
		JFrame frame = new JFrame( "Demo" );
		frame.getContentPane().add( new JScrollPane( table ) );
		
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.pack();
		frame.setVisible( true );
	}
}

Ein TableModel das Integer ausgiebt, und mitzählt, wieoft "getValueAt" aufgerufen wurde (für jede Zelle einzeln)
Java:
class Model implements TableModel{
	private int width, height;
	
	int[][] calls;
	
	public Model( int width, int height ){
		this.width = width;
		this.height = height;
		calls = new int[ width ][ height ];
	}
	
	// Die Anzahl Columns
	public int getColumnCount() {
		return width;
	}
	
	// Die Anzahl Vehikel
	public int getRowCount() {
		return height;
	}
	
	// Die Titel der einzelnen Columns
	public String getColumnName(int column) {
		return String.valueOf( column );
	}
	
	// Der Wert der Zelle (rowIndex, columnIndex)
	public Object getValueAt(int rowIndex, int columnIndex) {
		// bei jedem Aufruf wird dieser Wert um 1 erhöht
		return new Integer( calls[ columnIndex ][ rowIndex ]++ );
	}

	// Eine Angabe, welchen Typ von Objekten in den Columns angezeigt werden soll
	public Class getColumnClass(int columnIndex) {
		return Integer.class;
	}
	
	public void addTableModelListener(TableModelListener l) {}
	public void removeTableModelListener(TableModelListener l) {}
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return false;
	}
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {}
}

beni-albums-jtable-picture58-table-06.png


Dieses TableModel zählt für jede Zelle, wie oft sie aufgerufen wurde.

Ausblick - Eingeben von Daten
Es wäre doch schön, wenn der Benutzer auch Daten eingeben könnte.
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:

Das Vehicel benötigt noch neue Methoden:

Java:
class Vehicel{
	... // der ganze Rest

	// Diese 4 Methoden müssen dem Vehikel noch hinzugefügt werden:
	public void setName( String name ){ this.name = name; }
	public void setPlaces( int places ){ this.places = places; }
	public void setWheels( int wheels ){ this.wheels = wheels; }
	public void setHasMotor( boolean motor ){ this.motor = motor; }
}

Die letzen beiden Methoden von "Model" müssen angepasst werden, so dass auch Daten gesetzt werden können
Java:
class Model implements TableModel{

	... // der ganze Rest

	// Die beiden letzten Methoden (siehe 4.) müssen noch verändert werden.

	// Gibt nun an, dass jede Zelle editierbar ist.
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return true;
	}

	// Wird von der JTable aufgerufen, falls in eine Zelle ein neuer Wert gesetzt werden soll
	// Praktischerweise ist "aValue" ein Objekt desselben Types, welchen wir bei
	// "public Class getColumnClass(int columnIndex)" zurückgegeben haben (Also String, Integer oder Boolean)
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		Vehicel vehicel = (Vehicel)vehicels.get( rowIndex );
		
		switch( columnIndex ){
			case 0: 
				vehicel.setName( (String)aValue );
				break;
			case 1: 
				vehicel.setPlaces( ((Integer)aValue).intValue() );
				break;
			case 2: 
				vehicel.setWheels( ((Integer)aValue).intValue() );
				break;
			case 3: 
				vehicel.setHasMotor( ((Boolean)aValue).booleanValue() );
				break;
		}
	}
}

beni-albums-jtable-picture57-table-05.png


(Anmerkung: falls das Editieren abgeschaltet werden will, muss #isCellEditable den Rückgabewert false haben)


© August 2004
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.
 
Status
Nicht offen für weitere Antworten.

Oben