JTable Sortierung.

Status
Nicht offen für weitere Antworten.

GilbertGrape

Bekanntes Mitglied
Hallo,

so jetzt das richtige Problem, nachdem ich das Beispiel endlich hingekriegt habe.
Also, ich habe eine JTable mit einem TableSorter als Model. Dieser wiederrum bekommt mein eigenes Model.
Nun hab ich folgendes Problem:

Wenn ich jetzt über getSelectedRow den ausgewählten Datensatz haben will, liefert er mir das falsche, wenn neu sortiert wurde.
Ich weiß, dass das ein bekanntes Problem ist und auch dass es convertRowToModel gibt, aber nicht unter java 1.5. Gibt es da auch eine Alternative, wie ich das möglichst einfach lösen kann?

falls es was hilft, hier das Beispiel:
Code:
public class GuiTests extends JFrame {

	JTable textTable;
	JPanel mainPanel;
	JTextPane textPane;
	JScrollPane scrollPane;
	Model myModel;
	
	public GuiTests(){
		mainPanel = new JPanel();
		mainPanel.setLayout(new BorderLayout(20,20));
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);		
				
		myModel = new Model();
		TableSorter sorter = new TableSorter(myModel);
		textTable = new JTable(sorter);
		

		textTable.setRowSelectionAllowed(true);
		JTableHeader header = textTable.getTableHeader();
		sorter.setTableHeader(header);
		scrollPane = new JScrollPane(textTable);
		
		UnmodifiedText test1 = new UnmodifiedText(Long.valueOf(1), "test1");
		UnmodifiedText test2 = new UnmodifiedText(Long.valueOf(2), "test2");
		
		myModel.addText(test1);
		myModel.addText(test2);
		
		textTable.addMouseListener(new MouseAdapter() {
			public void mouseClicked(final MouseEvent e) {
				if (e.getClickCount() == 2) {
					UnmodifiedText text = myModel.getRow(textTable
							.getSelectedRow());	
					System.out.println(textTable.getSelectedRow()+" "+ text.getText());
				}
			}
		});
		
		mainPanel.add(scrollPane,BorderLayout.CENTER);
		this.add(mainPanel);
	}
	
	public static void main(String[]args){
		GuiTests testFrame = new GuiTests();
		testFrame.pack();		
		testFrame.setVisible(true);
		
	}
}

und das Model:



Code:
class Model implements TableModel{
	   private Vector texts = new Vector();
	   private Vector listeners = new Vector();
	   
	   public void addText( UnmodifiedText text ){
	      int index = texts.size();
	      texts.add( text );
	      
	      TableModelEvent e = new TableModelEvent( this, index, index,
	            TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT );
	      
	      for( int i = 0, n = listeners.size(); i<n; i++ ){
	         ((TableModelListener)listeners.get( i )).tableChanged( e );
	      }
	   }
	   public int getColumnCount() {
	      return 2;
	   }
	   
	   public int getRowCount() {
	      return texts.size();
	   }
	   
	   public String getColumnName(int column) {
	      switch( column ){
	         case 0: return "Id";
	         case 1: return "Text";
	         default: return null;
	      }
	   }
	 
	   public Object getValueAt(int rowIndex, int columnIndex) {
	      UnmodifiedText text = (UnmodifiedText)texts.get( rowIndex );
	      
	      switch( columnIndex ){
	         case 0: return text.getId();
	         case 1: return text.getText();
	         default: return null;
	      }
	   }	   
	   public UnmodifiedText getRow(int rowIndex){
		   UnmodifiedText text = (UnmodifiedText)texts.get( rowIndex );
		   return text;
	   }

	   public Class getColumnClass(int columnIndex) {
	      switch( columnIndex ){
	         case 0: return Long.class;
	         case 1: return String.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
	   }
	}
 
Wie sieht die Klasse TableSorter aus? Du hast ein TableModel gegeben, welches die eigentlichen Daten liefert. Aus diesem TableModel generierst du deinen TableSorter, der offenbar auch ein TableModel ist aber eben die Daten in einer anderen Reihenfolge liefern kann...

Aus diesen TableSorter benutzt du, um damit die JTable zu erstellen... das heisst das Model der JTable ist die TableSorter-Instanz und nicht die Model-Instanz!

Wenn du also deine JTable fragst, welche Zeile markiert ist, musst du als nächstes die TableSorter Instanz fragen, welche Daten sich wohl in dieser Zeile befinden. Stattdessen hast du die Model Instanz gefragt, welche natürlich eine andere Reihenfolge der Daten wiedergibt, als der TableSorter:

Code:
UnmodifiedText text = myModel.getRow(textTable
                     .getSelectedRow());

Du musst also sorter.getRow anstelle von myModel.getRow benutzen.
 
die TableSorter ist nicht von mir, sondern diese hier: TableSorter.java
Das ist ja eine allgemeine Klasse, die mein Model (das nur weiß wie meine Daten aussehen) benutzt. Die ist nur zum Sortieren da.

Ich denke, das Problem ist, dass der Sorter nur die Datensätze in der JTable umsortiert, aber nicht im zugrundeliegenden TableModel. Ich weiß nur nicht, was ich da machen soll...
 
Eigentlich sollte das Modell auch nicht umsortiert werden. Und wenn doch, müßte man da speziell was bauen. Aber mit der Methode public int modelIndex(int viewIndex) { aus der verlinkten klasse sollte man sich alle nötigen Infos holen können...
 
Vielen Dank Marco!
Das hab ich auch gerade gefunden. Also das sieht jetzt so aus:

UnmodifiedText text = myModel.getRow(sorter.modelIndex(textTable.getSelectedRow()));
 
schreib dir einen eigenen Comparable

lass dir dein Model zurück geben

und wenn du sortieren willst
Collections.sort(model);
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben