@Override
		public void run(TaskMonitor monitor) throws CancelledException {
			try {
				MemoryMatch match = searcher.findOnce(start, forward, monitor);
				if (match != null) {
					tableModel.addInitialLoadListener(b -> tableLoadComplete(match, b));
					tableModel.addObject(match);
					return;
				}
			}
			catch (Throwable t) {
				// Catch any runtime errors so that we exit task gracefully and don't leave
				// the provider in a stuck "busy" state.
				Msg.showError(this, null, "Unexpected error refreshing bytes", t);
			}
			Swing.runLater(() -> provider.searchOnceCompleted(null, monitor.isCancelled()));
		}
Internal panel of the memory search window that manages the display of the search results
in a table. This panel also includes most of the search logic as it has direct access to the
table for showing the results.
Ghidra/Features/Base/src/main/java/ghidra/features/base/memsearch/gui/MemorySearchResultsPanel.java