public File askDirectory(final String title, final String approveButtonText)
			throws CancelledException {

		String key = join(title, approveButtonText);
		File existingValue = loadAskValue(this::parseDirectory, key);
		if (isRunningHeadless()) {
			return existingValue;
		}

		File choice = doAsk(DIRECTORY.class, title, approveButtonText, existingValue, lastValue -> {

			GhidraFileChooser chooser = new GhidraFileChooser(null);
			chooser.setSelectedFile(lastValue);
			chooser.setTitle(title);
			chooser.setApproveButtonText(approveButtonText);
			chooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY);
			File file = chooser.getSelectedFile();
			chooser.dispose();
			if (chooser.wasCancelled()) {
				throw new CancelledException();
			}

			return file;
		});

		return choice;
	}
Returns a directory File object, using the String parameters for guidance. The actual
behavior of the method depends on your environment, which can be GUI or headless.
<p>
Regardless of environment -- if script arguments have been set, this method will use the
next argument in the array and advance the array index so the next call to an ask method
will get the next argument.  If there are no script arguments and a .properties file
sharing the same base name as the Ghidra Script exists (i.e., Script1.properties for
Script1.java), then this method will then look there for the String value to return.
The method will look in the .properties file by searching for a property name that is a
space-separated concatenation of the input String parameters (title + " " + approveButtonText).
If that property name exists and its value represents a valid <b>absolute path</b> of a valid
directory File, then the .properties value will be used in the following way:
<ol>
		<li>In the GUI environment, this method displays a file chooser dialog that allows the
			user to select a directory. If the file chooser dialog has been run before in the
			same session, the directory selection will be pre-populated with the last-selected
			directory. If not, the directory selection will be pre-populated with the
			.properties	value (if it exists).</li>
		<li>In the headless environment, this method returns a directory File representing
			the .properties value (if it exists), or throws an Exception if there is an invalid
			or missing .properties value.</li>
</ol>

@param title the title of the dialog (in GUI mode) or the first part of the variable name
			(in headless mode or when using .properties file)
@param approveButtonText the approve button text (in GUI mode - typically, this would be
			"Open" or "Save") or the second part of the variable name (in headless mode or
			when using .properties file)
@return the selected directory or null if no tool was available
@throws CancelledException if the user hit the 'cancel' button in GUI mode
@throws IllegalArgumentException if in headless mode, there was a missing or invalid
				directory name specified in the .properties file
Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java