public void addDataTableObject(final int index, final DataTableObject dataTableObject) {
		if(getFirstRun()) {
			initHeaderSize();
			setFirstRun(false);
		}
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				DataTableObjectRenderer renderer = 
					new DataTableObjectRenderer(_headerGrid, dataTableObject, _selectionManager);
				int upperHeight = _emptyDummyUpperViewportPanel.getSize().height;
				int viewportHeight = _viewportPanel.getSize().height;
				int lowerHeight = _lowerViewportPanel.getSize().height;
				int value = _verticalScrollBar.getModel().getValue();
				_screenHeight = _verticalScrollBar.getVisibleAmount();
				
				if(_dtoRenderers.isEmpty()) {
					// einfach hinzufügen, _firstRow, _lastRow setzen
					_dtoRenderers.add(renderer);
					_firstRow = 0;
					_lastRow = 0;
					
					renderer.setLinks();
					
					/* Kode wie dieser läßt einen Gruseln: die Höhen der beiden Komponeneten sind
					 * voneinander abhängig, und was man nicht sieht: die Reihenfolge ist wichtig, 
					 * wenn man irgendetwas an anderen Stellen ändert, z.B. bei der Behebung eines
					 * Bugs zu Zeilenhöhen bei leeren Arrays! Also Vorsicht hier!
					 */
					JComponent rowHeaderRow = renderer.getRowHeaderRow(TIME_FORMAT);
					JComponent viewportRow = renderer.getViewportRow();
					
					int nextRowHeight = renderer.getHeight();
					
					rowHeaderRow.setPreferredSize(new Dimension(rowHeaderRow.getPreferredSize().width, nextRowHeight));
					rowHeaderRow.setMaximumSize(new Dimension(rowHeaderRow.getMaximumSize().width, nextRowHeight));
					viewportRow.setMaximumSize(new Dimension(viewportRow.getMaximumSize().width, nextRowHeight));
					
					_rowHeaderPanel.add(rowHeaderRow);
					_viewportPanel.add(viewportRow);
				}
				else {
					// an Position index einen Datensatz einfügen
					if(index < _firstRow) {
						int height = renderer.getHeight();
						setUpperPanel(_emptyDummyUpperViewportPanel.getSize().height + height);
						_dtoRenderers.add(index, renderer);
						_firstRow++;
						_lastRow++;
						_scrollPane.validate();
						_verticalScrollBar.getModel().setValue(_verticalScrollBar.getModel().getValue() + height);
					}
					else if(index > _lastRow) {
						int height = renderer.getHeight();
						setLowerPanel(_lowerViewportPanel.getSize().height + height);
						try {
							_dtoRenderers.add(index, renderer);
						} catch (IndexOutOfBoundsException e) {
							_dtoRenderers.add( renderer);
						}
					}
					else { // index >= _firstRow && index <= _lastRow
						// erst einfügen, dann ggf. löschen
						int position = index - _firstRow;
						
						renderer.setLinks();
						
						/* Kode wie dieser läßt einen Gruseln: die Höhen der beiden Komponeneten sind
						 * voneinander abhängig, und was man nicht sieht: die Reihenfolge ist wichtig, 
						 * wenn man irgendetwas an anderen Stellen ändert, z.B. bei der Behebung eines
						 * Bugs zu Zeilenhöhen bei leeren Arrays! Also Vorsicht hier!
						 */
						JComponent rowHeaderRow = renderer.getRowHeaderRow(TIME_FORMAT);
						JComponent viewportRow = renderer.getViewportRow();
						
						int nextRowHeight = renderer.getHeight();
						viewportHeight += nextRowHeight;
						
						rowHeaderRow.setPreferredSize(new Dimension(rowHeaderRow.getPreferredSize().width, nextRowHeight));
						rowHeaderRow.setMaximumSize(new Dimension(rowHeaderRow.getMaximumSize().width, nextRowHeight));
						viewportRow.setMaximumSize(new Dimension(viewportRow.getMaximumSize().width, nextRowHeight));
						
						_rowHeaderPanel.add(rowHeaderRow, position);
						_viewportPanel.add(viewportRow, position);
						_dtoRenderers.add(index, renderer);
						_lastRow++;
						
						// neue letzte zeile ermitteln
						DataTableObjectRenderer firstRenderer = _dtoRenderers.get(_firstRow);
						int firstRowHeight = firstRenderer.getHeight();
						viewportHeight = 0;
						int newLastRow = _firstRow;
						while(upperHeight + viewportHeight < 
								value + _screenHeight + firstRowHeight && newLastRow < _dtoRenderers.size()) {
							DataTableObjectRenderer nextRenderer = _dtoRenderers.get(newLastRow++);
							viewportHeight += nextRenderer.getHeight();
						}
						newLastRow--;
						for(int i = _lastRow; i > newLastRow; i--) { // überflüssige Zeilen löschen
							DataTableObjectRenderer nextRenderer = _dtoRenderers.get(i);
							lowerHeight += nextRenderer.getHeight();
							_rowHeaderPanel.remove(_rowHeaderPanel.getComponentCount() - 1);
							_viewportPanel.remove(_viewportPanel.getComponentCount() - 1);
							nextRenderer.unsetLinks();
						}
						_lastRow = newLastRow;
						setLowerPanel(lowerHeight);
					}
				}
				_scrollPane.revalidate();
			}
		});
	}