public static void runNow(Runnable r) {

		try {
			// not sure what a reasonable wait is for a background thread; we can make this larger
			// if we find that a really slow system UI causes this to fail
			runNow(r, SWING_TIMEOUT_SECONDS_VALUE, TimeUnit.SECONDS);
		}
		catch (UnableToSwingException e) {

			//
			// Special Cases: if we are in production mode, then this is most likely a deadlock.
			// In that case, log the thread state.  In development mode, it is possible for this
			// to happen while debugging.  In that case, log a message, and then post the work
			// to be done without a timeout.
			//
			String warning = "Timed-out waiting to run a Swing task--potential deadlock!";
			if (SystemUtilities.isInReleaseMode()) {
				Throwable threadDump = ReflectionUtilities.createJavaFilteredThrowable();
				Msg.error(Swing.class, warning + "\nThreads State:\n" + threadDump);
				throw new RuntimeException(warning, e);
			}

			//
			// dev or testing mode
			//

			// note: using Swing.class for the originator does not work (presumably it conflicts
			//       with another logger sharing its name.  So, use the full name here.
			String originator = Swing.class.getName();
			Msg.debug(originator, warning + "  Ignore this message if debugging");
			doRun(r, true, SWING_RUN_ERROR_MSG);
		}
	}
Calls the given runnable on the Swing thread

@param r the runnable
@see #runNow(Supplier) if you need to return a value from the Swing thread.
Ghidra/Framework/Utility/src/main/java/ghidra/util/Swing.java