# Jtable + TableRowSorter



## RalphW (2. Feb 2009)

Hi * 

ich habe ein kleines Problem: 

ich habe eine eigene Klasse die erbt von Jtable

```
class MyTable extends JTable

....
TableRowSorter<TableModel> sorter;
      sorter = new TableRowSorter<TableModel> (pDataModel);
      this.setRowSorter (sorter);


....
  this.convertRowIndexToModel(idx)
```

dort setzte ich den TableRowSorter und benutze die Konvertierung RowToModel. 

Beim Sortieren und anschliessender Selektion der Zeile hab ich auch immer die richtige Selektion. 

Beim Diplay wird die erste Row in der Tabelle blau eingefärbt.Wenn ich jetzt das erste mal Sortiere (klicken im Header) springt die Zeile (blau eingefärbt) an Ende der Tabelle. (So soll es sein) 
Klicke ich erneut aufs Sortieren springt die eingefärbte Zeile wieder an den Tabellenanfang.   
Spätestens nach dem 3 mal sortieren aber springt die eingefärbte Zeile aber nicht mehr an den Anfang oder Ende der Tabelle sondern irgendwo mitten drin. Sortiert ist die Tabelle immer noch auf- oder absteigend aber die eingefärbte Zeile ist eine andere. 

Any ideas ?? 


greets 
Ralph 


[/code]


----------



## André Uhres (2. Feb 2009)

1234567890


----------



## RalphW (2. Feb 2009)

André Uhres hat gesagt.:
			
		

> Bitte mach ein kurzes, selbständiges und kompilierbares Beispiel.




der Fehler liegt in der Methode getSelectedRows() . Wenn diese Methode nur den super.  returned tut es mit der Anzeige. 
Weiss allerdings gerade noch nicht warum. 
Nur mal hier ein Beispiel zum Auspropieren

```
package de.bwl.uis.module.vaws.test;
/*
 * TableSortDemo.java requires no other files.
 */

import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

public class TableSortDemo extends JPanel 
{
    public TableSortDemo() 
    {
        super(new GridLayout(1,0));
        ExtJTable table = new ExtJTable();
        table.setModel(new MyTableModel());
        table.setPreferredScrollableViewportSize(new Dimension(500, 100));
        table.setFillsViewportHeight(true);
        table.setSortierung(true);
        table.setHeaderLabels(new MyTableModel().columnNames);
        table.setContents( new MyTableModel().data ); 
        table.setRowSelectionInterval(0,0);
        //Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.getViewport().add(table, null);
        //Add the scroll pane to this panel.
        add(scrollPane);
    }

    class MyTableModel extends AbstractTableModel 
    {
        public String[] columnNames = {"First Name",
                                        "Last Name",
                                        "Sport",
                                        "# of Years",
                                        "Vegetarian"};
        public Object[][] data = {
            {"Mary", "Campione",
             "Snowboarding", new Integer(5), new Boolean(false)},
            {"Alison", "Huml",
             "Rowing", new Integer(3), new Boolean(true)},
            {"Kathy", "Walrath",
             "Knitting", new Integer(2), new Boolean(false)},
            {"Sharon", "Zakhour",
             "Speed reading", new Integer(20), new Boolean(true)},
            {"Philip", "Milne",
             "Pool", new Integer(10), new Boolean(false)},
        };

        public int getColumnCount() {
            return columnNames.length;
        }

        public int getRowCount() {
            return data.length;
        }

        public String getColumnName(int col) {
            return columnNames[col];
        }

        public Object getValueAt(int row, int col) {
            return data[row][col];
        }

        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }

        public boolean isCellEditable(int row, int col) {
            //Note that the data/cell address is constant,
            //no matter where the cell appears onscreen.
            if (col < 2) {
                return false;
            } else {
                return true;
            }
        }

        public void setValueAt(Object value, int row, int col) 
        {
             data[row][col] = value;
        }

    }
  
    public class ExtJTable extends JTable 
    {
      private String[] headerLabels;
      private boolean sortierung = false;
      public ExtJTable()
      {
        this.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
        this.getTableHeader().setReorderingAllowed(false);
      }

      public void setHeaderLabels(String[] pHeaderLabels) 
      {
        headerLabels = pHeaderLabels;
      }
  
      public void setContents(final Object[][] pContents) 
      {
        TableModel dataModel = new AbstractTableModel() 
        {
          public int getColumnCount() { return headerLabels.length; }
          public int getRowCount() { return pContents.length;}
          public Object getValueAt(int row, int col) {return pContents[row][col];}
          public String getColumnName(int column) {return headerLabels[column];}
          public Class getColumnClass(int c)
          {
            Object o = this.getValueAt(0, c);
            if (o != null)
            {
              return o.getClass();
            }
            else
            {
              return Object.class;
            }
          }

          public boolean isCellEditable(int row, int col)
          {
            return false;
          }

          public void setValueAt(Object aValue, int row, int column)
          {
            pContents[row][column] = aValue;
          }
        };

        this.setModel(dataModel);
      }

      /**
       * Bei Sortierung muss der RowIndex in den passenden Index im Model 
       * konvertiert werden 
       */
      public int getSelectedRow() 
      {
        int selectedRowIndex = super.getSelectedRow();
        if (sortierung) 
        {
          if (selectedRowIndex < 0) 
          {
            return selectedRowIndex;
          }
         
          selectedRowIndex = this.convertRowIndexToModel(selectedRowIndex);
        }
        
        return selectedRowIndex;
      }

      
      public int[] getSelectedRows() 
      {
        int[] tJetztIndexe = super.getSelectedRows();
        if (sortierung) 
        { // analog getSelectedRow()
          int[] tReturn = new int[tJetztIndexe.length];
          for (int i = 0; i < tJetztIndexe.length; i++) 
          {
            int tJetztIndex = tJetztIndexe[i];
            //tReturn[i] = sorter.getRealIndex(tJetztIndex);
            tReturn[i] = this.convertRowIndexToModel(tJetztIndex);
          }
          return tReturn;
        }
        return tJetztIndexe;
      }

      public void setSortierung(boolean pSortierung) 
      {
        sortierung = pSortierung;
        this.setAutoCreateRowSorter(sortierung);
      }

      
    }
    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("TableSortDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        TableSortDemo newContentPane = new TableSortDemo();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
```


----------



## André Uhres (3. Feb 2009)

1234567890


----------



## RalphW (3. Feb 2009)

André Uhres hat gesagt.:
			
		

> Warum überschreibst du getSelectedRow und getSelectedRows? Ohne die Überschreibungen funktioniert es doch super.



rein optisch funzt es ja. 
Wenn du aber attribute der selektierten Zeile auslesen würdest passt es nicht mehr (Synchronisation VIEW->Model).

Genau dafür gibt es ja die Methode convertRowIndexToModel. 
Nur wenn der Methodenaufruf in den getSelectedRows drin ist kommt es zum Problem. Aber auch dort wird die Synchronisation View->Model gebraucht.   


greets 
Ralph


----------



## André Uhres (3. Feb 2009)

1234567890


----------



## RalphW (3. Feb 2009)

André Uhres hat gesagt.:
			
		

> RalphW hat gesagt.:
> 
> 
> 
> ...





Hi André,

versteht ich jetzt nicht ganz.  Wo willst du View->Model synchronisieren , wenn nciht beim auslesen /selektieren der Row ?


----------



## André Uhres (3. Feb 2009)

1234567890


----------



## RalphW (23. Apr 2010)

Hi * 

hab mich nochmals nach längerer Zeit meinem Problem angenommen. 

in getSelectedRows benutze ich die methode convertRowIndexToModel. 

Diese ist auch nötig um nach dem Sortieren bei einer Row-Selektion den richtigen Index zu bekommen.

Ich vermute jetzt das in der View  der Index nicht zum model passt. Folglich wird bei der Forground/Backgroud Color nicht die ursprüngliche anselektierte Row markiert. 

Hat da irgend jemand ne Idee. 

Thanx Ralph


----------



## RalphW (23. Apr 2010)

Hi * 

habe gerade festgestellt das ich im Code Beispiel 

ListSelectionModel.SINGLE_SELECTION 
angegeben habe. 

Damit funzt alles so wie es soll.  

Stelle ich auf 
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION um hab ich das GUI-Display problem 


Greets 
Ralph


----------

