ComboBox sowie String in einer JTable Spalte

Fr33z3m4n

Mitglied
Guten Tag,

ich weiß nicht ob das jetzt der richtige Bereich für mein Thema ist, nur konnte ich mMn. kein geeignetes dafür finden. Wenn dennoch falsch, bitte verschieben, thx.

So: Mein Problem ist es, in einer JTable eine Spalte mit 2 unterschiedlichen Objekten zu versehen.
Zu der einen Seite, möchte ich in einer Zeile (in der Spalte) nur einen String anzeigen lassen, den man bearbeiten kann, und auf der anderen Seite, sollte da ggf. eine ComboBox auftauchen.
Es geht hierbei um Werte aus der SQL.
Wenn es sich um ein Boolean handelt, soll eine ComboBox angezeigt werden, und wenn es sich um einen String handelt, soll keine comboBox angezeigt werden, sondern die normale Zelle als String editierbar.

Ich versuche mich nun schon seit einigen Tagen daran, und bin nur noch am verzweifeln, weil es einfach nicht laufen will.

Ich poste mal ein wenig code, damit Ihr euch vlt. einen kleinen Überblick verschaffen könnt.

Erstmal die Tabelle:
Java:
.....
tblBerechtigung = new JTable();
tblBerechtigung.setRowSelectionAllowed(false);
panel.add(tblBerechtigung, new CellConstraints("2, 4, 4, 1, fill, fill"));
.....

Das erstellen des Models
Java:
Object[][] xBenutzer = new Object[5][5];
int[][] xBenutzerID = new int[5][1];
for (int i = 0; i < 5; i++) {
	xBenutzer[i][0] = new String("Benutzer " + i);
	xBenutzer[i][1] = new String("Mandant " + i);
	xBenutzer[i][2] = new String("Vorname " + i);
	xBenutzer[i][3] = new String("Nachname " + i);
	if (i == 0) {
		xBenutzer[i][4] = new String("String");
	} else {
		xBenutzer[i][4] = new Boolean(true);
	}
	xBenutzerID[i][0] = i;
}
String[] Header = new String[] { "Benutzer", "Mandant", "Vorname", "Nachname", "Boolean" };
MyDefaultTableModel tblModel = new MyDefaultTableModel(Header, xBenutzer, xBenutzerID, 0);
tblBerechtigung.setModel(tblModel);
Java:
MyDefaultTableModelextends DefaultTableModel
Nun wird die ComboBox erstellt
Java:
// ComboBox
Object[] values = new Object[] { new String("Ja"), new String("Nein") };
JComboBox comboBox = new JComboBox(values);
TableColumn column = tblBerechtigung.getColumnModel().getColumn(4);
comboBox.setEditable(true);
column.setCellEditor(new MyDefaultCellEditor(comboBox));
column.setCellRenderer(new MyJComboBoxRenderer(values));
DefaultCellEditor
Java:
public class MyDefaultCellEditor extends DefaultCellEditor {

	private static final long serialVersionUID = 4849412983002818694L;
	
	public MyDefaultCellEditor(JComboBox comboBox) {
		super(comboBox);
	}
}
ComboBoxRenderer
Java:
public class MyJComboBoxRenderer extends JComboBox implements TableCellRenderer {

	private static final long serialVersionUID = -8520403329366110894L;
	protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();

	public MyJComboBoxRenderer (Object[] items) {
		super(items);
	}

	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
			int row, int column) {

		// if (isSelected) {
		// setForeground(table.getSelectionForeground());
		// super.setBackground(table.getSelectionBackground());
		// } else {
		// setForeground(table.getForeground());
		// setBackground(table.getBackground());
		// }
		// Select the current value
		if(value instanceof Boolean) {
			this.setEditable(true);
		}
		else {
			this.setEditable(false);
		}
		setSelectedItem(value);
		return this;
	}
}
Das ist jetzt der letzte Stand, nach diversen Rumspielen/Testen usw. ;(
Hoffe mir kann da jemand helfen, wenn das überhaupt möglich ist, weil ich bislang noch nichts in dieser Richtung gefunden habe, dass man pro Zeile/Spalte den Typen ändern könnte.
 
In dem Fall würde ich nicht den DefaultCellEditor verwenden:
Java:
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.AbstractCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;

public class TableComboEditorDemo extends JFrame {
	
	public TableComboEditorDemo() {
		JTable table = new JTable(new DefaultTableModel(new Object[][] {
				{ "String", "Test" },
				{ Boolean.FALSE, "Test" } ,
				{ Boolean.TRUE, "Test" },
				{ "String", "Test" },
				{ Boolean.FALSE, "Test" }},
				new String[] {"Spalte A", "Spalte B" }));
		TableColumn column = table.getColumnModel().getColumn(0); 
		column.setCellEditor(new CustomEditor());
		table.setRowHeight(30);
		this.getContentPane().add(new JScrollPane(table));
	}
	
	class CustomEditor extends AbstractCellEditor implements TableCellEditor {
		private JComboBox box;
		private JTextField field;
		private Component currentRenderer;
		
		public CustomEditor() {
			box = new JComboBox(new String[] {"Ja", "Nein"});
			field = new JTextField();
			//optional um den Editor unmittelbar nach der Selektion zu beenden
			box.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					CustomEditor.this.stopCellEditing();
				}
			});
		}

		public Object getCellEditorValue() {
			if (currentRenderer.equals(box))
				return (box.getSelectedIndex()==0);
			return field.getText();
		}

		public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
			if (value instanceof Boolean) {
				boolean b = (Boolean) value;
				if (b)
					box.setSelectedIndex(0);
				else
					box.setSelectedIndex(1);
				currentRenderer = box;
			}
			else {
				if (value!=null)
					field.setText(value.toString());
				else
					field.setText("");
				currentRenderer = field;
			}
			return currentRenderer;
		}
	}
	
	public static void main(String[] args) {
		JFrame frame = new TableComboEditorDemo();
		frame.setBounds(0, 0, 500, 300);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
Für den Renderer muss dann ebenfalls die Unterscheidung gemacht werden.
 
Da sag ich doch mal vielen lieben Dank 🙂

Renderer hab ich auch angepasst, vielen Dank.
Und dafür hab ich vergeblich einige Tage für gebraucht, tsts ^^
 

Zurück
Oben