JTable - Teil 6 - JTableHeader,TableColumn,TableColumnModel

Status
Nicht offen für weitere Antworten.
R

Roar

Gast
JTable - Teil 6 - JTableHeader, TableColumn und das TableColumnModel

JTableHeader
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.

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:

Java:
import javax.swing.*;
import javax.swing.table.JTableHeader;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableColumn;



class TableHeaderTest {
	
	public static void main(String[] args) {
		// JTable initialisieren und mit Inhalt füllen; siehe dazu Teil 2
		JTable table = new JTable(new String[][]{{"1", "2", "3"},{"4", "5", "6"}}, new String[]{"A", "B", "C"});
		
		// JTableHeader holen
		JTableHeader header = table.getTableHeader();
		
		// ColumnModel holen:
		TableColumnModel columnModel = header.getColumnModel();
		
		// TableColumn erstellen
		TableColumn aColumn = new TableColumn();
		// setHeaderValue() setzt den Titel
		aColumn.setHeaderValue("D");
		// modelIndex zeigt an von welcher Spalte im DatenModel die neue Spalte ihre Werte holen soll
		aColumn.setModelIndex(1); // Index 1 im Model sind also "2" und "5"
		columnModel.addColumn(aColumn);
		
		// eine spalte verschieben
		columnModel.moveColumn(0, 2); // Spalte 0 (mit Titel "A") verschieben an Position 2 im Model
		
		// Spalten nicht resizable machen, nicht zulassen dass die Spaltenreihenfolge geändert werden kann
		header.setResizingAllowed(false);
		header.setReorderingAllowed(false);
		
		// JFrame konstruieren
		JFrame frame = new JFrame("JTableHeader test");
		// Table in JScrollPane einfügen und dem Frame hinzufügen
		frame.getContentPane().add(new JScrollPane(table));
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.pack();
		frame.setVisible(true);
	}
}

Ausgabe:

attachment.php


Erklärung:
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 ("A") 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.

Header selber zeichnen

Eine weitere Möglichkeit von JTableHeader und TableColumn ist, wie auch bei JTable möglich, den Renderer für die Spalte zu setzen.
Es wird das gleiche Renderer Interface benutzt wie bei der JTable: javax.swing.table.TableCellRenderer. Zugewiesen wird der Renderer mit setDefaultRenderer(TableCellRenderer defaultRenderer);

Beispiel:
Java:
import java.awt.Component;
import java.awt.Color;
import javax.swing.*;
import javax.swing.table.JTableHeader;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableCellRenderer;



class TableHeaderTest {
	
	public static void main(String[] args) {
		// JTable initialisieren und mit Inhalt füllen; siehe dazu Teil 2
		JTable table = new JTable(new String[][]{{"1", "2", "3"},{"4", "5", "6"}}, new String[]{"A", "B", "C"});
		
		// JTableHeader holen
		JTableHeader header = table.getTableHeader();
		
		// ColumnModel holen:
		TableColumnModel columnModel = header.getColumnModel();
		
		// TableColumn erstellen
		TableColumn aColumn = new TableColumn();
		// setHeaderValue() setzt den Titel
		aColumn.setHeaderValue("D");
		// modelIndex zeigt an von welcher Spalte im DatenModel die neue Spalte ihre Werte holen soll
		aColumn.setModelIndex(1); // Index 1 im Model sind also "2" und "5"
		columnModel.addColumn(aColumn);
		
		// eine spalte verschieben
		columnModel.moveColumn(0, 2); // spalte 0 (mit Tiel "A") verschieben an position 2 im model
		
		// spalten nicht resizable machen, nicht zulassen dass die spaltenreihenfolge geändert werden kann
		header.setResizingAllowed(false);
		header.setReorderingAllowed(false);
		
		// Renderer zuweisen
		header.setDefaultRenderer(new MyHeaderCellRenderer());
		
		// JFrame konstruieren
		JFrame frame = new JFrame("JTableHeader test");
		// Table in JScrollPane einfügen und dem Frame hinzufügen
		frame.getContentPane().add(new JScrollPane(table));
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.pack();
		frame.setVisible(true);
	}
}


// Eigener CellRenderer für die spaltenköpfe. Liefert immer ein 
// JLabel zurück, und implementiert TableCellRenderer
class MyHeaderCellRenderer extends JLabel implements TableCellRenderer {
	
	// einzig wichtige methode
	public Component getTableCellRendererComponent(JTable table, Object value, 
			boolean isSelected, boolean hasFocus, int row, int column) {
		// text
		setText(value.toString());
		// normale schriftart
		setFont(table.getFont());
		// der standard rahmen für spaltenköpfe
		setBorder(UIManager.getBorder("TableHeader.cellBorder"));
		// text zentiriert darstellen
		setHorizontalAlignment(SwingConstants.CENTER);
		// tooltip
		setToolTipText("Colum No. "+(column+1));
		// undurchsichtig damit man die hintergrundfarbe sieht.
		setOpaque(true);
		// je nach spalte die hintergrundfarbe setzen
		switch(column) {
			case 0:  setBackground(Color.GREEN); break;
			case 1:  setBackground(Color.BLUE); break;
			case 2:  setBackground(Color.YELLOW); break;
			case 3:  setBackground(Color.RED); break;
			default: setBackground(Color.LIGHT_GRAY);
		}
		return this;
	}
}

Ausgabe:

attachment.php


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:

Java:
class MyHeaderCellRenderer implements TableCellRenderer {
	
	// einzig wichtige methode
	public Component getTableCellRendererComponent(JTable table, Object value, 
			boolean isSelected, boolean hasFocus, int row, int column) {
		JComponent c = null;
		if(value instanceof String ) {
			c = new JLabel((String)value);
			((JLabel)c).setHorizontalAlignment(SwingConstants.CENTER);
		} else if(value instanceof JCheckBox) {
			c = (JCheckBox) value;
		} else if(value instanceof JComboBox) {
			c = (JComboBox) value;
		} else {
			c = new JLabel(value.toString());
			((JLabel)c).setHorizontalAlignment(SwingConstants.CENTER);
		}
		c.setEnabled(true);
		// normale schriftart
		c.setFont(table.getFont());
		// der standard rahmen für spaltenköpfe
		c.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
		// text zentiriert darstellen
		c.setToolTipText("Colum No. "+(column+1));
		// undurchsichtig damit man die hintergrundfarbe sieht.
		c.setOpaque(true);
		// je nach spalte die hintergrundfarbe setzen
		switch(column) {
			case 0:  c.setBackground(Color.GREEN); break;
			case 1:  c.setBackground(Color.BLUE); break;
			case 2:  c.setBackground(Color.YELLOW); break;
			case 3:  c.setBackground(Color.RED); break;
			default: c.setBackground(Color.LIGHT_GRAY);
		}
		return c;
	}

Jetzt gibt es aber das Problem dass man die Komponenten nicht ändern kann. Das ist auch etwas komplizierter, aber gute Tutorials,
die sich damit eingehender beschäftigen findet man z.B. hier:
New site launched | objects, hosting, tutoring | objects
Dort sind auch andere mehrere tiefergehende Beispiele zu JTableHeader und TableColumn.

© 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.
 

Anhänge

  • JTableHeaderTest.png
    JTableHeaderTest.png
    4,1 KB · Aufrufe: 326
  • JTableHeaderTest2.png
    JTableHeaderTest2.png
    4,1 KB · Aufrufe: 309
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben