GP-3352 - Fixed table dispose() exception

This commit is contained in:
dragonmacher 2023-04-25 15:28:43 -04:00
parent 102729174d
commit 3fbcb32b65
3 changed files with 19 additions and 18 deletions

View file

@ -162,7 +162,7 @@ public class FunctionStartRFParamsDialog extends ReusableDialogComponentProvider
this.plugin = plugin; this.plugin = plugin;
rowObjects = new ArrayList<>(); rowObjects = new ArrayList<>();
trainingSource = plugin.getCurrentProgram(); trainingSource = plugin.getCurrentProgram();
JPanel panel = createPanel(); JPanel panel = createWorkPanel();
addWorkPanel(panel); addWorkPanel(panel);
trainButton = addTrainModelsButton(); trainButton = addTrainModelsButton();
addHideDialogButton(); addHideDialogButton();
@ -268,7 +268,7 @@ public class FunctionStartRFParamsDialog extends ReusableDialogComponentProvider
return trainModelsButton; return trainModelsButton;
} }
private JPanel createPanel() { private JPanel createWorkPanel() {
JPanel mainPanel = new JPanel(new BorderLayout()); JPanel mainPanel = new JPanel(new BorderLayout());
tableModel = new RandomForestTableModel(plugin.getTool(), rowObjects); tableModel = new RandomForestTableModel(plugin.getTool(), rowObjects);
@ -277,7 +277,7 @@ public class FunctionStartRFParamsDialog extends ReusableDialogComponentProvider
GTable modelStatsTable = evalPanel.getTable(); GTable modelStatsTable = evalPanel.getTable();
modelStatsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); modelStatsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
evalPanel.setBorder(BorderFactory.createTitledBorder(MODEL_STATISTICS)); evalPanel.setBorder(BorderFactory.createTitledBorder(MODEL_STATISTICS));
mainPanel.add(evalPanel, BorderLayout.EAST); mainPanel.add(evalPanel, BorderLayout.CENTER);
DockingAction applyAction = new ActionBuilder(APPLY_MODEL_ACTION_NAME, plugin.getName()) DockingAction applyAction = new ActionBuilder(APPLY_MODEL_ACTION_NAME, plugin.getName())
.description("Apply Model to Source Program") .description("Apply Model to Source Program")
@ -438,7 +438,7 @@ public class FunctionStartRFParamsDialog extends ReusableDialogComponentProvider
private JScrollPane getFuncAlignmentScrollPane() { private JScrollPane getFuncAlignmentScrollPane() {
Long modulus = (Long) modBox.getSelectedItem(); Long modulus = (Long) modBox.getSelectedItem();
int minSize = minimumSizeField.getIntValue(); int minSize = minimumSizeField.getIntValue();
//initialize map //initialize map
Map<Long, Long> countMap = Map<Long, Long> countMap =
LongStream.range(0, modulus).boxed().collect(Collectors.toMap(i -> i, i -> 0l)); LongStream.range(0, modulus).boxed().collect(Collectors.toMap(i -> i, i -> 0l));
FunctionIterator fIter = trainingSource.getFunctionManager().getFunctionsNoStubs(true); FunctionIterator fIter = trainingSource.getFunctionManager().getFunctionsNoStubs(true);
@ -514,7 +514,7 @@ public class FunctionStartRFParamsDialog extends ReusableDialogComponentProvider
private void searchProgram(Program targetProgram, RandomForestRowObject modelRow) { private void searchProgram(Program targetProgram, RandomForestRowObject modelRow) {
GetAddressesToClassifyTask getTask = GetAddressesToClassifyTask getTask =
new GetAddressesToClassifyTask(targetProgram, plugin.getMinUndefinedRangeSize()); new GetAddressesToClassifyTask(targetProgram, plugin.getMinUndefinedRangeSize());
//don't want to use the dialog's progress bar //don't want to use the dialog's progress bar
TaskLauncher.launchModal("Gathering Addresses To Classify", getTask); TaskLauncher.launchModal("Gathering Addresses To Classify", getTask);
if (getTask.isCancelled()) { if (getTask.isCancelled()) {
return; return;

View file

@ -28,7 +28,7 @@ public abstract class AbstractGTableModel<T> extends AbstractTableModel
private List<T> lastSelectedObjects = new ArrayList<>(); private List<T> lastSelectedObjects = new ArrayList<>();
private boolean isDisposed; protected boolean isDisposed;
@Override @Override
public T getRowObject(int row) { public T getRowObject(int row) {

View file

@ -162,9 +162,9 @@ public abstract class ThreadedTableModel<ROW_OBJECT, DATA_SOURCE>
/** /**
* A package-level method. Subclasses should not call this. * A package-level method. Subclasses should not call this.
* *
* <p>This exists to handle whether this model should load incrementally. * <p>This exists to handle whether this model should load incrementally.
* *
* @param monitor the monitor * @param monitor the monitor
* @return the loaded data * @return the loaded data
* @throws CancelledException if the load was cancelled * @throws CancelledException if the load was cancelled
@ -221,7 +221,7 @@ public abstract class ThreadedTableModel<ROW_OBJECT, DATA_SOURCE>
* This method will retrieve a column value for the given row object. Further, the retrieved * This method will retrieve a column value for the given row object. Further, the retrieved
* value will be cached. This is useful when sorting a table, as the same column value may * value will be cached. This is useful when sorting a table, as the same column value may
* be requested multiple times. * be requested multiple times.
* *
* <p><u>Performance Notes</u> * <p><u>Performance Notes</u>
* <ul> * <ul>
* <li>This method uses a {@link HashMap} to cache column values for a row object. Further, * <li>This method uses a {@link HashMap} to cache column values for a row object. Further,
@ -241,7 +241,7 @@ public abstract class ThreadedTableModel<ROW_OBJECT, DATA_SOURCE>
* {@link Comparable}. This is possible any time that a row object already has a field * {@link Comparable}. This is possible any time that a row object already has a field
* that is used for a given column. * that is used for a given column.
* </ul> * </ul>
* *
* @param rowObject the row object * @param rowObject the row object
* @param columnIndex the column index for which to get a value * @param columnIndex the column index for which to get a value
* @return the column value * @return the column value
@ -413,7 +413,7 @@ public abstract class ThreadedTableModel<ROW_OBJECT, DATA_SOURCE>
* Override this to change how filtering is performed. This implementation will do nothing * Override this to change how filtering is performed. This implementation will do nothing
* if a <code>TableFilter</code> has not been set via a call to * if a <code>TableFilter</code> has not been set via a call to
* {@link #setTableFilter(TableFilter)}. * {@link #setTableFilter(TableFilter)}.
* *
* @param data The list of data to be filtered. * @param data The list of data to be filtered.
* @param monitor the progress monitor to check for cancellation. * @param monitor the progress monitor to check for cancellation.
* @param lastSortingContext the comparator used to sort data. This can be used by overridden * @param lastSortingContext the comparator used to sort data. This can be used by overridden
@ -513,17 +513,17 @@ public abstract class ThreadedTableModel<ROW_OBJECT, DATA_SOURCE>
/** /**
* Removes the specified object from this model and schedules an update. * Removes the specified object from this model and schedules an update.
* *
* <P>Note: for this method to function correctly, the given object must compare as * <P>Note: for this method to function correctly, the given object must compare as
* {@link #equals(Object)} and have the same {@link #hashCode()} as the object to be removed * {@link #equals(Object)} and have the same {@link #hashCode()} as the object to be removed
* from the table data. This allows clients to create proxy objects to pass into this method, * from the table data. This allows clients to create proxy objects to pass into this method,
* as long as they honor those requirements. * as long as they honor those requirements.
* *
* <P>If this model's data is sorted, then a binary search will be used to locate the item * <P>If this model's data is sorted, then a binary search will be used to locate the item
* to be removed. However, for this to work, all field used to sort the data must still be * to be removed. However, for this to work, all field used to sort the data must still be
* available from the original object and must be the same values. If this is not true, then * available from the original object and must be the same values. If this is not true, then
* the binary search will not work and a brute force search will be used. * the binary search will not work and a brute force search will be used.
* *
* @param obj the object to remove * @param obj the object to remove
*/ */
public void removeObject(ROW_OBJECT obj) { public void removeObject(ROW_OBJECT obj) {
@ -537,7 +537,7 @@ public abstract class ThreadedTableModel<ROW_OBJECT, DATA_SOURCE>
/** /**
* Called when a {@link TableUpdateJob} is cancelled by the user via the Gui. (Disposing of the * Called when a {@link TableUpdateJob} is cancelled by the user via the Gui. (Disposing of the
* table takes a different path.) This is not called when using an incrementally loading * table takes a different path.) This is not called when using an incrementally loading
* table model. * table model.
*/ */
protected void backgroundWorkCancelled() { protected void backgroundWorkCancelled() {
pendingSortContext = null; pendingSortContext = null;
@ -668,6 +668,7 @@ public abstract class ThreadedTableModel<ROW_OBJECT, DATA_SOURCE>
doClearData(); doClearData();
disposeDynamicColumnData(); disposeDynamicColumnData();
clearCache(); clearCache();
isDisposed = true;
} }
/** /**
@ -787,7 +788,7 @@ public abstract class ThreadedTableModel<ROW_OBJECT, DATA_SOURCE>
/** /**
* Sets the update delay, which is how long the model should wait before updating, after a * Sets the update delay, which is how long the model should wait before updating, after a
* change has been made the data. * change has been made the data.
* *
* @param updateDelayMillis the new update delay. * @param updateDelayMillis the new update delay.
* @param maxUpdateDelayMillis the new max update delay; updates will not wait past this time. * @param maxUpdateDelayMillis the new max update delay; updates will not wait past this time.
*/ */
@ -818,13 +819,13 @@ public abstract class ThreadedTableModel<ROW_OBJECT, DATA_SOURCE>
* Returns the strategy to use for performing adds and removes to this table. Subclasses can * Returns the strategy to use for performing adds and removes to this table. Subclasses can
* override this method to customize this process for their particular type of data. See the * override this method to customize this process for their particular type of data. See the
* implementations of {@link TableAddRemoveStrategy} for details. * implementations of {@link TableAddRemoveStrategy} for details.
* *
* <P>Note: The default add/remove strategy assumes that objects to be removed will be the same * <P>Note: The default add/remove strategy assumes that objects to be removed will be the same
* instance that is in the list of this model. This allows the {@link #equals(Object)} and * instance that is in the list of this model. This allows the {@link #equals(Object)} and
* {@link #hashCode()} to be used when removing the object from the list. If you model does * {@link #hashCode()} to be used when removing the object from the list. If you model does
* not pass the same instance into {@link #removeObject(Object)}, then you will need to update * not pass the same instance into {@link #removeObject(Object)}, then you will need to update
* your add/remove strategy accordingly. * your add/remove strategy accordingly.
* *
* @return the strategy * @return the strategy
*/ */
protected TableAddRemoveStrategy<ROW_OBJECT> getAddRemoveStrategy() { protected TableAddRemoveStrategy<ROW_OBJECT> getAddRemoveStrategy() {