Object mit JTable verknüpfen

d3rbastl3r

Bekanntes Mitglied
Hallo,
hat einer eine idee wie ich ein Objekt an eine Reihe in der JTable binden kann?

Ich zeige in der tabelle mein ModelTree an, hierbei habe ich in meiner model eine methode die mir aus jedem Element einen vector erzeugt so dass ich diesen dann in die Tabelle laden kann.

Nun möchte ich dass bei einem Klick auf eine Reihe der verweis zu dem eigentlichem Objekt zurückgegeben wird damit ich mit den Daten weiterarbeiten kann.

Momentan habe ich das so gelöst (habe irgendwo hier gefunden) dass ich einer Zelle das Objekt übergebe und die MaxWidth der Spalte auf 0 setze. So kriege ich natürlich das Objekt wenn ich den inhalt der Zelle abfrage, jedoch ist die spalte trot width(0) sichtbar.

Gibt es da eine Andere möglichkeit dass eine Reihe auf ein bestimmtes Objekt verweist?
 
Ich weiss zwar nicht ob das in Deinem Fall die ideale bzw. sauberste Lösung ist
und hab es selbst jetzt auch nicht ausprobiert.

Aber theoretisch könnte man das Objekt in der letzten Spalte
des TableModel speichern und in getColumnCount() die Anzahl Spalten -1 zurück liefern.

Java:
public int getColumnCount() { return columnNames.length - 1; }

Dann müsstest Du das TabelModel noch um eine Funktion erweitern, mit der Du auf das Objekt zugreifen kannst.
 
Wie schaut den so ein Element aus?
Du könntest anstelle die Bestandteile der Elemente in einem Vector abzuspeichern, einfach eine Liste (z.B ArrayList) mit den relevanten Elementen im TableModel vorhalten. Methoden wie getRowCount, getColumnCount, get/setValueAt entsprechend überschreiben. Zusätzlich noch eine Methode ala public Element getElementAt(int row) bereitstellen, welche Dir über die Liste immer das passende Element zur Zeile liefert.
 
Ich habe es damals so gemacht: (gibt aber sicherlich ne elegantere lösung...)

Java:
        ruleTableModel = new javax.swing.table.DefaultTableModel(data,header) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.Boolean.class, Rule.class // in der 3. Spalte befindet sich das RuleObjekt
            };

            boolean[] canEdit = new boolean [] {
                false, true, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        };

Die Spalte ausgeblendet habe ich dann so:

Java:
        ruleTable.getColumnModel().getColumn(2).setMinWidth(0); // Spalte ausblenden
        ruleTable.getColumnModel().getColumn(2).setMaxWidth(0);

Mich würde aber auch interessieren ob es dafür eine schönere Lösung gibt.
 
Danke erstmal für die antworten 🙂

Ich weiss zwar nicht ob das in Deinem Fall die ideale bzw. sauberste Lösung ist
und hab es selbst jetzt auch nicht ausprobiert.

Aber theoretisch könnte man das Objekt in der letzten Spalte
des TableModel speichern und in getColumnCount() die Anzahl Spalten -1 zurück liefern.

Java:
public int getColumnCount() { return columnNames.length - 1; }

Dann müsstest Du das TabelModel noch um eine Funktion erweitern, mit der Du auf das Objekt zugreifen kannst.

So geht es leider nicht, versuche ich hier dann auf eine zelle der spalte "columnNames.length" zuzugreifen, existiert diese nicht, die aber quasi mein objekt darstellen müsste.

@ EikeB, so habe ich das momentan auch gelöst, ist zwar unschön, aber die einzige lösung die ich gefunden habe.

@ Michael, ich weis nicht genau was du meinst. Also meine Datenstruktur ist etwas komplexer aufgebaut, und das ganze auch noch in einen BinärenBaum verpackt. Mit der Methode getDataVector kann ich dann quasi genau festlegen was in der tabelle angezeigt werden soll.
 
So wie ich das verstanden habe "entspricht" eine Zeile einem bestimmten Objekt und in den Zellen der Zeile werden diverse Attribute dieses Objekts dargestellt.
Dann könnte man das so (Klasse ObjectModel) umsetzen:
Java:
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

public class ObjectModelDemo extends JFrame {
	private JTable table;
	private ObjectModel model;
	private JLabel label;
	
	public ObjectModelDemo() {
		List<MyElement> list = new ArrayList<MyElement>();
		String[] name = {"Heinz", "Otto", "Rosi", "Susi"};
		String[] value = {"Nord", "Süd", "West", "Ost"};
		for (int i=0; i<name.length; i++)
			list.add(new MyElement(name[i], value[i], null));
		model = new ObjectModel(list);
		table = new JTable(model);
		this.getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
		this.getContentPane().add(label = new JLabel("Select a row"), BorderLayout.SOUTH);
		
		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				if(!e.getValueIsAdjusting()) {
					int row = table.getSelectedRow();
					if (row >= 0)
						label.setText(model.getElementAt(row).toString());
					else
						label.setText("");
				}
			}
		});
	}
	
	class ObjectModel extends DefaultTableModel {
		private List<MyElement> objList;
		private String[] colNames = {"Name", "Wert1", "Wert2"};
		
		public ObjectModel(List<MyElement> list) {
			objList = list;
		}
		
		public int getRowCount() {
			if (objList==null)
				return 0;
			return objList.size();
		}
		
		public int getColumnCount() {
			return 3;
		}
		
		public String getColumnName(int column) {
			if (column>=colNames.length || column<0)
				return null;
			return colNames[column];
		}
		
		public MyElement getElementAt(int row) {
			return objList.get(row);
		}
		
		public Object getValueAt(int row, int column) {
			MyElement elem = objList.get(row);
			switch(column) {
			case 0:return elem.getName();
			case 1:return elem.getValue1();
			case 2:return elem.getValue2();
			}
			return null;
		}
		
		public void setValueAt(Object o, int row, int column) {
			MyElement elem = objList.get(row);
			switch(column) {
			case 0: elem.setName(String.valueOf(o));break;
			case 1: elem.setValue1(String.valueOf(o));break;
			case 2: elem.setValue2(String.valueOf(o));break;
			}
		}
	}
	
	class MyElement {
		private String name, value1, value2;
		
		public MyElement(String name, String value1, String value2) {
			this.name = name;
			this.value1 = value1;
			this.value2 = value2;
		}
		
		public void setName(String name) {
			this.name = name;
		}
		
		public void setValue1(String value) {
			this.value1 = value;
		}
		
		public void setValue2(String value) {
			this.value2 = value;
		}
		
		public String getName() {return name;}
		
		public String getValue1() {return value1;}
		
		public String getValue2() {return value2;}
		
		public String toString() {
			return getClass().getSimpleName() + "@" + hashCode() + " [" + getName() + ", " + getValue1() + ", " + getValue2() + "]"; 
		}
	}
	
	public static void main(String[] args) {
		JFrame frame = new ObjectModelDemo();
		frame.setBounds(0, 0, 500, 300);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
 
d3rbastl3r hat gesagt.:
r.w. hat gesagt.:
Dann müsstest Du das TabelModel noch um eine Funktion erweitern, mit der Du auf das Objekt zugreifen kannst.
So geht es leider nicht, versuche ich hier dann auf eine zelle der spalte "columnNames.length" zuzugreifen, existiert diese nicht, die aber quasi mein objekt darstellen müsste.
Wie ich schon erwähnt hab, müsstest Du dann im TableModel eine eigene Funktion implementieren,
die dort intern auf die Spalte zugreift. Und zwar direkt und nicht über die Funktion ".getValueAt()".
Denn diese wird ja ".getColumnCount()" verwenden und somit die letzte Spalte nicht finden.

Ich hoffe, ich hab mich verständlich ausgedrückt. Bin grad etwas in Zeitnot. ;-)
 
Boahh, eigentlich gibt es einen gaaaanz einfachen weg der verknüpfung xD der mir jedoch irgendwie erst eingefallen ist als ich überlegt habe wie ich die objekte nun mit JComboBox verknüpfen soll.

Im grunde hat jede zeile eine ID
Ich würde jetzt einfach in der ViewKlasse einen Vector mit referenzen auf die eigentliche Objekte anlegen.
Diese natürlich im Vector genau so anordnen wie in der Tabelle oder JComboBox.
Bei einem Event krigt man die nummer der Zeile raus und durch diesen index kann man dann auf die Referenz im Vector zugreifen.
 

Zurück
Oben