# Markierte Zeile löschen AbstractTableModel



## Hades (28. Jan 2011)

Hallo zusammen,

ich habe ein Problem und zwar wie kann ich im AbstractTableModel makierte Zeilen löschen.
Versucht habe ich es schon mit dieser Variante:


```
public void removeRow(JTable table) {
    	DefaultTableModel tm = (DefaultTableModel) table.getModel();
    	int[] rows = table.getSelectedRows();
    	
    	for(int i = 0; i < rows.length; i++) {
    		tm.removeRow(table.getSelectedRow());
    	}	
    }
```
, aber dann bekomme ich als Fehlermeldung nur diese Nachricht:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: Table cannot be cast to javax.swing.table.DefaultTableModel
	at Frame.removeRow(Frame.java:355)
	at Frame.actionPerformed(Frame.java:350)
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)


Ich weiß gerade echt nicht mehr weiter, wäre echt super wenn mir einer helfen könnte.
Vielen Dank schon mal im voraus.


----------



## Gast2 (28. Jan 2011)

Ja dein Model ist keine Instanz vom DefaultTableModel...
Die Fehlermeldung sagt doch alles.


----------



## Hades (28. Jan 2011)

Mhm... dann muss ich anders fragen.

Welche Alternative bietet mir das AbstractTableModel?

Diese ?
void 	fireTableRowsDeleted(int firstRow, int lastRow)
          Notifies all listeners that rows in the range [firstRow, lastRow], inclusive, have been deleted.


----------



## Gast2 (28. Jan 2011)

Gar keins kommt auf dein eigenes Model an ich weiß ja nicht wie das aussieht...
Du musst ja irgendeine erbenden Klasse haben...


----------



## SlaterB (28. Jan 2011)

wenn der JTable-Konstruktor [c]JTable(final Object[][] rowData, final Object[] columnNames)[/c]
benutzt wurde, dann wird intern eben kein DefaultTableModel verwendet, 
bei den anderen Konstruktoren schon


----------



## Gast2 (28. Jan 2011)

SlaterB hat gesagt.:


> wenn der JTable-Konstruktor [c]JTable(final Object[][] rowData, final Object[] columnNames)[/c]
> benutzt wurde, dann wird intern eben kein DefaultTableModel verwendet,
> bei den anderen Konstruktoren schon



Stimmt die Möglichkeit gibt es auch noch ...


----------



## Hades (28. Jan 2011)

Ich habe echt ein bisschen zu kompliziert gedacht. 

```
public void delete(int rowIndex) {
		
		if(rowIndex < 0) {
			return;
		}
		
		getFiles.remove(rowIndex);
		this.fireTableRowsDeleted(rowIndex, rowIndex);
		
	}
```

Jetzt habe ich nur das Problem das zwar die Zeile gelöscht wird, aber die Aktualisierung erst mit einem klick auf die Tabelle angezeigt wird.


----------



## SlaterB (28. Jan 2011)

das DefaultTableModel machts genauso und da klappt für jedermann,

eine Ursache dafür kann man sich kaum ausdenken, vielleicht hilft mehr geposteter Code,
idealerweise ein kurzes vollständiges Testprogramm


----------



## Hades (29. Jan 2011)

```
import java.util.Vector;

import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;

/**
 * 
 */

/**
 * @author
 *
 */
public class Table extends AbstractTableModel {
	

	private Vector<ClassFile> getFiles = new Vector<ClassFile>();
	private Vector<TableModelListener> tableListener = new Vector<TableModelListener>();
	
	
	/**
	 * 
	 */
	@Override
	public int getColumnCount() {
		// TODO Auto-generated method stub
		return 6;
	}
	
	/**
	 * 
	 */
	@Override
	public int getRowCount() {
		// TODO Auto-generated method stub
		return getFiles.size();
	}

	/**
	 * 
	 */
	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		// TODO Auto-generated method stub
		ClassFile file = (ClassFile)getFiles.get(rowIndex);
		
		switch(columnIndex) {
			case 0:
				return  rowIndex + 1;
			case 1:
				return file.getName();
			case 2:
				return file.getExt();
			case 3:
				return file.getSize();
			case 4:
				return file.getDate();
			case 5:
				return file.isCanRead();
			default:
				return null;
		}	
	}
	
	/**
	 * 
	 */
	public String getColumnName(int columnIndex) {
		switch(columnIndex) {
			case 0:
				return "Row #";
			case 1:
				return "Name";
			case 2:
				return "Endung";
			case 3:
				return "Größe in KB";
			case 4:
				return "Datum";
			case 5:
				return "Schreibzugriff";
			default:
				return null;
		}
	}
	
	/**
	 *
	 */
	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		// TODO Auto-generated method stub
		return false;
	}
	
	
	@Override
	public void addTableModelListener(TableModelListener l) {
		// TODO Auto-generated method stub
		tableListener.add(l);
	}
	
	
	@Override
	public void removeTableModelListener(TableModelListener l) {
		// TODO Auto-generated method stub
		tableListener.add(l);
	}

	/**
	 * 
	 * @param 
	 */
	public void addFiles(ClassFile file) {
		int index = getFiles.size();
		getFiles.add(file);
		
		TableModelEvent event = new TableModelEvent(this, index, index,
				TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT);
		
		for(int i = 0, n = tableListener.size(); i < n; i++) {
			((TableModelListener)tableListener.get(i)).tableChanged(event);
		}
	}
	
	/**
	 * 
	 * @param
	 */
	public void delete(int rowIndex) {
		
		if(rowIndex < 0) {
			return;
		}
		
		getFiles.remove(rowIndex);
		this.fireTableRowsDeleted(rowIndex, rowIndex);
	}
}
```

das ist mein TableModel.


----------



## SlaterB (29. Jan 2011)

alles zu TableModelListener musst du entfernen, das AbstractTableModel kümmert sich darum 
bzw. informiert in seinen fire-Methoden auch nur die dort gespeicherten Listener, im Moment keine weil dein Model das addTableModelListener() abfängt,
wenn dann müsstest du dich auch um die Events kümmern, aber unnötig, alles dazu dem AbstractTableModel überlassen

edit: bei add() hast die Events ja richtig selber gemacht, so kompliziert auf bei remove,
oder Listener weg, überall fireXy() benutzen, auch beim add()

im Extremfall ist auch denkbar in addTableModelListener() einen super-Aufruf einzufügen, damit die Listener von beiden verwaltet werden, bei removeTableModelListener() dann auch, na nicht so schön


----------



## Hades (29. Jan 2011)

So jetzt habe ich es funktioniert jetzt einwandfrei.

```
public void delete(int rowIndex) {
        
        if(rowIndex < 0) {
            return;
        }
        
        getFiles.remove(rowIndex);
        this.fireTableRowsDeleted(rowIndex, rowIndex);
        
        TableModelEvent event = new TableModelEvent(this, rowIndex, rowIndex,
                TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE);
        
        for(int i = 0, n = tableListener.size(); i < n; i++) {
            ((TableModelListener)tableListener.get(i)).tableChanged(event);
        }
    }
```

nochmals vielen Dank für die Denkanstöße.


----------

