TableSorter Bug-Fehler?

Sebastian29

Erfahrenes Mitglied
Hi an alle!

Ich verwende die Klasse TableSorter von Sun und übergebe mit meinem eigenen AbstractTableModel. Meine eigene AbstractCellEditor und DefaultTableCellRenderer sind auch dabei. Es funktioniert auch alles prima.

Jetzt kommen wir zum Problem, was ich nur vermuten kann, dass das ein Bug-Fehler sein könnte.

Jedes Mal, wenn die Tabelle nur eine einzige Zeile hat und klicke per Maus einmal auf irgendeine Zelle, knallt plötzlich diesen ArrayIndexOutOfBoundsException:

Natürlich erst clear() und dann einfügen!

<CODE>
java.lang.ArrayIndexOutOfBoundsException: 1
at com.gselectronic.tabelle.TableSorter.modelIndex(TableSorter.java:250)
at com.gselectronic.tabelle.TableSorter.setValueAt(TableSorter.java:291)
at javax.swing.JTable.setValueAt(Unknown Source)
at javax.swing.JTable.editingStopped(Unknown Source)
at javax.swing.AbstractCellEditor.fireEditingStopped(Unknown Source)
at com.gselectronic.tabelle.Finanzbuchhaltung.TableCellEditorFinanzbuchhaltung.fireEditingStopped(TableCellEditorFinanzbuchhaltung.java:163)
at javax.swing.AbstractCellEditor.stopCellEditing(Unknown Source)
at com.gselectronic.tabelle.Finanzbuchhaltung.TableCellEditorFinanzbuchhaltung.stopCellEditing(TableCellEditorFinanzbuchhaltung.java:159)
at javax.swing.JTable.editCellAt(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI$MouseInputHandler.adjustFocusAndSelection(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI$MouseInputHandler.mousePressed(Unknown Source)
at java.awt.AWTEventMulticaster.mousePressed(Unknown Source)
at java.awt.Component.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.pumpOneEventForHierarchy(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)
</CODE>


ab da in der Klasse TableSorter sehe ich, dass row = 1 steht! Die 1. Zeile (row = 0) der Tabelle ist doch 0 und die 2. Zeile (row = 1) gibt es gar nicht, weil es in der Tabelle nur eine Zeile gibt! Deshalb Exception!

<CODE>
public void setValueAt(Object aValue, int row, int column) { <--- BUG-Fehler row = 1
tableModel.setValueAt(aValue, modelIndex(row), column);
}
</CODE>

Falls ihr nicht wisst, wie ich dieses Problem lösen könnte, möchte ich gerne dieses an Sun schreiben, ansonsten finde ich überhaupt keine aktuelle TableSorter-Klasse. Kostet es was, wenn ich mich bei Sun anmelde bzw. bei Sun registiere, um dort diesen Bug-Fehler zu fragen?

Gruß
Sebastian29
 
Hallo,

ich denke eher das ist ein Fehler in deiner Implementierung... wenn du Java 6 verwendest kannst du auch den TableRowSorter verwenden:
http://java.sun.com/javase/6/docs/api/javax/swing/table/TableRowSorter.html
(Nebenbei gibts dann auch noch ne Möglichkeit zum Filtern)

Schau mal hier:
http://www.tutorials.de/forum/swing-awt-swt/190669-defaulttablemodel-jtable-sortieren.html
http://www.tutorials.de/forum/swing...en-auch-urspruenglicher-tabelle-loeschen.html

Poste doch mal eine "MInimale" Beispielanwendung die dein Problem reproduziert.

Gruß Tom
 
Moin Thomas!

Ich verwende mit Java 1.4.2 !

Zwischen DefaultTableModel und Sorter müsste bei mir in Ordnung sein, was ich gerade beim Debuggen gründlich geprüft habe! Sorry, erstmal von meinem Denkfehler, was manchmal auch passieren könnte.

Ich erkläre erstmal die Reihenfolge, was ich im AbstractCellEditor eingebaut habe, da ich ein Gefühl aus dem Bauch habe, dass ich da irgendwie falsch implementiert habe, sonst hat es ohne AbstractCellEditor immer geklappt.

Also, es geht darum, dass man eine bestimmte Zeile auswählen möchte. Wenn man auf der gewünschten Zeile doppelklickt, wird die Nummer in das Textfeld, das ausserhalb der Tabelle liegt, eingetragen und mit der Methode doClick() wird das Button autom. geklickt. Die Tabelle kriegt ja mit, wenn ich das Vector erstmal mit deleteAll() und fireTableDataChanged() lösche und dann werden die neuen Daten in das Vector mit setValueAt hinzugefügt und die Tabelle wird neu dargestellt. Was ich nur denke ist, dass TableSorter nicht mitgekriegt hat, dass der Vector neue ZeileIndex (row) hat, z.B. beim 1. Suchen bekommt die Tabelle 15 Zeilen, dann klicke ich die gewünschte Zeile in der Tabelle, die Nummer wird in das Textfeld eingetragen, nach dem doClick() bekommt die Tabelle dann 4 Zeilen. Wenn ich nochmal die gewünschte Zeile auswähle, wird plötzlich ein ArrayIndexOutOfBoundsException: 13! Ich frage mich bloß, wo kommt die 13 her? Ich habe doch nur 4 Zeilen. Deshalb muss ich irgendwo abfeuern oder nicht?


Die Methode in der Klasse von AbstractTableModel:

Code:
	public Component getTableCellEditorComponent(
			JTable table, 
			Object value, 
			boolean isSelected, 
			int row, int column) 
	{
		this.table = table;
		
		m_textfield.setForeground( LABEL_COLOR_BLACK );
		m_textfield.setSelectionColor( LABEL_COLOR_RED );
		m_textfield.setDisabledTextColor( LABEL_COLOR_BLACK );
		m_textfield.setHorizontalAlignment(  
                     Column.m_columnsFinanzbuchhaltung[ column ].m_alignment );
		m_textfield.setText( value == null ? "" : value.toString() );
		
		if( m_textfield.getText().equals( "0" ) )
			m_textfield.setText( "" );
		
		// Bei leerem Textfeld ist nicht klickbar
		if( m_textfield.getText().equals( "" ) )
		{
			m_textfield.setEnabled( false );
			return m_textfield;
		}
				
		// Automatisch suchen
		if( !m_textfield.getText().equals( "" ) )
		{
			switch ( column ) 
			{
				// Spalte KontoNr
				case 1:
					// Suchoption autom.auf KontoNr wechseln
					parent.getCbSuchOptionen().setSelectedIndex( 0 );
					break;
				// Spalte RechnNr
				case 2:
					// Suchoption autom.auf RechnNr wechseln
					parent.getCbSuchOptionen().setSelectedIndex( 1 );
					break;
				// Spalte VertragsNr
				case 3:
					// Suchoption autom.auf VertragsNr wechseln
					parent.getCbSuchOptionen().setSelectedIndex( 2 );
					break;
				default:
					break;
			}
			
			parent.getTfKontoNrVon().setText( m_textfield.getText() );
			
			if( !parent.getTfKontoNrVon().getText().equals( "" ) )
				parent.getBtnSuchen().doClick();
		}
		
		fireEditingCanceled();
		
		return m_textfield;
	}


Die Methode in der Klasse von DefaultTableCellRenderer:

Code:
public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column )
	{
		c = super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column);
		
		l = (JLabel) c;
		
		String art = String.valueOf( table.getModel().getValueAt( row, Column.COL_FINANZ_ART ) );
        
		l.setOpaque(true);
		l.setHorizontalAlignment( Column.m_columnsFinanzbuchhaltung[ column ].m_alignment );
	
        // Status
	status.setText( table.getRowCount() + TEXT_FINANZ_EINTRAEGE );
        
	// Jede gefundene Zeile der Art "U" wird rot gefärbt
        if (art.equals("U") ) {
            l.setBackground( Color.RED );
            l.setForeground( Color.WHITE );
        }
        else if( !isSelected )
        {
            l.setBackground( Color.WHITE );
            l.setForeground( Color.BLACK );
        }
        
        if( String.valueOf( value ).equals( "0" ) )
        	l.setText( "" );
        
		return l;
	}


Ich hoffe, ihr wisst, was ich meine!

Gruß
Sebastian29
 
Hi!

So, jetzt habe ich endlich den schweren Fehler gefunden! Es lag tatsächlich daran, dass der Vector (AbstractTableModel) dem TableSorter nicht mitgeteilt hat, dass ich eine neue Tabelle habe, deshalb stand in der alten Tabelle, wo trotzdem neue Daten dort dargestellt wurde, aber der Index der Zeilen wurde nicht aktualisiert.

Ich habe ganz einfach in der Methode "setValueAt" von AbstractTableModel am Ende zusätzlich "fireTableChanged( null );" eingetragen!

Damit ist das Problem endlich gelöst. :-)

Trotzdem Danke an Thomas, dass der Fehler an mir liegen könnte, was ich nur noch an Bug gedacht habe! :-) Sorry, über den Bug hätte ich auch besser zurückhalten müssen! :-)

Gruß
Sebastian29
 
Zurück