JTable DateRenderer / TimeRenderer

Moltar

Mitglied
Hallo,

ich habe (immernoch :) ) eine JTable. Diese bekommt aus einer Datenbank verschiedenste Arten von Daten. Um auch Datums- und Zeitangaben nach meinen Vorstellungen anzeigen zu lassen, habe ich mir 4 Klasse gebaut: je einen Renderer und einen Editor für Datum bzw. Zeit.
Das Datum soll im Format: dd.MM.yyyy dargestellt werden und die Uhrzeit in HH:mm.

Als Beispiel hier die Klassen für Time (Datum habe ich analog realisiert, nur dass das DateFormat angepasst ist).
Der Renderer:
Code:
public class TimeRenderer extends DefaultTableCellRenderer {
	private static final long serialVersionUID = 1L;
	private JLabel component;
	private boolean editable = true;
	DateFormat dateFormat = new SimpleDateFormat("HH:mm");
	
	public TimeRenderer(boolean canBeEdited) {
		editable = canBeEdited;
		
	}
	
	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
		component.setOpaque(true);
		component = new JLabel();
		if(!editable) {
			JTableHeader header = table.getTableHeader();
			component.setBackground(header.getBackground());
			component.setForeground(header.getForeground());
		}
		if(col > 1) {
			component.setHorizontalAlignment(JLabel.CENTER);
		}
		if(value != null) {
			component.setText(dateFormat.format((Time)value));
		}
		return component;
	}
}

Der Editor:
Code:
public class TimeEditor extends AbstractCellEditor implements TableCellEditor {
	private static final long serialVersionUID = 1L;
	private JTextField component;
	DateFormat dateFormat = new SimpleDateFormat("HH:mm");
	
	public Component getTableCellEditorComponent(JTable tab, Object value, boolean isSelected, int row, int col) {
		component = new JTextField();
		if(value != null) {
			component.setText(dateFormat.format(value));
		}
		if(col > 1) {
			component.setHorizontalAlignment(JTextField.CENTER);
		}
		
		return component;
	}
	
	public Object getCellEditorValue() {
		return Boolean.valueOf(component.getText());
	}
}

Die Darstellung der Daten funktioniert wie gewünscht. Wenn ich allerdings Daten eingebe und das Feld bestätige, erhalte ich eine "IllegalArgumentException" mit der Begründung, aus "value" könne kein Datum erzeugt werden. (Sorry, hab das Programm leider auf einem anderen PC, sonst würde ich die vollständige Exception posten.)
Der Debugger zeigt an, dass die Daten beim Laden aus der Datenbank als java.sql.Date bzw java.sql.Time vorliegen (das halte ich für sinnvoll, da sie auch genau mit den Typen wieder in die Datenbank rein sollen).

Weiß jemand, wie ich den Code anpassen müsste, damit auch das Eingeben neuer Werte funktioniert?

Danke schonmal
Moltar
 
Mich verwirrt gerade folgende Anweisung

Code:
public Object getCellEditorValue() {
        return Boolean.valueOf(component.getText());
}

Wenn ich deine Beschreibung richtig gelesen habe, liegt hier ein Datum oder eine Zeit. Weshalb dann Boolen.valueOff(...)
 
Oh, da ist mir wohl ein Fehler unterlaufen. Ich hatte den Editor von meinem CheckBoxEditor kopiert.

Das war aber leider nur ein Teil des Fehlers. Mittlerweile habe ich eine Lösung gefunden:

Code:
public class TimeRenderer extends DefaultTableCellRenderer {
	private static final long serialVersionUID = 1L;
	private JLabel component;
	private boolean editable = true;
	DateFormat dateFormat = new SimpleDateFormat("HH:mm");
	
	public TimeRenderer(boolean canBeEdited) {
		editable = canBeEdited;
		
	}
	
	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
		component = new JLabel();
		component.setOpaque(true);
		if(!editable) {
			JTableHeader header = table.getTableHeader();
			component.setBackground(header.getBackground());
			component.setForeground(header.getForeground());
		}
		if(col > 1) {
			component.setHorizontalAlignment(JLabel.CENTER);
		}
		if(value != null) {
			try {
				Date date = dateFormat.parse(value.toString());
				component.setText(dateFormat.format(date));
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return component;
	}

und

Code:
public class TimeEditor extends AbstractCellEditor implements TableCellEditor {
	private static final long serialVersionUID = 1L;
	private JTextField component;
	DateFormat dateFormat = new SimpleDateFormat("HH:mm");
	
	public Component getTableCellEditorComponent(JTable tab, Object value, boolean isSelected, int row, int col) {
		component = new JTextField();
		if(value != null) {
			try {
				Date date = dateFormat.parse(value.toString());
				component.setText(dateFormat.format(date));
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(col > 1) {
			component.setHorizontalAlignment(JTextField.CENTER);
		}
		
		return component;
	}
	
	public Object getCellEditorValue() {
		return component.getText();
	}
}

Das Problem war, dass "value" in Objekt vom Typ String war. dateFormat.format() erwartet aber ein Date-Objekt. Das habe ich jetzt durch parsen gelöst. So wie der Code oben steht, funktioniert er bei mir.
Eine entsprechende Anpassung war natürlich auch für den Code in der DateRenderer und DateEditor-Klasse nötig.

Grüße
Moltar
 
Zurück