# JTable / RowSorter macht große Probleme



## Thomas Lorenz (26. Dez 2009)

Servus Gemeinde, 
auf meinen letzten Eintrag hier erhielt ich keine Antwort. Seitdem hat sich ein wenig an meinem Problem geändert.
Nun habe ich eine Table die die Daten sehr gut verwaltet. 
Aber sobald ich den TableRowSorter mit hinein nehme läuft es nicht mehr. 


Ich hoffe, dass sich diesmal jemand findet um mir zu helfen.

Hier die Exception : 

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Invalid range
	at javax.swing.DefaultRowSorter.rowsDeleted(DefaultRowSorter.java:863)
	at javax.swing.JTable.notifySorter(JTable.java:4271)
	at javax.swing.JTable.sortedTableChanged(JTable.java:4115)
	at javax.swing.JTable.tableChanged(JTable.java:4392)
	at _Pol649.AdminReportModel.deleteData(AdminReportTable.java:1572)
	at _Pol649.AdminReportTable$6.actionPerformed(AdminReportTable.java:316)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
	at java.awt.Component.processMouseEvent(Component.java:6348)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3255)
	at java.awt.Component.processEvent(Component.java:6113)
	at java.awt.Container.processEvent(Container.java:2085)
	at java.awt.Component.dispatchEventImpl(Component.java:4714)
	at java.awt.Container.dispatchEventImpl(Container.java:2143)
	at java.awt.Component.dispatchEvent(Component.java:4544)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4618)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4282)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4212)
	at java.awt.Container.dispatchEventImpl(Container.java:2129)
	at java.awt.Window.dispatchEventImpl(Window.java:2475)
	at java.awt.Component.dispatchEvent(Component.java:4544)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:635)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

hier kommt auszugsweise die Klasse incl. TableModel : 


```
package _Pol649;

import java.awt.AWTException;
..
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

import sun.tools.jconsole.inspector.TableSorter;
 
public class AdminReportTable extends JFrame implements Comparable <AdminReportData>{
    
  
    private static ArrayList<String> employeeList = new ArrayList<String>();
    private String[] indexString = new String []{"", "Datum", "Streifenart", "Status"};
    private int selectedRow = 0;
    Message msg = new Message();
    private Timer 	messageTimer;
    private boolean 	timerFlag = true;
    //public static ArrayList<AdminReportData> reportList = new ArrayList<AdminReportData>();
    
    public static int searchStartTime = 0;
    public static int searchEndTime = 0;
    public static String actualEmployee = "";
    
    public static boolean searchOnlyInMain ;
    
    
    public static String[] reportStatus 	= {"übergeben", "korrigieren", "gespeichert"};
    //AdminReportLogData reportLog;
    SystemData _Sys;
    ErrorHelper _Error;
    PropertyData _Data;
    CheckFiles _Files;
    JFrame _Main;
    ReportData report;
    
    final JFrame frame 				= new JFrame ( "Übersicht der Mitarbeitervorgänge" );
    
         // Unser TableModel (siehe unten)
    final AdminReportModel model 		= new AdminReportModel();
 // Der TableRowSorter wird die Daten des Models sortieren
    final TableRowSorter<AdminReportModel> sorter = new TableRowSorter<AdminReportModel>(model);

    // Das JTable initialisieren
    public JTable table 			= new JTable( model );
    JScrollPane scr_table 			= new JScrollPane(table);
    
    ..    
    public AdminReportTable() {
	this._Sys = SystemData.getInstance();
	this._Error = ErrorHelper.getInstance();
	this._Data = PropertyData.getInstance();
	this._Files = CheckFiles.getInstance();
	table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
	
	.. 
   
    
    public Container addComponentsToPane(){
	    messageTimer = new Timer(_Sys.getTimerInfo(), new ActionListener() {
	            public void actionPerformed(final ActionEvent e) {
	        	clearInfoWindow();
	            }
	        });
	     messageTimer.setRepeats(false);
	Container pane = getContentPane();
	..
	bt_searchByDate.addActionListener(new ActionListener(){
	    @Override
	    public void actionPerformed(ActionEvent e) {
		// Wurden zwei Daten ausgewählt?
		if(!isDate()){return;}
		// Liegt das Enddatum vor dem Startdatum?
		checkDate(tf_searchDateFrom.getText(), tf_searchDateTo.getText());
		setSearchStartTime(Integer.parseInt((tf_searchDateFrom.getText().substring(6, 8))+
			(tf_searchDateFrom.getText().substring(3, 5))+(tf_searchDateFrom.getText().substring(0, 2))));
		setSearchEndTime(Integer.parseInt((tf_searchDateTo.getText().substring(6, 8))+
			(tf_searchDateTo.getText().substring(3, 5))+(tf_searchDateTo.getText().substring(0, 2))));
		// Den Array und das Model entleeren
		//clearReportAndArrayList();
		model.deleteData();
		// Main-Datei durchsuchen
		loadReportFromMainFile(model,_Files.getFileDataMain(), "searchByDate");

		// Wenn auch in den Mitarbeiter Dateien gesucht werden soll
		if(!getSearchOnlyInMain()){
		    for(int i = 0; i < employeeList.size(); i++){
			String userFile = _Sys.getUserIndex() + getEmployeeFromList(i)+"FileDataUser.txt";
			loadReportFromMainFile(model,userFile, "searchByDate");
		    }
		    
		}
		// Wenn kein Vorgang gefunden wurde, wird die Table entleert, eine Meldung wird angezeigt
		if(AdminReportData.getArraySize() == 0){
		   scr_table.repaint();
		   _Error.getErrorMessage(142, 
				new Exception().getStackTrace()[0].getClassName() + "/" + new Exception().getStackTrace()[0].getMethodName(),"");
			    setInfoText(_Error.getErrorClassification(), _Error.getErrorText1(), _Error.getErrorText2(), 
				    _Error.getErrorText3(), _Error.getErrorText4(), tf_searchDateFrom.getText() + " - " + tf_searchDateTo.getText());
			    setSearchByDateTextFieldsToNull(); // Textfelder leeren
			    return;
		}
		// Die Datumsfelder leeren
		
		setSearchByDateTextFieldsToNull();
		table.repaint();
		return;
	    }
	});
	tf_searchDateFrom.setEditable(false);
	tf_searchDateFrom.setHorizontalAlignment(JTextField.CENTER);
	pan_tabbed1.add(tf_searchDateFrom);
	tf_searchDateTo.setEditable(false);
	tf_searchDateTo.setHorizontalAlignment(JTextField.CENTER);
	pan_tabbed1.add(tf_searchDateTo);
	
	
	tp_main.add("Suche innerhalb Zeitraum", pan_tabbed1);
..
	bt_searchByEmployee.addActionListener(new ActionListener(){
	    @Override
	    public void actionPerformed(ActionEvent e) {
		// Es wurde kein Mitarbeiter ausgewählt
		if(cb_searchByEmployee.getSelectedIndex()<1){
		    _Error.getErrorMessage(143, 
				new Exception().getStackTrace()[0].getClassName() + "/" + new Exception().getStackTrace()[0].getMethodName(),"");
			    setInfoText(_Error.getErrorClassification(), _Error.getErrorText1(), _Error.getErrorText2(), 
				    _Error.getErrorText3(), _Error.getErrorText4(), _Error.getExtraText());
			    setSearchByDateTextFieldsToNull(); // Textfelder leeren
			    return;
		}
		setSearchOnlyInMain(true);
		// Den Array und das Model entleeren
		//clearReportAndArrayList();
		model.deleteData();
		
		
		//AdminReportData.clearArray();
		String userFile = _Sys.getUserIndex() + cb_searchByEmployee.getSelectedItem().toString().substring(2, 10) + "FileDataUser.txt";
		setActualEmployee(cb_searchByEmployee.getSelectedItem().toString().substring(2, 10));
		// Main-Datei durchsuchen
		loadReportFromMainFile(model,_Files.getFileDataMain(), "searchByEmployee");
		// Die Anwenderdatei durchsuchen
		
		loadReportFromMainFile(model,userFile, "searchByEmployee");
		// aktuellen Mitarbeiter wieder auf Null setzen
		
		cb_searchByEmployee.setSelectedIndex(0);
		setActualEmployee("");
		table.repaint();
	    }
	    
	});
	tp_main.add("Suche nach Mitarbeiter", pan_tabbed2);
	
	
	
..
	// Der Sorter muss dem JTable bekannt sein
	table.setRowSorter( sorter );
	        
	// ... und der Sorter muss wissen, welche Daten er sortieren muss
	sorter.setModel( model );
	        
	// hier kommt die Sortierung der Datumsspalte
	sorter.setComparator(5, new Comparator<String>(){
	@Override
	public int compare(String o1, String o2) {
	    
	    int e = (Integer.parseInt(o1.substring(6,8))*10000) + (Integer.parseInt(o1.substring(3, 5))*100)+ (Integer.parseInt(o1.substring(0,2)));
	    int f = (Integer.parseInt(o2.substring(6,8))*10000) + (Integer.parseInt(o2.substring(3, 5))*100)+ (Integer.parseInt(o2.substring(0,2)));
	    if(e < f ){return 1;}
	    if(e == f ){return 0;}
	    if(e> f ){return -1;}
	    return 0;}});
	   
	
	
	sorter.allRowsChanged();
	
	sorter.sort();
	

	
	
	 table.getColumnModel().getColumn(10).setCellRenderer(
	                new DefaultTableCellRenderer() {
	                    @Override
	                    public Component getTableCellRendererComponent(
	                            JTable table, Object value, boolean isSelected,
	                            boolean hasFocus, int row, int column) {
	 
	                        Component component = super
	                                .getTableCellRendererComponent(table, value,
	                                        isSelected, hasFocus, row, column);
	                        // Mit der Methode 'convertRowIndexToModel' wird der Index des Models auf
	                        // den Index der Row umgerechnet
	                        // Anderenfalls wird die farbliche Markierung nicht angepasst.
	                        if (model.getValueAt(table.convertRowIndexToModel(row), 9).toString().equals(_Sys.getReportStatusText(1))) {
	                            component.setBackground(_Sys.getTableYellow());
	                        }
	                        if (model.getValueAt(table.convertRowIndexToModel(row), 9).toString().equals(_Sys.getReportStatusText(0))) {
	                            component.setBackground(_Sys.getTableRed());
	                        }
	                        if (model.getValueAt(table.convertRowIndexToModel(row), 9).toString().equals(_Sys.getReportStatusText(2))) {
	                            component.setBackground(_Sys.getTableGreen());
	                        }
	                        return component;
	                    }
	                });
	 
	
	            
	table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	// SelectionListener für die Table
	
	/*tablegetSelectionModel().addListSelectionListener(new ListSelectionListener(){
	    public void valueChanged(ListSelectionEvent e) {
		//setButtonsVisible(model.getValueAt(table.getSelectedRow(), 9).toString());
		System.out.println(model.getValueAt(table.getSelectedRow(), 9).toString());
		}
	});
	*/
	
	north.setLayout(new GridLayout(1,1));
	north.setBorder(new EmptyBorder(10,50,10,50));
	north.add(tp_main);

	..
bt_delete.addActionListener(new ActionListener(){

	    public void actionPerformed(ActionEvent e) {
		if(!isTableSelect()){return;}
		// Wenn der Anwender einen seiner eigenen Vorgänge löschen möchte, 
		// so muss dies verhindert werden.
		if(isSameEmployee(_Sys.getPersonalNumber())){
		    _Error.getErrorMessage(516, 
				new Exception().getStackTrace()[0].getClassName() + "/" + new Exception().getStackTrace()[0].getMethodName(),"");
		    setInfoText(_Error.getErrorClassification(), _Error.getErrorText1(), _Error.getErrorText2(), _Error.getErrorText3(), 
			    _Error.getErrorText4(), _Error.getExtraText());
		    return;
		}
		// Mitarbeitervorgänge im Status 'gespeichert', oder 'korrigieren' können nicht gelöscht werden
		if(!checkReportStatusToDelete()){
		     return;
		}
		// Anwender bricht das Löschen ab
		if(_Error.getQuestionMessage(514, new Exception().getStackTrace()[0].getClassName() + "/" +
			new Exception().getStackTrace()[0].getMethodName(),"").equals("nein")){
		    _Error.getErrorMessage(515, 
				new Exception().getStackTrace()[0].getClassName() + "/" + new Exception().getStackTrace()[0].getMethodName(),"");
		    setInfoText(_Error.getErrorClassification(), _Error.getErrorText1(), _Error.getErrorText2(), _Error.getErrorText3(), 
			    _Error.getErrorText4(), _Error.getExtraText());
		    return;
		}
		// Löschen wird ausgewählt
		/* Das Löschen von Mitarbeitervorgängen ist an Vorraussetzungen geknüpft.
		 * 
		 * Diese Vorraussetzungen sind noch nicht programmiert, sollten aber
		 * nach Rücksprache mit dem Abschnitt eingefügt werden
		 */
		
		
		/* Hier beginnt der Löschvorgang*/
		else{
		    	sendReport(model.getValueAt(table.convertRowIndexToModel(table.getSelectedRow()), 11).toString(), true);
			_Error.getErrorMessage(517, 
			new Exception().getStackTrace()[0].getClassName() + "/" + new Exception().getStackTrace()[0].getMethodName(),
			"Vorgangsnummer : " + model.getValueAt(table.getSelectedRow(), 11).toString());
			setInfoText(_Error.getErrorClassification(), _Error.getErrorText1(), _Error.getErrorText2(), _Error.getErrorText3(), 
			_Error.getErrorText4(), _Error.getExtraText());
		}
		//clearReportAndArrayList();
		model.deleteData();
	    }
	    
	    
	});
	
	..
    }
	
    public void createAndShowGUI1(JFrame main){
	this._Main = main;
	
	frame.setContentPane(addComponentsToPane());
 	frame.setSize(1260, 900);
 	frame.setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE);
 	frame.setBackground(_Sys.getBackground());
 	frame.setResizable(false);
 	frame.setLocationRelativeTo(null);
	frame.setVisible( true );
	loadEmployee();
	//model.deleteData();
	}
    
    
  ..
    
    public void clearReportAndArrayList(){
	AdminReportData.reportList.clear();
	model.getModelVector().clear();
	table.removeAll();
	
	model.deleteData();
	table.repaint();
    }
    
  ..
    public int compareTo(AdminReportData o) {
	
	int obj = Integer.parseInt(o.getDateAsSimpleDateFormat().substring(0, 2) + o.getDateAsSimpleDateFormat().substring(3,5));
	int th = Integer.parseInt(o.getDateAsSimpleDateFormat().substring(0, 2) + o.getDateAsSimpleDateFormat().substring(3,5));
		    if(th < obj ){
		    return -1;
		}
		if(th == obj ){
		    return 0;
		}
		if(th > obj ){
		    return 1;
		}
	return 0;
	
	
	}
	
    ..
/** Diese Methode liest alle Vorgänge aus der Datei "FileDataMain.txt" aus.*/
public static AdminReportData loadReportFromMainFile( AdminReportModel model, String files , String method){
   
    
    SystemData _Sys = (SystemData)CollectionController.getObject("SystemData");
    CheckFiles _File = (CheckFiles)CollectionController.getObject("CheckFiles");
    MainFrame _Main = (MainFrame)CollectionController.getObject("MainFrame");
   
    String searchFile = files;
       
    
	// hier beginnt das Einlesen aus der Datei
 // hier beginnt das Einlesen aus der Datei
	String read_ReportNumber= "";
	String read_artOfPatrol="";
	..
	String read_fourthPatrolAttenderRang = "";
	
	String read_reportString = ""; // Dieser String entspricht der Zeile in der FileDataUser.txt und dient dazu,Veränderungen am Vorgang festzustellen
	
	// ab hier kommen spezielle Strings für das JTable
	String read_patrolTime ="";
	String read_reportStatus = "";
	String read_patrolAttender = "";
	String emptyFirst = "";
	String emptySecond = "";
	
		
	try{
	    	BufferedReader in=new BufferedReader(new FileReader(searchFile)); 			
	    	String str ;
	    	int i = 0;
	    	int y = 0;
	    	while((str = in.readLine())!= null ){
	    	    if(str.startsWith("V_") ){
	    		char hyphen 		= '•';		// Trennzeichen '•'
    			
    			int  oneHyphen		= str.indexOf(hyphen, 1);
			..
			int  thirtyThreeHyphen	= str.indexOf(hyphen, thirtyTwoHyphen +1);
			
			..
			}
			
			/* Wenn die Suche im Zeitraum gestartet wird..
			 * 
			 */
			if(method.equals("searchByDate")){
			     if((getDateForSearchByDate(read_date)) <= getSearchEndTime() &&
				    getDateForSearchByDate(read_date) >= getSearchStartTime()){
				AdminReportData log = new AdminReportData( read_ReportNumber,read_artOfPatrol,read_operationOffice,read_patrolArea, 
						read_patrolIdentification,read_licenceNumber,read_date, read_nightService, 
						read_patrolTime,read_patrolAttender,read_zivilColor,read_zivilTyp, read_reportStatus, 
						read_firstPatrolTimeFrom, read_firstPatrolTimeTil,read_firstPatrolLeaderName , 
						read_firstPatrolLeaderRang ,read_firstPatrolAttenderName, 
						read_firstPatrolAttenderRang,read_secondPatrolTimeFrom,read_secondPatrolTimeTil,
						read_secondPatrolLeaderName, read_secondPatrolLeaderRang,read_secondPatrolAttenderName,
						read_secondPatrolAttenderRang, read_thirdPatrolTimeFrom,read_thirdPatrolTimeTil, 
						read_thirdPatrolLeaderName ,read_thirdPatrolLeaderRang,read_thirdPatrolAttenderName,
						read_thirdPatrolAttenderRang,read_fourthPatrolTimeFrom,read_fourthPatrolTimeTil,
						read_fourthPatrolLeaderName, read_fourthPatrolLeaderRang,read_fourthPatrolAttenderName,
						read_fourthPatrolAttenderRang ,read_reportString);
				log.addReportDataToArrayList(log);  // legt das Objekt in die ArrayList 'reportList' ab
				//reportList.add(log);
				model.addVehicle(log);
				
				i += 1;
			    }
			}
			/* Wenn die Suche nach Mitarbeiter gestartet wird..
			 * 
			 */
			if(method.equals("searchByEmployee")){
			   if(str.substring(9,17).equals(getActualEmployee())){
				AdminReportData log = new AdminReportData( read_ReportNumber,read_artOfPatrol,read_operationOffice,read_patrolArea, 
						read_patrolIdentification,read_licenceNumber,read_date, read_nightService, 
						read_patrolTime,read_patrolAttender,read_zivilColor,read_zivilTyp, read_reportStatus, 
						read_firstPatrolTimeFrom, read_firstPatrolTimeTil,read_firstPatrolLeaderName , 
						read_firstPatrolLeaderRang ,read_firstPatrolAttenderName, 
						read_firstPatrolAttenderRang,read_secondPatrolTimeFrom,read_secondPatrolTimeTil,
						read_secondPatrolLeaderName, read_secondPatrolLeaderRang,read_secondPatrolAttenderName,
						read_secondPatrolAttenderRang, read_thirdPatrolTimeFrom,read_thirdPatrolTimeTil, 
						read_thirdPatrolLeaderName ,read_thirdPatrolLeaderRang,read_thirdPatrolAttenderName,
						read_thirdPatrolAttenderRang,read_fourthPatrolTimeFrom,read_fourthPatrolTimeTil,
						read_fourthPatrolLeaderName, read_fourthPatrolLeaderRang,read_fourthPatrolAttenderName,
						read_fourthPatrolAttenderRang ,read_reportString);
				log.addReportDataToArrayList(log);  // legt das Objekt in die ArrayList 'reportList' ab
				//reportList.add(log);
				model.addVehicle(log);
				i += 1;
			    }
			     
			}
		    	i+=1;
	    	}
	    	
	    	    
		   
		    }
	    	 in.close();
	}
		   catch (IOException e){
		       JOptionPane.showMessageDialog(null,
				"Es ist ein Dateifehler aufgetreten."+System.getProperty("line.separator")+
				System.getProperty("line.separator")+ "Modul : AdminReportTable/loadReportFromMainFile" +
				System.getProperty("line.separator")+ "Diese Funktion kann nicht fortgeführt werden."+ e +
				System.getProperty("line.separator"), "Dateifehler",
				JOptionPane.ERROR_MESSAGE);
			  return null;
			  }
		   
		  
		return null;
	    	}

	
}



//Unsere Implementation des TableModels
class AdminReportModel implements TableModel{
	private static ArrayList reports = new ArrayList();
	private Vector listeners = new Vector();
 
	public void addVehicle( AdminReportData log ){		// Das wird der Index des Vehikels werden
		int index = reports.size();
		// letzter Eintrag erscheint zuerst
		reports.add(0, log);
		// Jetzt werden alle Listeners benachrichtigt
 
		// Zuerst ein Event, "neue Row an der Stelle index" herstellen
		TableModelEvent e = new TableModelEvent( this, index, index, 
				TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT );
 
		// Nun das Event verschicken
		for( int i = 0, n = listeners.size(); i<n; i++ ){
			((TableModelListener)listeners.get( i )).tableChanged(e);
		}
		
	}
	// Die Anzahl Columns
	public int getColumnCount() { return 12; }
	
	public ArrayList getModelVector(){ return reports; }
	
	// Die Anzahl der Zeilen
	public int getRowCount() {return reports.size();}
 
	// Die Titel der einzelnen Columns
	public String getColumnName(int column) {
		switch( column ){
			case 0: return "Streifenart";
			case 1: return "Einsatzdst.";
			case 2: return "Streifenbereich";
			case 3: return "Streifenbez.";
			case 4: return "amtl. Kz.";
			case 5: return "Datum";
			case 6: return "Nacht";
			case 7: return "Streifenzeit";
			case 8: return "Besatzung";
			case 9: return "Status";
			case 10:return "";
			case 11:return "Vorgangsnummer";
			
			default: return "";
		}
	}
 
	// Der Wert der Zelle (rowIndex, columnIndex)
	public Object getValueAt(int rowIndex, int columnIndex) {
	    System.out.println("rowInd" + rowIndex + "-colInd"+columnIndex);
	       AdminReportData vehicle = AdminReportData.reportList.get( rowIndex );
	      
 
		switch( columnIndex ){
			case 0: return vehicle.getArtOfPatrol();
			case 1: return vehicle.getOperationOffice();
			case 2: return vehicle.getPatrolArea();
			case 3: return vehicle.getPatrolIdentification();
			case 4: return vehicle.getLicenceNumber();
			case 5: return vehicle.getDateAsSimpleDateFormat();
			case 6: return vehicle.getNightService();
			case 7: return vehicle.getPatrolTime();
			case 8: return vehicle.getPatrolAttender();
			case 9: return vehicle.getReportStatus();
			case 10: return null;
			case 11: return vehicle.getReportNumber();
			
			default: return null;
		}
	}
 
	// Eine Angabe, welchen Typ von Objekten in den Columns angezeigt werden soll
	public Class getColumnClass(int columnIndex) {
		switch( columnIndex ){
			case 0: return String.class;
			case 1: return String.class;
			case 2: return String.class;
			case 3: return String.class; 
			case 4: return String.class;
			case 5: return String.class;
			case 6: return Boolean.class;
			case 7: return String.class;
			case 8: return String.class;
			case 9: return String.class;
			case 10: return  String.class;
			case 11: 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 
	    }
	
	public void deleteData(){
	    int index = reports.size();
	    reports.clear();
	    // Jetzt werden alle Listeners benachrichtigt
	    TableModelEvent e = new TableModelEvent( this, index, index, 
				 TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE );
	    // Nun das Event verschicken
	    for( int i = 0, n = listeners.size(); i<n; i++ ){
		((TableModelListener)listeners.get( i )).tableChanged(e);
	    }
	    AdminReportData.reportList.clear();
	}
}
```


----------



## Marco13 (26. Dez 2009)

Bei "deleteData" wirfst du einen
 TableModelEvent e = new TableModelEvent( this, index, index, ...
Das Intervall (von index bis index) ist wohl ungültig. Müßte vielleicht sowas wie  
TableModelEvent e = new TableModelEvent( this, 0, anzahlZeilen, ...
oder so sein...


----------



## Thomas Lorenz (26. Dez 2009)

Das war noch nicht die Lösung. 

Ich habe dieses Intervall wie folgt probiert :

0, getRowCount()      // gleicher Fehler
0, index                  // gleicher Fehler

aber ich sehe es wie Du, dass der Fehler bei deleteData() besteht.

Mir ist noch nicht ganz klar, was dieses Event bewirkt. Löscht das Event aus eigener Kraft die Daten aus dem Model.
Dann bräuchte ich die Zeile : reports.clear() nicht.
Ober gibt das Event den Listenern bekannt dass kurz zuvor (mit reports.clear()) die Daten gelöscht wurden?

Und warum der Sorter nicht so will wie ich ist mir auch nicht klar.


----------

