Skip to content

Commit

Permalink
Fix NPE with UnitHelp.
Browse files Browse the repository at this point in the history
  • Loading branch information
asvitkine committed Sep 20, 2023
1 parent 1b4ffaa commit 5c6180a
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
import static com.google.common.base.Preconditions.checkState;

import com.google.common.base.Throwables;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Supplier;
import javax.annotation.Nullable;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import lombok.Getter;
import lombok.experimental.UtilityClass;
import org.triplea.java.Interruptibles;
import org.triplea.java.function.ThrowingSupplier;
Expand All @@ -19,7 +22,7 @@
/** Provides methods for running tasks in the background to avoid blocking the UI. */
@UtilityClass
public final class BackgroundTaskRunner {
private static JFrame mainFrame;
@Getter private static JFrame mainFrame;

public static void setMainFrame(final JFrame mainFrame) {
checkState(BackgroundTaskRunner.mainFrame == null);
Expand Down Expand Up @@ -72,7 +75,16 @@ public static void runInBackground(final String message, final Runnable backgrou
*/
public static <T> T runInBackgroundAndReturn(
final String message, final Supplier<T> backgroundAction) throws InterruptedException {
return runInBackgroundAndReturn(message, backgroundAction::get, RuntimeException.class);
return runInBackgroundAndReturn(message, backgroundAction::get, null, RuntimeException.class);
}

public static <T> T runInBackgroundAndReturn(
Consumer<T> runOnEdtBeforeDialogClose,
final String message,
final Supplier<T> backgroundAction)
throws InterruptedException {
return runInBackgroundAndReturn(
message, backgroundAction::get, runOnEdtBeforeDialogClose, RuntimeException.class);
}

/**
Expand All @@ -88,6 +100,9 @@ public static <T> T runInBackgroundAndReturn(
* @param <E> The type of exception thrown by the background action.
* @param message The message displayed to the user while the background action is running.
* @param backgroundAction The action to run in the background.
* @param runOnEdtBeforeDialogClose Work to be done on EDT with the result, before closing the
* dialog. Some Swing operations can be slow (e.g. layout of lots of HTML like unit help), so
* this can be used to ensure we only close the progress dialog once this work has been done.
* @param exceptionType The type of exception thrown by the background action.
* @return The value returned by {@code backgroundAction}.
* @throws IllegalStateException If this method is not called from the EDT.
Expand All @@ -98,6 +113,7 @@ public static <T> T runInBackgroundAndReturn(
public static <T, E extends Exception> T runInBackgroundAndReturn(
final String message,
final ThrowingSupplier<T, E> backgroundAction,
final Consumer<T> runOnEdtBeforeDialogClose,
final Class<E> exceptionType)
throws E, InterruptedException {
checkState(SwingUtilities.isEventDispatchThread());
Expand All @@ -117,16 +133,18 @@ protected T doInBackground() throws Exception {

@Override
protected void done() {
waitDialog.setVisible(false);
waitDialog.dispose();

try {
resultRef.set(get());
T t = get();
resultRef.set(t);
Optional.ofNullable(runOnEdtBeforeDialogClose).ifPresent(c -> c.accept(t));
} catch (final ExecutionException e) {
exceptionRef.set(e.getCause());
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
exceptionRef.set(e);
} finally {
waitDialog.setVisible(false);
waitDialog.dispose();
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import games.strategy.engine.data.GameData;
import games.strategy.engine.framework.ui.background.BackgroundTaskRunner;
import games.strategy.engine.framework.ui.background.WaitDialog;
import games.strategy.triplea.ui.UiContext;
import java.awt.Dimension;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JDialog;
Expand All @@ -20,21 +22,26 @@ class UnitHelpMenu {
Action buildMenu(final GameData gameData, final UiContext uiContext) {
return SwingAction.of(
unitHelpTitle,
e -> {
final Result<JDialog> result =
Interruptibles.awaitResult(
() ->
BackgroundTaskRunner.runInBackgroundAndReturn(
"Calculating Data",
() -> {
String text = UnitStatsTable.getUnitStatsTable(gameData, uiContext);
JEditorPane editorPane = new JEditorPane("text/html", text);
editorPane.setEditable(false);
JScrollPane scroll = new JScrollPane(editorPane);
scroll.setBorder(BorderFactory.createEmptyBorder());
return InformationDialog.createDialog(scroll, unitHelpTitle);
}));
result.result.orElseThrow().setVisible(true);
event -> {
try {
BackgroundTaskRunner.runInBackgroundAndReturn(
UnitHelpMenu::showDialog,
"Calculating Data",
() -> UnitStatsTable.getUnitStatsTable(gameData, uiContext));
} catch (InterruptedException e) {
// Nothing to do.
}
});
}

private static void showDialog(String text) {
final JEditorPane editorPane = new JEditorPane();
editorPane.setContentType("text/html");
editorPane.setEditable(false);
final JScrollPane scroll = new JScrollPane(editorPane);
scroll.setBorder(BorderFactory.createEmptyBorder());
editorPane.setText(text);
editorPane.setCaretPosition(0);
InformationDialog.createDialog(scroll, unitHelpTitle).setVisible(true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ private void forgotPassword(final ForgotPasswordPanel panel) {
.username(panel.getUserName())
.email(panel.getEmail())
.build()),
null,
IOException.class)
.getResponseMessage();
DialogBuilder.builder()
Expand Down

0 comments on commit 5c6180a

Please sign in to comment.