getFirstRow()源码实例Demo

javax.swing.event.TableModelEvent#getFirstRow()源码实例Demo

下面列出了javax.swing.event.TableModelEvent#getFirstRow() 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: CodenameOne   文件: PropertySheetTable.java
public void tableChanged(TableModelEvent e) {
  // in case the table changes for the following reasons:
  // * the editing row has changed
  // * the editing row was removed
  // * all rows were changed
  // * rows were added
  //
  // it is better to cancel the editing of the row as our editor
  // may no longer be the right one. It happens when you play with
  // the sorting while having the focus in one editor.
  if (e.getType() == TableModelEvent.UPDATE) {
    int first = e.getFirstRow();
    int last = e.getLastRow();
    int editingRow = PropertySheetTable.this.getEditingRow();

    TableCellEditor editor = PropertySheetTable.this.getCellEditor();
    if (editor != null && first <= editingRow && editingRow <= last) {
      editor.cancelCellEditing();
    }
  }
}
 
源代码2 项目: netbeans   文件: SchemaPanel.java
public void tableChanged(TableModelEvent e) {
    //System.out.println("TBALE changed");
    //boolean prefixFlag = false;
    int row = e.getFirstRow();
    int column = e.getColumn();
    AbstractTableModel tblModel = (AbstractTableModel) e.getSource();
    Object data = tblModel.getValueAt(row, column);
    if(column == SCHEMA_COL) {
        SchemaObject rowValue = (SchemaObject)data;
        if(rowValue.toString().equals(startString))
            return;
        String genPrefix = (String) tblModel.getValueAt(row, PREFIX_COL);
        if (genPrefix == null || genPrefix.equals(" ")  ) {
            String prefix = generateUniquePrefix();               
            tableModel.setValueAt(prefix, row, PREFIX_COL);                 
        }
        if(row == tableModel.getRowCount() - 1) {
            addRow(startString);
        }
        //if its the first row, then select it as primary
        if(row == 0) {
           // System.out.println("added first row");
            tblModel.setValueAt(new Boolean(true), 0, 0);
        }
    } 
}
 
源代码3 项目: orbit-image-analysis   文件: PropertySheetTable.java
public void tableChanged(TableModelEvent e) {
  // in case the table changes for the following reasons:
  // * the editing row has changed
  // * the editing row was removed
  // * all rows were changed
  // * rows were added
  //
  // it is better to cancel the editing of the row as our editor
  // may no longer be the right one. It happens when you play with
  // the sorting while having the focus in one editor.
  if (e.getType() == TableModelEvent.UPDATE) {
    int first = e.getFirstRow();
    int last = e.getLastRow();
    int editingRow = PropertySheetTable.this.getEditingRow();

    TableCellEditor editor = PropertySheetTable.this.getCellEditor();
    if (editor != null && first <= editingRow && editingRow <= last) {
      editor.cancelCellEditing();
    }
  }
}
 
源代码4 项目: mae-annotation   文件: TagTableModel.java
@Override
public void tableChanged(TableModelEvent event) {
    tablePanelController.logger.debug(String.format("\"%s\" table changed: %d at %d, %d (INS=1, UPD=0, DEL=-1)", getAssociatedTagTypeName(), event.getType(), event.getFirstRow(), event.getColumn()));

    if (event.getFirstRow() == -1 && event.getColumn() == -1) {
        // ignore changes happened out of table (when initially setting up tables)
        return;
    }
    if (event.getType() == TableModelEvent.UPDATE) {
        // INSERT: listen to insertion is unnecessary, since adding a new tag never happens through table
        // DELETE: since we cannot recover what's already deleted anyway,
        // propagated deletion should be called right before the deletion of a row happens
        // that is, in DeleteTag action, not here, after deletion
        String tid = (String) getValueAt(event.getFirstRow(), TablePanelController.ID_COL);
        List<Integer> oldSpans = Collections.emptyList();
        try {
            oldSpans = tablePanelController.getDriver().getAnchorLocationsByTid(tid);
        } catch (MaeDBException e) {
            tablePanelController.getMainController().showError(e);
        }
        String colName = getColumnName(event.getColumn());
        String value = (String) getValueAt(event.getFirstRow(), event.getColumn());
        // this will return false if update fails
        boolean updated = tablePanelController.getMainController().updateDBFromTableUpdate(tid, colName, value);
        if (!updated) {
            revertChange(event.getFirstRow(), event.getColumn());
        } else {
            propagateChange(event, tid, value, oldSpans);
        }

    }
}
 
源代码5 项目: netbeans   文件: EventBroadcaster.java
private static String tableModelEventToString (TableModelEvent e) {
    StringBuilder sb = new StringBuilder();
    sb.append ("TableModelEvent ");
    switch (e.getType()) {
        case TableModelEvent.INSERT : sb.append ("insert ");
             break;
        case TableModelEvent.DELETE : sb.append ("delete ");
             break;
        case TableModelEvent.UPDATE : sb.append ("update ");
             break;
        default : sb.append("Unknown type ").append(e.getType());
    }
    sb.append ("from ");
    switch (e.getFirstRow()) {
        case TableModelEvent.HEADER_ROW : sb.append ("header row ");
            break;
        default : sb.append (e.getFirstRow());
                  sb.append (' ');
    }
    sb.append ("to ");
    sb.append (e.getLastRow());
    sb.append (" column ");
    switch (e.getColumn()) {
        case TableModelEvent.ALL_COLUMNS :
            sb.append ("ALL_COLUMNS");
            break;
        default : sb.append (e.getColumn());
    }
    return sb.toString();
}
 
源代码6 项目: jdal   文件: TableEditor.java
public void tableChanged(TableModelEvent e) {
	if (e.getType() == TableModelEvent.UPDATE) {
		int row = e.getFirstRow();
		if (row >= 0) {
			setDirtyRow(row);
		}
	}
}
 
源代码7 项目: pentaho-reporting   文件: RowMapperTableModel.java
public void tableChanged( final TableModelEvent e ) {
  recomputeRowCount();
  if ( e.getFirstRow() == 0 && e.getLastRow() == Integer.MAX_VALUE ) {
    fireTableModelEvent( new TableModelEvent( RowMapperTableModel.this,
      e.getFirstRow(), e.getLastRow(), e.getColumn(), e.getType() ) );
    return;
  }

  final TableModelEvent event = new TableModelEvent( RowMapperTableModel.this,
    mapFromModel( e.getFirstRow() ), mapFromModel( e.getLastRow() ), e.getColumn(), e.getType() );
  fireTableModelEvent( event );
}
 
源代码8 项目: rapidminer-studio   文件: TablePanel.java
/**
 * Creates a new {@link TablePanel} instance.
 *
 * @param model
 * @param useScrollPane
 *            if set to <code>true</code>, will add a scrollpane around the GUI.
 * @param hideUnavailableContentAssist
 *            if <code>true</code>, the content assist button will be hidden if no content
 *            assist is available for the given field
 */
public TablePanel(final TablePanelModel model, boolean useScrollPane, boolean hideUnavailableContentAssist) {
	this.mapOfComponents = new HashMap<>();
	this.useScrollPane = useScrollPane;
	this.hideUnavailableContentAssist = hideUnavailableContentAssist;
	this.listener = new TableModelListener() {

		@Override
		public void tableChanged(TableModelEvent e) {
			// table structure changed, re-create it
			if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
				createGUI();
			} else {
				updateComponent(e.getFirstRow(), e.getColumn());
			}
		}
	};

	SwingUtilities.invokeLater(new Runnable() {

		@Override
		public void run() {
			initGUI();
			setModel(model);
		}

	});
}
 
源代码9 项目: pentaho-reporting   文件: GroupedTableModel.java
public void tableChanged( final TableModelEvent e ) {
  recomputeRowCount();
  if ( e.getFirstRow() == 0 && e.getLastRow() == Integer.MAX_VALUE ) {
    fireTableModelEvent( new TableModelEvent( GroupedTableModel.this,
      e.getFirstRow(), e.getLastRow(), e.getColumn(), e.getType() ) );
    return;
  }

  final TableModelEvent event = new TableModelEvent( GroupedTableModel.this,
    mapFromModel( e.getFirstRow() ), mapFromModel( e.getLastRow() ), e.getColumn(), e.getType() );
  fireTableModelEvent( event );
}
 
源代码10 项目: nmonvisualizer   文件: ScrollingTableFix.java
@Override
public void tableChanged(TableModelEvent e) {
    if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
        if (scrollPane.getViewport().getWidth() < table.getPreferredSize().getWidth()) {
            table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        }
        else {
            table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        }
    }
}
 
源代码11 项目: binnavi   文件: CTableSorter.java
@Override
public void tableChanged(final TableModelEvent e) {
  // If we're not sorting by anything, just pass the event along.
  if (!isSorting()) {
    clearSortingState();
    fireTableChanged(e);
    return;
  }

  // If the table structure has changed, cancel the sorting; the
  // sorting columns may have been either moved or deleted from
  // the model.
  if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
    cancelSorting();
    fireTableChanged(e);
    return;
  }

  // We can map a cell event through to the view without widening
  // when the following conditions apply:
  //
  // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and,
  // b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and,
  // c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and,
  // d) a reverse lookup will not trigger a sort (modelToView != null)
  //
  // Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS.
  //
  // The last check, for (modelToView != null) is to see if modelToView
  // is already allocated. If we don't do this check; sorting can become
  // a performance bottleneck for applications where cells
  // change rapidly in different parts of the table. If cells
  // change alternately in the sorting column and then outside of
  // it this class can end up re-sorting on alternate cell updates -
  // which can be a performance problem for large tables. The last
  // clause avoids this problem.
  final int column = e.getColumn();
  if ((e.getFirstRow() == e.getLastRow()) && (column != TableModelEvent.ALL_COLUMNS)
      && (getSortingStatus(column) == NOT_SORTED) && (modelToView != null)) {
    final int viewIndex = getModelToView()[e.getFirstRow()];
    fireTableChanged(new TableModelEvent(CTableSorter.this, viewIndex, viewIndex, column,
        e.getType()));
    return;
  }

  // Something has happened to the data that may have invalidated the row order.
  clearSortingState();
  fireTableDataChanged();
  return;
}
 
源代码12 项目: netbeans   文件: QueryBuilderGraphFrame.java
private void tableModelChanged(TableModelEvent e) {
    
    Log.getLogger().entering("QueryBuilderGraphFrame", "tableModelChanged");

    // We have a mouse click inside a graph table node, indicating select/deselect.
    // Propagate the information to the input table
    
    // Extract some information from the event
    int row = e.getFirstRow();   // the first row that changed
    int column = e.getColumn();  // the column for this event
    
    QueryBuilderTableModel model = (QueryBuilderTableModel) e.getSource();
    String tableSpec = model.getTableSpec();
    
    // DB column name
    String columnName = (String) model.getValueAt(row, column+2);
    
    // boolean - Selected/deselected
    Object value = model.getValueAt(row, column);
    
    if (value==Boolean.TRUE) {      // A column has been selected
        
        // Update the query model if appropriate
        // Do this first so that it's available when adding the row
        if (_queryBuilder._updateModel) {
            _queryBuilder.getQueryModel().addColumn(tableSpec, columnName);
            _queryBuilderInputTable.selectColumn(tableSpec, columnName, Boolean.TRUE);
        }
    }
    
    else if (value==Boolean.FALSE) { // A column has been deselected
        
        // Update the query model, if we're not being driven by it
        // Do this before updating the grid, because we use the model to generate sortorder
        if (_queryBuilder._updateModel) {
            _queryBuilder.getQueryModel().removeColumn(tableSpec, columnName); }
        
        // do not remove the whole row, just deselect the output column.
        _queryBuilderInputTable.selectColumn(tableSpec, columnName, Boolean.FALSE);
    }
    
    // We used to update the text query after every event.  That
    // caused degraded performance.  Now, we check whether we've
    // received a real event, or we're generating the graph as a
    // batch operation.  Also, we trigger only on TableModel events,
    // so InputTableMode must explicitly invoke
    if (_queryBuilder._updateText) {
        // An interactive event -- update the text query
        _queryBuilder.generateText();
    }
}
 
源代码13 项目: cropplanning   文件: TableSorter.java
public void tableChanged(TableModelEvent e) {
    // If we're not sorting by anything, just pass the event along.             
    if (!isSorting()) {
        clearSortingState();
        fireTableChanged(e);
        return;
    }
        
    // If the table structure has changed, cancel the sorting; the             
    // sorting columns may have been either moved or deleted from             
    // the model. 
    if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
        cancelSorting();
        fireTableChanged(e);
        return;
    }

    // We can map a cell event through to the view without widening             
    // when the following conditions apply: 
    // 
    // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and, 
    // b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and,
    // c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and, 
    // d) a reverse lookup will not trigger a sort (modelToView != null)
    //
    // Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS.
    // 
    // The last check, for (modelToView != null) is to see if modelToView 
    // is already allocated. If we don't do this check; sorting can become 
    // a performance bottleneck for applications where cells  
    // change rapidly in different parts of the table. If cells 
    // change alternately in the sorting column and then outside of             
    // it this class can end up re-sorting on alternate cell updates - 
    // which can be a performance problem for large tables. The last 
    // clause avoids this problem. 
    int column = e.getColumn();
    if (e.getFirstRow() == e.getLastRow()
            && column != TableModelEvent.ALL_COLUMNS
            && getSortingStatus(column) == NOT_SORTED
            && modelToView != null) {
        int viewIndex = getModelToView()[e.getFirstRow()];
        fireTableChanged(new TableModelEvent(TableSorter.this, 
                                             viewIndex, viewIndex, 
                                             column, e.getType()));
        return;
    }

    // Something has happened to the data that may have invalidated the row order. 
    clearSortingState();
    fireTableDataChanged();
    return;
}
 
@Override
public void tableChanged(TableModelEvent e) {
	// If we're not sorting by anything, just pass the event along.
	if (!isSorting()) {
		clearSortingState();
		fireTableChanged(e);
		return;
	}

	// If the table structure has changed, cancel the sorting; the
	// sorting columns may have been either moved or deleted from
	// the model.
	if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
		cancelSorting();
		fireTableChanged(e);
		return;
	}

	// We can map a cell event through to the view without widening
	// when the following conditions apply:
	//
	// a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and,
	// b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and,
	// c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and,
	// d) a reverse lookup will not trigger a sort (modelToView != null)
	//
	// Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS.
	//
	// The last check, for (modelToView != null) is to see if modelToView
	// is already allocated. If we don't do this check; sorting can become
	// a performance bottleneck for applications where cells
	// change rapidly in different parts of the table. If cells
	// change alternately in the sorting column and then outside of
	// it this class can end up re-sorting on alternate cell updates -
	// which can be a performance problem for large tables. The last
	// clause avoids this problem.
	int column = e.getColumn();
	if (e.getFirstRow() == e.getLastRow() && column != TableModelEvent.ALL_COLUMNS
			&& getSortingStatus(column) == NOT_SORTED && modelToView != null) {
		int viewIndex = getModelToView()[e.getFirstRow()];
		fireTableChanged(new TableModelEvent(ExtendedJTableSorterModel.this, viewIndex, viewIndex, column,
				e.getType()));
		return;
	}

	// Something has happened to the data that may have invalidated the row order.
	clearSortingState();
	fireTableDataChanged();
	return;
}
 
源代码15 项目: evosql   文件: TableSorter.java
public void tableChanged(TableModelEvent e) {

            // If we're not sorting by anything, just pass the event along.
            if (!isSorting()) {
                clearSortingState();
                fireTableChanged(e);

                return;
            }

            // If the table structure has changed, cancel the sorting; the
            // sorting columns may have been either moved or deleted from
            // the model.
            if (e == null || e.getFirstRow() == TableModelEvent.HEADER_ROW) {
                cancelSorting();
                fireTableChanged(e);

                return;
            }

            // We can map a cell event through to the view without widening
            // when the following conditions apply:
            //
            // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and,
            // b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and,
            // c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and,
            // d) a reverse lookup will not trigger a sort (modelToView != null)
            //
            // Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS.
            //
            // The last check, for (modelToView != null) is to see if modelToView
            // is already allocated. If we don't do this check; sorting can become
            // a performance bottleneck for applications where cells
            // change rapidly in different parts of the table. If cells
            // change alternately in the sorting column and then outside of
            // it this class can end up re-sorting on alternate cell updates -
            // which can be a performance problem for large tables. The last
            // clause avoids this problem.
            int column = e.getColumn();

            if (e.getFirstRow() == e.getLastRow()
                    && column != TableModelEvent.ALL_COLUMNS
                    && getSortingStatus(column) == NOT_SORTED
                    && modelToView != null) {
                int viewIndex = getModelToView()[e.getFirstRow()];

                fireTableChanged(new TableModelEvent(TableSorter.this,
                                                     viewIndex, viewIndex,
                                                     column, e.getType()));

                return;
            }

            // Something has happened to the data that may have invalidated the row order.
            clearSortingState();
            fireTableDataChanged();

            return;
        }
 
源代码16 项目: Logisim   文件: TableSorter.java
@Override
public void tableChanged(TableModelEvent e) {
	// If we're not sorting by anything, just pass the event along.
	if (!isSorting()) {
		clearSortingState();
		fireTableChanged(e);
		return;
	}

	// If the table structure has changed, cancel the sorting; the
	// sorting columns may have been either moved or deleted from
	// the model.
	if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
		cancelSorting();
		fireTableChanged(e);
		return;
	}

	// We can map a cell event through to the view without widening
	// when the following conditions apply:
	//
	// a) all the changes are on one row (e.getFirstRow() ==
	// e.getLastRow()) and,
	// b) all the changes are in one column (column !=
	// TableModelEvent.ALL_COLUMNS) and,
	// c) we are not sorting on that column (getSortingStatus(column) ==
	// NOT_SORTED) and,
	// d) a reverse lookup will not trigger a sort (modelToView != null)
	//
	// Note: INSERT and DELETE events fail this test as they have column
	// == ALL_COLUMNS.
	//
	// The last check, for (modelToView != null) is to see if
	// modelToView
	// is already allocated. If we don't do this check; sorting can
	// become
	// a performance bottleneck for applications where cells
	// change rapidly in different parts of the table. If cells
	// change alternately in the sorting column and then outside of
	// it this class can end up re-sorting on alternate cell updates -
	// which can be a performance problem for large tables. The last
	// clause avoids this problem.
	int column = e.getColumn();
	if (e.getFirstRow() == e.getLastRow() && column != TableModelEvent.ALL_COLUMNS
			&& getSortingStatus(column) == NOT_SORTED && modelToView != null) {
		int viewIndex = getModelToView()[e.getFirstRow()];
		fireTableChanged(new TableModelEvent(TableSorter.this, viewIndex, viewIndex, column, e.getType()));
		return;
	}

	// Something has happened to the data that may have invalidated the
	// row order.
	clearSortingState();
	fireTableDataChanged();
	return;
}
 
源代码17 项目: jplag   文件: TableSorter.java
public void tableChanged(TableModelEvent e) {
    // If we're not sorting by anything, just pass the event along.             
    if (!isSorting()) {
        clearSortingState();
        fireTableChanged(e);
        return;
    }
        
    // If the table structure has changed, cancel the sorting; the             
    // sorting columns may have been either moved or deleted from             
    // the model. 
    if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
        cancelSorting();
        fireTableChanged(e);
        return;
    }

    // We can map a cell event through to the view without widening             
    // when the following conditions apply: 
    // 
    // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and, 
    // b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and,
    // c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and, 
    // d) a reverse lookup will not trigger a sort (modelToView != null)
    //
    // Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS.
    // 
    // The last check, for (modelToView != null) is to see if modelToView 
    // is already allocated. If we don't do this check; sorting can become 
    // a performance bottleneck for applications where cells  
    // change rapidly in different parts of the table. If cells 
    // change alternately in the sorting column and then outside of             
    // it this class can end up re-sorting on alternate cell updates - 
    // which can be a performance problem for large tables. The last 
    // clause avoids this problem. 
    int column = e.getColumn();
    if (e.getFirstRow() == e.getLastRow()
            && column != TableModelEvent.ALL_COLUMNS
            && getSortingStatus(column) == NOT_SORTED
            && modelToView != null) {
        int viewIndex = getModelToView()[e.getFirstRow()];
        fireTableChanged(new TableModelEvent(TableSorter.this, 
                                             viewIndex, viewIndex, 
                                             column, e.getType()));
        return;
    }

    // Something has happened to the data that may have invalidated the row order. 
    clearSortingState();
    fireTableDataChanged();
    return;
}
 
源代码18 项目: wandora   文件: SimpleTable.java
public UpdateHandler(TableModelEvent e) {
    firstModelRow = e.getFirstRow();
    lastModelRow = e.getLastRow();
    convert();
}
 
源代码19 项目: tda   文件: TableSorter.java
public void tableChanged(TableModelEvent e) {
    // If we're not sorting by anything, just pass the event along.             
    if (!isSorting()) {
        clearSortingState();
        fireTableChanged(e);
        return;
    }
        
    // If the table structure has changed, cancel the sorting; the             
    // sorting columns may have been either moved or deleted from             
    // the model. 
    if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
        cancelSorting();
        fireTableChanged(e);
        return;
    }

    // We can map a cell event through to the view without widening             
    // when the following conditions apply: 
    // 
    // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and, 
    // b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and,
    // c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and, 
    // d) a reverse lookup will not trigger a sort (modelToView != null)
    //
    // Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS.
    // 
    // The last check, for (modelToView != null) is to see if modelToView 
    // is already allocated. If we don't do this check; sorting can become 
    // a performance bottleneck for applications where cells  
    // change rapidly in different parts of the table. If cells 
    // change alternately in the sorting column and then outside of             
    // it this class can end up re-sorting on alternate cell updates - 
    // which can be a performance problem for large tables. The last 
    // clause avoids this problem. 
    int column = e.getColumn();
    if (e.getFirstRow() == e.getLastRow()
            && column != TableModelEvent.ALL_COLUMNS
            && getSortingStatus(column) == NOT_SORTED
            && modelToView != null) {
        int viewIndex = getModelToView()[e.getFirstRow()];
        fireTableChanged(new TableModelEvent(TableSorter.this, 
                                             viewIndex, viewIndex, 
                                             column, e.getType()));
        return;
    }

    // Something has happened to the data that may have invalidated the row order. 
    clearSortingState();
    fireTableDataChanged();
    return;
}
 
源代码20 项目: wandora   文件: SimpleTable.java
/**
 * Convenience method to detect a structureChanged table event type.
 * @param e the event to examine.
 * @return true if the event is of type structureChanged or null, false else.
 */
protected boolean isStructureChanged(TableModelEvent e) {
    return e == null || e.getFirstRow() == TableModelEvent.HEADER_ROW;
}