added PerMainWindowInjector

master
Stefan Dollase 2017-02-24 19:43:13 +01:00
parent 0e9e935fca
commit 0968c20de4
11 changed files with 515 additions and 402 deletions

View File

@ -7,6 +7,7 @@ import amidst.documentation.CalledOnlyBy;
import amidst.documentation.NotThreadSafe;
import amidst.gui.license.LicenseWindow;
import amidst.gui.main.MainWindow;
import amidst.gui.main.MainWindowDialogs;
import amidst.gui.main.UpdatePrompt;
import amidst.gui.profileselect.ProfileSelectWindow;
import amidst.mojangapi.MojangApi;
@ -14,7 +15,7 @@ import amidst.mojangapi.MojangApi;
@NotThreadSafe
public class Application {
private final MojangApi mojangApi;
private final Factory1<MainWindow, UpdatePrompt> noisyUpdatePromptFactory;
private final Factory1<MainWindowDialogs, UpdatePrompt> noisyUpdatePromptFactory;
private final Factory0<UpdatePrompt> silentUpdatePromptFactory;
private final Factory0<MainWindow> mainWindowFactory;
private final Factory0<ProfileSelectWindow> profileSelectWindowFactory;
@ -26,7 +27,7 @@ public class Application {
@CalledOnlyBy(AmidstThread.EDT)
public Application(
MojangApi mojangApi,
Factory1<MainWindow, UpdatePrompt> noisyUpdatePromptFactory,
Factory1<MainWindowDialogs, UpdatePrompt> noisyUpdatePromptFactory,
Factory0<UpdatePrompt> silentUpdatePromptFactory,
Factory0<MainWindow> mainWindowFactory,
Factory0<ProfileSelectWindow> profileSelectWindowFactory,
@ -50,8 +51,8 @@ public class Application {
}
@CalledOnlyBy(AmidstThread.EDT)
public void checkForUpdates(MainWindow mainWindow) {
noisyUpdatePromptFactory.create(mainWindow).check();
public void checkForUpdates(MainWindowDialogs dialogs) {
noisyUpdatePromptFactory.create(dialogs).check();
}
@CalledOnlyBy(AmidstThread.EDT)

View File

@ -12,6 +12,7 @@ import amidst.fragment.layer.LayerBuilder;
import amidst.gui.license.LicenseWindow;
import amidst.gui.main.Actions;
import amidst.gui.main.MainWindow;
import amidst.gui.main.MainWindowDialogs;
import amidst.gui.main.UpdatePrompt;
import amidst.gui.main.viewer.BiomeSelection;
import amidst.gui.main.viewer.ViewerFacade;
@ -71,8 +72,8 @@ public class PerApplicationInjector {
}
@CalledOnlyBy(AmidstThread.EDT)
private UpdatePrompt createNoisyUpdatePrompt(MainWindow mainWindow) {
return UpdatePrompt.from(metadata.getVersion(), threadMaster.getWorkerExecutor(), mainWindow, false);
private UpdatePrompt createNoisyUpdatePrompt(MainWindowDialogs dialogs) {
return UpdatePrompt.from(metadata.getVersion(), threadMaster.getWorkerExecutor(), dialogs, false);
}
@CalledOnlyBy(AmidstThread.EDT)
@ -82,14 +83,14 @@ public class PerApplicationInjector {
@CalledOnlyBy(AmidstThread.EDT)
private MainWindow createMainWindow() {
return new MainWindow(
return new PerMainWindowInjector(
application,
metadata,
settings,
mojangApi,
biomeProfileDirectory,
this::createViewerFacade,
threadMaster);
threadMaster).getMainWindow();
}
@CalledOnlyBy(AmidstThread.EDT)

View File

@ -0,0 +1,106 @@
package amidst.dependency.injection;
import java.awt.Container;
import java.util.concurrent.atomic.AtomicReference;
import javax.swing.JFrame;
import amidst.AmidstMetaData;
import amidst.AmidstSettings;
import amidst.Application;
import amidst.documentation.AmidstThread;
import amidst.documentation.CalledOnlyBy;
import amidst.documentation.NotThreadSafe;
import amidst.gui.main.Actions;
import amidst.gui.main.MainWindow;
import amidst.gui.main.MainWindowDialogs;
import amidst.gui.main.WorldSwitcher;
import amidst.gui.main.menu.AmidstMenu;
import amidst.gui.main.menu.AmidstMenuBuilder;
import amidst.gui.main.viewer.ViewerFacade;
import amidst.gui.seedsearcher.SeedSearcher;
import amidst.gui.seedsearcher.SeedSearcherWindow;
import amidst.mojangapi.MojangApi;
import amidst.mojangapi.world.World;
import amidst.settings.biomeprofile.BiomeProfileDirectory;
import amidst.threading.ThreadMaster;
@NotThreadSafe
public class PerMainWindowInjector {
@CalledOnlyBy(AmidstThread.EDT)
private static String createVersionString(AmidstMetaData metadata, MojangApi mojangApi) {
return metadata.getVersion().createLongVersionString() + " - Selected Profile: " + mojangApi.getProfileName()
+ " - Minecraft Version " + mojangApi.getVersionId() + " (recognised: "
+ mojangApi.getRecognisedVersionName() + ")";
}
private final Factory2<World, Actions, ViewerFacade> viewerFacadeFactory;
private final String versionString;
private final JFrame frame;
private final Container contentPane;
private final AtomicReference<ViewerFacade> viewerFacadeReference;
private final MainWindowDialogs dialogs;
private final WorldSwitcher worldSwitcher;
private final SeedSearcher seedSearcher;
private final SeedSearcherWindow seedSearcherWindow;
private final Actions actions;
private final AmidstMenu menuBar;
private final MainWindow mainWindow;
@CalledOnlyBy(AmidstThread.EDT)
public PerMainWindowInjector(
Application application,
AmidstMetaData metadata,
AmidstSettings settings,
MojangApi mojangApi,
BiomeProfileDirectory biomeProfileDirectory,
Factory2<World, Actions, ViewerFacade> viewerFacadeFactory,
ThreadMaster threadMaster) {
this.viewerFacadeFactory = viewerFacadeFactory;
this.versionString = createVersionString(metadata, mojangApi);
this.frame = new JFrame();
this.contentPane = frame.getContentPane();
this.viewerFacadeReference = new AtomicReference<>();
this.dialogs = new MainWindowDialogs(settings, mojangApi, frame);
this.worldSwitcher = new WorldSwitcher(
mojangApi,
this::createViewerFacade,
threadMaster,
frame,
contentPane,
viewerFacadeReference,
dialogs,
this::getMenuBar);
this.seedSearcher = new SeedSearcher(dialogs, mojangApi, threadMaster.getWorkerExecutor());
this.seedSearcherWindow = new SeedSearcherWindow(metadata, dialogs, worldSwitcher, seedSearcher);
this.actions = new Actions(
application,
dialogs,
worldSwitcher,
seedSearcherWindow,
viewerFacadeReference::get,
settings.biomeProfileSelection);
this.menuBar = new AmidstMenuBuilder(settings, actions, biomeProfileDirectory).construct();
this.mainWindow = new MainWindow(frame, worldSwitcher, seedSearcherWindow);
this.mainWindow.initializeFrame(metadata, versionString, actions, menuBar);
}
@CalledOnlyBy(AmidstThread.EDT)
private ViewerFacade createViewerFacade(World world) {
return viewerFacadeFactory.create(world, actions);
}
/**
* This only exists to break the cyclic dependency between {@link #menuBar},
* {@link #actions} and {@link #worldSwitcher}.
*/
@CalledOnlyBy(AmidstThread.EDT)
private AmidstMenu getMenuBar() {
return this.menuBar;
}
@CalledOnlyBy(AmidstThread.EDT)
public MainWindow getMainWindow() {
return mainWindow;
}
}

View File

@ -8,7 +8,7 @@ import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import javax.imageio.ImageIO;
@ -19,6 +19,7 @@ import amidst.documentation.NotThreadSafe;
import amidst.gui.crash.CrashWindow;
import amidst.gui.main.menu.MovePlayerPopupMenu;
import amidst.gui.main.viewer.ViewerFacade;
import amidst.gui.seedsearcher.SeedSearcherWindow;
import amidst.logging.AmidstLogger;
import amidst.mojangapi.world.WorldSeed;
import amidst.mojangapi.world.WorldType;
@ -33,25 +34,31 @@ import amidst.util.FileExtensionChecker;
@NotThreadSafe
public class Actions {
private final Application application;
private final MainWindow mainWindow;
private final AtomicReference<ViewerFacade> viewerFacade;
private final MainWindowDialogs dialogs;
private final WorldSwitcher worldSwitcher;
private final SeedSearcherWindow seedSearcherWindow;
private final Supplier<ViewerFacade> viewerFacadeSupplier;
private final BiomeProfileSelection biomeProfileSelection;
@CalledOnlyBy(AmidstThread.EDT)
public Actions(
Application application,
MainWindow mainWindow,
AtomicReference<ViewerFacade> viewerFacade,
MainWindowDialogs dialogs,
WorldSwitcher worldSwitcher,
SeedSearcherWindow seedSearcherWindow,
Supplier<ViewerFacade> viewerFacadeSupplier,
BiomeProfileSelection biomeProfileSelection) {
this.application = application;
this.mainWindow = mainWindow;
this.viewerFacade = viewerFacade;
this.dialogs = dialogs;
this.worldSwitcher = worldSwitcher;
this.seedSearcherWindow = seedSearcherWindow;
this.viewerFacadeSupplier = viewerFacadeSupplier;
this.biomeProfileSelection = biomeProfileSelection;
}
@CalledOnlyBy(AmidstThread.EDT)
public void newFromSeed() {
WorldSeed seed = mainWindow.askForSeed();
WorldSeed seed = dialogs.askForSeed();
if (seed != null) {
newFromSeed(seed);
}
@ -64,30 +71,30 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
private void newFromSeed(WorldSeed worldSeed) {
WorldType worldType = mainWindow.askForWorldType();
WorldType worldType = dialogs.askForWorldType();
if (worldType != null) {
mainWindow.displayWorld(worldSeed, worldType);
worldSwitcher.displayWorld(worldSeed, worldType);
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void searchForRandom() {
mainWindow.displaySeedSearcherWindow();
seedSearcherWindow.show();
}
@CalledOnlyBy(AmidstThread.EDT)
public void openSaveGame() {
File file = mainWindow.askForSaveGame();
File file = dialogs.askForSaveGame();
if (file != null) {
mainWindow.displayWorld(file);
worldSwitcher.displayWorld(file);
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void export() {
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
viewerFacade.export(mainWindow.askForExportConfiguration());
viewerFacade.export(dialogs.askForExportConfiguration());
}
}
@ -103,16 +110,16 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void goToCoordinate() {
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
String input = mainWindow.askForCoordinates();
String input = dialogs.askForCoordinates();
if (input != null) {
CoordinatesInWorld coordinates = CoordinatesInWorld.tryParse(input);
if (coordinates != null) {
viewerFacade.centerOn(coordinates);
} else {
AmidstLogger.warn("Invalid location entered, ignoring.");
mainWindow.displayError("You entered an invalid location.");
dialogs.displayError("You entered an invalid location.");
}
}
}
@ -120,7 +127,7 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void goToSpawn() {
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
viewerFacade.centerOn(viewerFacade.getSpawnWorldIcon());
}
@ -128,9 +135,9 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void goToStronghold() {
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
WorldIcon stronghold = mainWindow
WorldIcon stronghold = dialogs
.askForOptions("Go to", "Select Stronghold:", viewerFacade.getStrongholdWorldIcons());
if (stronghold != null) {
viewerFacade.centerOn(stronghold);
@ -140,17 +147,17 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void goToPlayer() {
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
List<WorldIcon> playerWorldIcons = viewerFacade.getPlayerWorldIcons();
if (!playerWorldIcons.isEmpty()) {
WorldIcon player = mainWindow.askForOptions("Go to", "Select player:", playerWorldIcons);
WorldIcon player = dialogs.askForOptions("Go to", "Select player:", playerWorldIcons);
if (player != null) {
viewerFacade.centerOn(player);
}
} else {
AmidstLogger.warn("There are no players in this world.");
mainWindow.displayError("There are no players in this world.");
dialogs.displayError("There are no players in this world.");
}
}
}
@ -167,9 +174,9 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void savePlayerLocations() {
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
if (mainWindow.askToConfirmSaveGameManipulation()) {
if (dialogs.askToConfirmSaveGameManipulation()) {
viewerFacade.savePlayerLocations();
}
}
@ -177,7 +184,7 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void reloadPlayerLocations() {
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
viewerFacade.loadPlayers();
}
@ -185,7 +192,7 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void howCanIMoveAPlayer() {
mainWindow.displayInfo(
dialogs.displayInfo(
"How can I move a player?",
"If you load the world from a save game, you can change the player locations.\n"
+ "1. Scroll the map to and right-click on the new player location, this opens a popup menu.\n"
@ -195,7 +202,7 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void copySeedToClipboard() {
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
String seed = "" + viewerFacade.getWorldSeed().getLong();
StringSelection selection = new StringSelection(seed);
@ -205,25 +212,25 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void saveCaptureImage() {
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
BufferedImage image = viewerFacade.createCaptureImage();
String suggestedFilename = "screenshot_" + viewerFacade.getWorldType().getFilenameText() + "_"
+ viewerFacade.getWorldSeed().getLong() + ".png";
File file = mainWindow.askForCaptureImageSaveFile(suggestedFilename);
File file = dialogs.askForCaptureImageSaveFile(suggestedFilename);
if (file != null) {
file = appendPNGFileExtensionIfNecessary(file);
if (file.exists() && !file.isFile()) {
String message = "Unable to write capture image, because the target exists but is not a file: "
+ file.getAbsolutePath();
AmidstLogger.warn(message);
mainWindow.displayError(message);
dialogs.displayError(message);
} else if (!canWriteToFile(file)) {
String message = "Unable to write capture image, because you have no writing permissions: "
+ file.getAbsolutePath();
AmidstLogger.warn(message);
mainWindow.displayError(message);
} else if (!file.exists() || mainWindow.askToConfirmYesNo(
dialogs.displayError(message);
} else if (!file.exists() || dialogs.askToConfirmYesNo(
"Replace file?",
"File already exists. Do you want to replace it?\n" + file.getAbsolutePath() + "")) {
saveImageToFile(image, file);
@ -236,7 +243,7 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void selectBiomeProfile(BiomeProfile profile) {
biomeProfileSelection.set(profile);
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
viewerFacade.reloadBackgroundLayer();
}
@ -249,7 +256,7 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void checkForUpdates() {
application.checkForUpdates(mainWindow);
application.checkForUpdates(dialogs);
}
@CalledOnlyBy(AmidstThread.EDT)
@ -259,7 +266,7 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void about() {
mainWindow.displayInfo(
dialogs.displayInfo(
"About",
"Amidst - Advanced Minecraft Interfacing and Data/Structure Tracking\n\n"
+ "Author: Skidoodle aka skiphs\n" + "Mail: toolbox4minecraft+amidst@gmail.com\n"
@ -268,7 +275,7 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
private void adjustZoom(int notches) {
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
viewerFacade.adjustZoom(notches);
}
@ -276,7 +283,7 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void adjustZoom(Point mousePosition, int notches) {
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
viewerFacade.adjustZoom(mousePosition, notches);
}
@ -284,7 +291,7 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void selectWorldIcon(WorldIcon worldIcon) {
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
viewerFacade.selectWorldIcon(worldIcon);
}
@ -292,7 +299,7 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void showPlayerPopupMenu(CoordinatesInWorld targetCoordinates, Component component, int x, int y) {
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
if (viewerFacade.canSavePlayerLocations()) {
new MovePlayerPopupMenu(this, viewerFacade.getMovablePlayerList(), targetCoordinates)
@ -303,17 +310,16 @@ public class Actions {
@CalledOnlyBy(AmidstThread.EDT)
public void movePlayer(Player player, CoordinatesInWorld targetCoordinates) {
ViewerFacade viewerFacade = this.viewerFacade.get();
ViewerFacade viewerFacade = viewerFacadeSupplier.get();
if (viewerFacade != null) {
PlayerCoordinates currentCoordinates = player.getPlayerCoordinates();
long currentHeight = currentCoordinates.getY();
String input = mainWindow.askForPlayerHeight(currentHeight);
String input = dialogs.askForPlayerHeight(currentHeight);
if (input != null) {
player.moveTo(targetCoordinates, tryParseLong(input, currentHeight), currentCoordinates.getDimension());
viewerFacade.reloadPlayerLayer();
if (mainWindow
.askToConfirmYesNo("Save Player Locations", "Do you want to save the player locations?")) {
if (mainWindow.askToConfirmSaveGameManipulation()) {
if (dialogs.askToConfirmYesNo("Save Player Locations", "Do you want to save the player locations?")) {
if (dialogs.askToConfirmSaveGameManipulation()) {
viewerFacade.savePlayerLocations();
}
}
@ -342,7 +348,7 @@ public class Actions {
ImageIO.write(image, "png", file);
} catch (IOException e) {
AmidstLogger.warn(e);
mainWindow.displayError(e);
dialogs.displayError(e);
}
}

View File

@ -1,372 +1,52 @@
package amidst.gui.main;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import amidst.AmidstMetaData;
import amidst.AmidstSettings;
import amidst.Application;
import amidst.dependency.injection.Factory2;
import amidst.documentation.AmidstThread;
import amidst.documentation.CalledOnlyBy;
import amidst.documentation.NotThreadSafe;
import amidst.gui.main.menu.AmidstMenu;
import amidst.gui.main.menu.AmidstMenuBuilder;
import amidst.gui.main.viewer.ViewerFacade;
import amidst.gui.seedsearcher.SeedSearcher;
import amidst.gui.seedsearcher.SeedSearcherWindow;
import amidst.logging.AmidstLogger;
import amidst.logging.AmidstMessageBox;
import amidst.mojangapi.MojangApi;
import amidst.mojangapi.file.MojangApiParsingException;
import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException;
import amidst.mojangapi.world.World;
import amidst.mojangapi.world.WorldSeed;
import amidst.mojangapi.world.WorldType;
import amidst.mojangapi.world.export.WorldExporterConfiguration;
import amidst.mojangapi.world.player.MovablePlayerList;
import amidst.mojangapi.world.player.WorldPlayerType;
import amidst.settings.biomeprofile.BiomeProfileDirectory;
import amidst.threading.ThreadMaster;
@NotThreadSafe
public class MainWindow {
private final Application application;
private final AmidstMetaData metadata;
private final AmidstSettings settings;
private final MojangApi mojangApi;
private final BiomeProfileDirectory biomeProfileDirectory;
private final Factory2<World, Actions, ViewerFacade> viewerFacadeFactory;
private final ThreadMaster threadMaster;
private final JFrame frame;
private final Container contentPane;
private final Actions actions;
private final AmidstMenu menuBar;
private final WorldSwitcher worldSwitcher;
private final SeedSearcherWindow seedSearcherWindow;
private final AtomicReference<ViewerFacade> viewerFacade = new AtomicReference<>();
@CalledOnlyBy(AmidstThread.EDT)
public MainWindow(
Application application,
AmidstMetaData metadata,
AmidstSettings settings,
MojangApi mojangApi,
BiomeProfileDirectory biomeProfileDirectory,
Factory2<World, Actions, ViewerFacade> viewerFacadeFactory,
ThreadMaster threadMaster) {
this.application = application;
this.metadata = metadata;
this.settings = settings;
this.mojangApi = mojangApi;
this.biomeProfileDirectory = biomeProfileDirectory;
this.viewerFacadeFactory = viewerFacadeFactory;
this.threadMaster = threadMaster;
this.frame = createFrame();
this.contentPane = createContentPane();
this.actions = createActions();
this.menuBar = createMenuBar();
this.seedSearcherWindow = createSeedSearcherWindow();
initCloseListener();
showFrame();
clearViewerFacade();
public MainWindow(JFrame frame, WorldSwitcher worldSwitcher, SeedSearcherWindow seedSearcherWindow) {
this.frame = frame;
this.worldSwitcher = worldSwitcher;
this.seedSearcherWindow = seedSearcherWindow;
}
@CalledOnlyBy(AmidstThread.EDT)
private JFrame createFrame() {
JFrame frame = new JFrame();
frame.setTitle(
createVersionString(
mojangApi.getVersionId(),
mojangApi.getRecognisedVersionName(),
mojangApi.getProfileName()));
public void initializeFrame(AmidstMetaData metadata, String versionString, Actions actions, AmidstMenu menuBar) {
frame.setSize(1000, 800);
frame.setIconImages(metadata.getIcons());
return frame;
}
@CalledOnlyBy(AmidstThread.EDT)
private String createVersionString(String versionId, String recognisedVersionName, String profileName) {
return metadata.getVersion().createLongVersionString() + " - Selected Profile: " + profileName
+ " - Minecraft Version " + versionId + " (recognised: " + recognisedVersionName + ")";
}
@CalledOnlyBy(AmidstThread.EDT)
private Container createContentPane() {
Container contentPane = frame.getContentPane();
contentPane.setLayout(new BorderLayout());
return contentPane;
}
@CalledOnlyBy(AmidstThread.EDT)
private Actions createActions() {
return new Actions(application, this, viewerFacade, settings.biomeProfileSelection);
}
@CalledOnlyBy(AmidstThread.EDT)
private AmidstMenu createMenuBar() {
AmidstMenu menuBar = new AmidstMenuBuilder(settings, actions, biomeProfileDirectory).construct();
frame.setTitle(versionString);
frame.setJMenuBar(menuBar.getMenuBar());
return menuBar;
}
@CalledOnlyBy(AmidstThread.EDT)
private SeedSearcherWindow createSeedSearcherWindow() {
return new SeedSearcherWindow(
metadata,
this,
new SeedSearcher(this, mojangApi, threadMaster.getWorkerExecutor()));
}
@CalledOnlyBy(AmidstThread.EDT)
private void initCloseListener() {
frame.getContentPane().setLayout(new BorderLayout());
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
actions.exit();
}
});
}
@CalledOnlyBy(AmidstThread.EDT)
private void showFrame() {
frame.setVisible(true);
}
@CalledOnlyBy(AmidstThread.EDT)
public void displayWorld(WorldSeed worldSeed, WorldType worldType) {
try {
setWorld(mojangApi.createWorldFromSeed(worldSeed, worldType));
} catch (IllegalStateException | MinecraftInterfaceException e) {
AmidstLogger.warn(e);
displayError(e);
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void displayWorld(File file) {
try {
setWorld(mojangApi.createWorldFromSaveGame(file));
} catch (IllegalStateException | MinecraftInterfaceException | IOException | MojangApiParsingException e) {
AmidstLogger.warn(e);
displayError(e);
}
}
@CalledOnlyBy(AmidstThread.EDT)
private void setWorld(World world) {
clearViewerFacade();
if (decideWorldPlayerType(world.getMovablePlayerList())) {
setViewerFacade(viewerFacadeFactory.create(world, actions));
} else {
frame.revalidate();
frame.repaint();
}
}
@CalledOnlyBy(AmidstThread.EDT)
private boolean decideWorldPlayerType(MovablePlayerList movablePlayerList) {
if (movablePlayerList.getWorldPlayerType().equals(WorldPlayerType.BOTH)) {
WorldPlayerType worldPlayerType = askForWorldPlayerType();
if (worldPlayerType != null) {
movablePlayerList.setWorldPlayerType(worldPlayerType);
return true;
} else {
return false;
}
} else {
return true;
}
}
@CalledOnlyBy(AmidstThread.EDT)
private void setViewerFacade(ViewerFacade viewerFacade) {
contentPane.add(viewerFacade.getComponent(), BorderLayout.CENTER);
menuBar.set(viewerFacade);
frame.validate();
viewerFacade.loadPlayers();
threadMaster.setOnRepaintTick(viewerFacade.getOnRepainterTick());
threadMaster.setOnFragmentLoadTick(viewerFacade.getOnFragmentLoaderTick());
this.viewerFacade.set(viewerFacade);
}
@CalledOnlyBy(AmidstThread.EDT)
private void clearViewerFacade() {
threadMaster.clearOnRepaintTick();
threadMaster.clearOnFragmentLoadTick();
ViewerFacade viewerFacade = this.viewerFacade.getAndSet(null);
if (viewerFacade != null) {
contentPane.remove(viewerFacade.getComponent());
viewerFacade.dispose();
}
menuBar.clear();
worldSwitcher.clearWorld();
}
@CalledOnlyBy(AmidstThread.EDT)
public void dispose() {
clearViewerFacade();
worldSwitcher.clearWorld();
seedSearcherWindow.dispose();
frame.dispose();
}
@CalledOnlyBy(AmidstThread.EDT)
private WorldPlayerType askForWorldPlayerType() {
return askForOptions(
"Loading World",
"This world contains Multiplayer and Singleplayer data. What do you want to load?\n"
+ "If you do not know what to do, just choose Singleplayer.",
WorldPlayerType.getSelectable());
}
@CalledOnlyBy(AmidstThread.EDT)
public WorldSeed askForSeed() {
return new SeedPrompt(frame).askForSeed();
}
@CalledOnlyBy(AmidstThread.EDT)
public File askForSaveGame() {
return showOpenDialogAndGetSelectedFileOrNull(createSaveGameFileChooser());
}
@CalledOnlyBy(AmidstThread.EDT)
private JFileChooser createSaveGameFileChooser() {
JFileChooser result = new JFileChooser(mojangApi.getSaves());
result.setFileFilter(new LevelFileFilter());
result.setAcceptAllFileFilterUsed(false);
result.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
result.setFileHidingEnabled(false);
return result;
}
@CalledOnlyBy(AmidstThread.EDT)
private File showOpenDialogAndGetSelectedFileOrNull(JFileChooser fileChooser) {
if (fileChooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
return fileChooser.getSelectedFile();
} else {
return null;
}
}
@CalledOnlyBy(AmidstThread.EDT)
public File askForCaptureImageSaveFile(String suggestedFilename) {
return showSaveDialogAndGetSelectedFileOrNull(createCaptureImageSaveFileChooser(suggestedFilename));
}
@CalledOnlyBy(AmidstThread.EDT)
private JFileChooser createCaptureImageSaveFileChooser(String suggestedFilename) {
JFileChooser result = new JFileChooser();
result.setFileFilter(new PNGFileFilter());
result.setAcceptAllFileFilterUsed(false);
result.setSelectedFile(new File(suggestedFilename));
return result;
}
@CalledOnlyBy(AmidstThread.EDT)
private File showSaveDialogAndGetSelectedFileOrNull(JFileChooser fileChooser) {
if (fileChooser.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
return fileChooser.getSelectedFile();
} else {
return null;
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void displayInfo(String title, String message) {
AmidstMessageBox.displayInfo(frame, title, message);
}
@CalledOnlyBy(AmidstThread.EDT)
public void displayError(String message) {
AmidstMessageBox.displayError(frame, "Error", message);
}
@CalledOnlyBy(AmidstThread.EDT)
public void displayError(Exception e) {
AmidstMessageBox.displayError(frame, "Error", e);
}
@CalledOnlyBy(AmidstThread.EDT)
public boolean askToConfirmSaveGameManipulation() {
return askToConfirmYesNo(
"Save Game Manipulation",
"WARNING: You are about to change the contents of the save game directory. There is a chance that it gets corrupted.\n"
+ "We try to minimize the risk by creating a backup of the changed file, before it is changed.\n"
+ "If the backup fails, we will not write the changes.\n"
+ "You can find the backup files in the directory 'amidst/backup', which is placed in the save game directory.\n"
+ "Especially, make sure to not have the save game loaded in Minecraft during this process.\n\n"
+ "Do you want to proceed?");
}
@CalledOnlyBy(AmidstThread.EDT)
public boolean askToConfirmYesNo(String title, String message) {
return AmidstMessageBox.askToConfirmYesNo(frame, title, message);
}
@CalledOnlyBy(AmidstThread.EDT)
public WorldType askForWorldType() {
String worldTypeSetting = settings.worldType.get();
if (worldTypeSetting.equals(WorldType.PROMPT_EACH_TIME)) {
return askForOptions("World Type", "Enter world type\n", WorldType.getSelectable());
} else {
return WorldType.from(worldTypeSetting);
}
}
@CalledOnlyBy(AmidstThread.EDT)
@SuppressWarnings("unchecked")
public <T> T askForOptions(String title, String message, List<T> choices) {
Object[] choicesArray = choices.toArray();
return (T) JOptionPane
.showInputDialog(frame, message, title, JOptionPane.PLAIN_MESSAGE, null, choicesArray, choicesArray[0]);
}
@CalledOnlyBy(AmidstThread.EDT)
public String askForCoordinates() {
return askForString("Go To", "Enter coordinates: (Ex. 123,456)");
}
@CalledOnlyBy(AmidstThread.EDT)
public String askForPlayerHeight(long currentHeight) {
Object input = JOptionPane.showInputDialog(
frame,
"Enter new player height:",
"Move Player",
JOptionPane.QUESTION_MESSAGE,
null,
null,
currentHeight);
if (input != null) {
return input.toString();
} else {
return null;
}
}
@CalledOnlyBy(AmidstThread.EDT)
private String askForString(String title, String message) {
return JOptionPane.showInputDialog(frame, message, title, JOptionPane.QUESTION_MESSAGE);
}
@CalledOnlyBy(AmidstThread.EDT)
public void displaySeedSearcherWindow() {
seedSearcherWindow.show();
}
@CalledOnlyBy(AmidstThread.EDT)
public WorldExporterConfiguration askForExportConfiguration() {
// TODO: implement me!
// TODO: display gui to create configuration
return new WorldExporterConfiguration();
}
}

View File

@ -0,0 +1,178 @@
package amidst.gui.main;
import java.io.File;
import java.util.List;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import amidst.AmidstSettings;
import amidst.documentation.AmidstThread;
import amidst.documentation.CalledOnlyBy;
import amidst.documentation.NotThreadSafe;
import amidst.logging.AmidstMessageBox;
import amidst.mojangapi.MojangApi;
import amidst.mojangapi.world.WorldSeed;
import amidst.mojangapi.world.WorldType;
import amidst.mojangapi.world.export.WorldExporterConfiguration;
import amidst.mojangapi.world.player.WorldPlayerType;
@NotThreadSafe
public class MainWindowDialogs {
private final AmidstSettings settings;
private final MojangApi mojangApi;
private final JFrame frame;
@CalledOnlyBy(AmidstThread.EDT)
public MainWindowDialogs(AmidstSettings settings, MojangApi mojangApi, JFrame frame) {
this.settings = settings;
this.mojangApi = mojangApi;
this.frame = frame;
}
@CalledOnlyBy(AmidstThread.EDT)
public WorldPlayerType askForWorldPlayerType() {
return askForOptions(
"Loading World",
"This world contains Multiplayer and Singleplayer data. What do you want to load?\n"
+ "If you do not know what to do, just choose Singleplayer.",
WorldPlayerType.getSelectable());
}
@CalledOnlyBy(AmidstThread.EDT)
public WorldSeed askForSeed() {
return new SeedPrompt(frame).askForSeed();
}
@CalledOnlyBy(AmidstThread.EDT)
public File askForSaveGame() {
return showOpenDialogAndGetSelectedFileOrNull(createSaveGameFileChooser());
}
@CalledOnlyBy(AmidstThread.EDT)
private JFileChooser createSaveGameFileChooser() {
JFileChooser result = new JFileChooser(mojangApi.getSaves());
result.setFileFilter(new LevelFileFilter());
result.setAcceptAllFileFilterUsed(false);
result.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
result.setFileHidingEnabled(false);
return result;
}
@CalledOnlyBy(AmidstThread.EDT)
private File showOpenDialogAndGetSelectedFileOrNull(JFileChooser fileChooser) {
if (fileChooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
return fileChooser.getSelectedFile();
} else {
return null;
}
}
@CalledOnlyBy(AmidstThread.EDT)
public File askForCaptureImageSaveFile(String suggestedFilename) {
return showSaveDialogAndGetSelectedFileOrNull(createCaptureImageSaveFileChooser(suggestedFilename));
}
@CalledOnlyBy(AmidstThread.EDT)
private JFileChooser createCaptureImageSaveFileChooser(String suggestedFilename) {
JFileChooser result = new JFileChooser();
result.setFileFilter(new PNGFileFilter());
result.setAcceptAllFileFilterUsed(false);
result.setSelectedFile(new File(suggestedFilename));
return result;
}
@CalledOnlyBy(AmidstThread.EDT)
private File showSaveDialogAndGetSelectedFileOrNull(JFileChooser fileChooser) {
if (fileChooser.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
return fileChooser.getSelectedFile();
} else {
return null;
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void displayInfo(String title, String message) {
AmidstMessageBox.displayInfo(frame, title, message);
}
@CalledOnlyBy(AmidstThread.EDT)
public void displayError(String message) {
AmidstMessageBox.displayError(frame, "Error", message);
}
@CalledOnlyBy(AmidstThread.EDT)
public void displayError(Exception e) {
AmidstMessageBox.displayError(frame, "Error", e);
}
@CalledOnlyBy(AmidstThread.EDT)
public boolean askToConfirmSaveGameManipulation() {
return askToConfirmYesNo(
"Save Game Manipulation",
"WARNING: You are about to change the contents of the save game directory. There is a chance that it gets corrupted.\n"
+ "We try to minimize the risk by creating a backup of the changed file, before it is changed.\n"
+ "If the backup fails, we will not write the changes.\n"
+ "You can find the backup files in the directory 'amidst/backup', which is placed in the save game directory.\n"
+ "Especially, make sure to not have the save game loaded in Minecraft during this process.\n\n"
+ "Do you want to proceed?");
}
@CalledOnlyBy(AmidstThread.EDT)
public boolean askToConfirmYesNo(String title, String message) {
return AmidstMessageBox.askToConfirmYesNo(frame, title, message);
}
@CalledOnlyBy(AmidstThread.EDT)
public WorldType askForWorldType() {
String worldTypeSetting = settings.worldType.get();
if (worldTypeSetting.equals(WorldType.PROMPT_EACH_TIME)) {
return askForOptions("World Type", "Enter world type\n", WorldType.getSelectable());
} else {
return WorldType.from(worldTypeSetting);
}
}
@CalledOnlyBy(AmidstThread.EDT)
@SuppressWarnings("unchecked")
public <T> T askForOptions(String title, String message, List<T> choices) {
Object[] choicesArray = choices.toArray();
return (T) JOptionPane
.showInputDialog(frame, message, title, JOptionPane.PLAIN_MESSAGE, null, choicesArray, choicesArray[0]);
}
@CalledOnlyBy(AmidstThread.EDT)
public String askForCoordinates() {
return askForString("Go To", "Enter coordinates: (Ex. 123,456)");
}
@CalledOnlyBy(AmidstThread.EDT)
public String askForPlayerHeight(long currentHeight) {
Object input = JOptionPane.showInputDialog(
frame,
"Enter new player height:",
"Move Player",
JOptionPane.QUESTION_MESSAGE,
null,
null,
currentHeight);
if (input != null) {
return input.toString();
} else {
return null;
}
}
@CalledOnlyBy(AmidstThread.EDT)
private String askForString(String title, String message) {
return JOptionPane.showInputDialog(frame, message, title, JOptionPane.QUESTION_MESSAGE);
}
@CalledOnlyBy(AmidstThread.EDT)
public WorldExporterConfiguration askForExportConfiguration() {
// TODO: implement me!
// TODO: display gui to create configuration
return new WorldExporterConfiguration();
}
}

View File

@ -23,23 +23,23 @@ public class UpdatePrompt {
public static UpdatePrompt from(
AmidstVersion currentVersion,
WorkerExecutor workerExecutor,
MainWindow mainWindow,
MainWindowDialogs dialogs,
boolean silent) {
if (mainWindow != null) {
if (dialogs != null) {
if (silent) {
return new UpdatePrompt(
currentVersion,
workerExecutor,
NOOP_CONSUMER,
NOOP,
message -> mainWindow.askToConfirmYesNo(TITLE, message));
message -> dialogs.askToConfirmYesNo(TITLE, message));
} else {
return new UpdatePrompt(
currentVersion,
workerExecutor,
e -> mainWindow.displayError(e),
() -> mainWindow.displayInfo(TITLE, NO_UPDATES_AVAILABLE),
message -> mainWindow.askToConfirmYesNo(TITLE, message));
e -> dialogs.displayError(e),
() -> dialogs.displayInfo(TITLE, NO_UPDATES_AVAILABLE),
message -> dialogs.askToConfirmYesNo(TITLE, message));
}
} else {
if (silent) {

View File

@ -0,0 +1,133 @@
package amidst.gui.main;
import java.awt.BorderLayout;
import java.awt.Container;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import javax.swing.JFrame;
import amidst.dependency.injection.Factory1;
import amidst.documentation.AmidstThread;
import amidst.documentation.CalledOnlyBy;
import amidst.documentation.NotThreadSafe;
import amidst.gui.main.menu.AmidstMenu;
import amidst.gui.main.viewer.ViewerFacade;
import amidst.logging.AmidstLogger;
import amidst.mojangapi.MojangApi;
import amidst.mojangapi.file.MojangApiParsingException;
import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException;
import amidst.mojangapi.world.World;
import amidst.mojangapi.world.WorldSeed;
import amidst.mojangapi.world.WorldType;
import amidst.mojangapi.world.player.MovablePlayerList;
import amidst.mojangapi.world.player.WorldPlayerType;
import amidst.threading.ThreadMaster;
@NotThreadSafe
public class WorldSwitcher {
private final MojangApi mojangApi;
private final Factory1<World, ViewerFacade> viewerFacadeFactory;
private final ThreadMaster threadMaster;
private final JFrame frame;
private final Container contentPane;
private final AtomicReference<ViewerFacade> viewerFacadeReference;
private final MainWindowDialogs dialogs;
private final Supplier<AmidstMenu> menuBarSupplier;
@CalledOnlyBy(AmidstThread.EDT)
public WorldSwitcher(
MojangApi mojangApi,
Factory1<World, ViewerFacade> viewerFacadeFactory,
ThreadMaster threadMaster,
JFrame frame,
Container contentPane,
AtomicReference<ViewerFacade> viewerFacadeReference,
MainWindowDialogs dialogs,
Supplier<AmidstMenu> menuBarSupplier) {
this.mojangApi = mojangApi;
this.viewerFacadeFactory = viewerFacadeFactory;
this.threadMaster = threadMaster;
this.frame = frame;
this.contentPane = contentPane;
this.viewerFacadeReference = viewerFacadeReference;
this.dialogs = dialogs;
this.menuBarSupplier = menuBarSupplier;
}
@CalledOnlyBy(AmidstThread.EDT)
public void displayWorld(WorldSeed worldSeed, WorldType worldType) {
try {
setWorld(mojangApi.createWorldFromSeed(worldSeed, worldType));
} catch (IllegalStateException | MinecraftInterfaceException e) {
AmidstLogger.warn(e);
dialogs.displayError(e);
}
}
@CalledOnlyBy(AmidstThread.EDT)
public void displayWorld(File file) {
try {
setWorld(mojangApi.createWorldFromSaveGame(file));
} catch (IllegalStateException | MinecraftInterfaceException | IOException | MojangApiParsingException e) {
AmidstLogger.warn(e);
dialogs.displayError(e);
}
}
@CalledOnlyBy(AmidstThread.EDT)
private void setWorld(World world) {
clearViewerFacade();
if (decideWorldPlayerType(world.getMovablePlayerList())) {
setViewerFacade(viewerFacadeFactory.create(world));
} else {
frame.revalidate();
frame.repaint();
}
}
@CalledOnlyBy(AmidstThread.EDT)
private boolean decideWorldPlayerType(MovablePlayerList movablePlayerList) {
if (movablePlayerList.getWorldPlayerType().equals(WorldPlayerType.BOTH)) {
WorldPlayerType worldPlayerType = dialogs.askForWorldPlayerType();
if (worldPlayerType != null) {
movablePlayerList.setWorldPlayerType(worldPlayerType);
return true;
} else {
return false;
}
} else {
return true;
}
}
@CalledOnlyBy(AmidstThread.EDT)
private void setViewerFacade(ViewerFacade viewerFacade) {
contentPane.add(viewerFacade.getComponent(), BorderLayout.CENTER);
menuBarSupplier.get().set(viewerFacade);
frame.validate();
viewerFacade.loadPlayers();
threadMaster.setOnRepaintTick(viewerFacade.getOnRepainterTick());
threadMaster.setOnFragmentLoadTick(viewerFacade.getOnFragmentLoaderTick());
viewerFacadeReference.set(viewerFacade);
}
@CalledOnlyBy(AmidstThread.EDT)
private void clearViewerFacade() {
threadMaster.clearOnRepaintTick();
threadMaster.clearOnFragmentLoadTick();
ViewerFacade viewerFacade = viewerFacadeReference.getAndSet(null);
if (viewerFacade != null) {
contentPane.remove(viewerFacade.getComponent());
viewerFacade.dispose();
}
menuBarSupplier.get().clear();
}
@CalledOnlyBy(AmidstThread.EDT)
public void clearWorld() {
clearViewerFacade();
}
}

View File

@ -5,7 +5,7 @@ import java.util.function.Consumer;
import amidst.documentation.AmidstThread;
import amidst.documentation.CalledOnlyBy;
import amidst.documentation.NotThreadSafe;
import amidst.gui.main.MainWindow;
import amidst.gui.main.MainWindowDialogs;
import amidst.logging.AmidstLogger;
import amidst.mojangapi.MojangApi;
import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException;
@ -17,7 +17,7 @@ import amidst.threading.worker.ProgressReportingWorker;
@NotThreadSafe
public class SeedSearcher {
private final MainWindow mainWindow;
private final MainWindowDialogs dialogs;
private final MojangApi mojangApi;
private final WorkerExecutor workerExecutor;
@ -25,8 +25,8 @@ public class SeedSearcher {
private volatile boolean isStopRequested = false;
@CalledOnlyBy(AmidstThread.EDT)
public SeedSearcher(MainWindow mainWindow, MojangApi mojangApi, WorkerExecutor workerExecutor) {
this.mainWindow = mainWindow;
public SeedSearcher(MainWindowDialogs dialogs, MojangApi mojangApi, WorkerExecutor workerExecutor) {
this.dialogs = dialogs;
this.mojangApi = mojangApi.createSilentPlayerlessCopy();
this.workerExecutor = workerExecutor;
}
@ -69,7 +69,7 @@ public class SeedSearcher {
doSearch(reporter, configuration);
} catch (IllegalStateException | MinecraftInterfaceException e) {
AmidstLogger.warn(e);
mainWindow.displayError(e);
dialogs.displayError(e);
} finally {
this.isSearching = false;
this.isStopRequested = false;

View File

@ -17,7 +17,8 @@ import amidst.AmidstMetaData;
import amidst.documentation.AmidstThread;
import amidst.documentation.CalledOnlyBy;
import amidst.documentation.NotThreadSafe;
import amidst.gui.main.MainWindow;
import amidst.gui.main.MainWindowDialogs;
import amidst.gui.main.WorldSwitcher;
import amidst.logging.AmidstLogger;
import amidst.mojangapi.file.json.filter.WorldFilterJson_MatchAll;
import amidst.mojangapi.world.WorldSeed;
@ -28,7 +29,8 @@ import net.miginfocom.swing.MigLayout;
@NotThreadSafe
public class SeedSearcherWindow {
private final AmidstMetaData metadata;
private final MainWindow mainWindow;
private final MainWindowDialogs dialogs;
private final WorldSwitcher worldSwitcher;
private final SeedSearcher seedSearcher;
private final JTextArea searchQueryTextArea;
@ -38,9 +40,14 @@ public class SeedSearcherWindow {
private final JFrame frame;
@CalledOnlyBy(AmidstThread.EDT)
public SeedSearcherWindow(AmidstMetaData metadata, MainWindow mainWindow, SeedSearcher seedSearcher) {
public SeedSearcherWindow(
AmidstMetaData metadata,
MainWindowDialogs dialogs,
WorldSwitcher worldSwitcher,
SeedSearcher seedSearcher) {
this.metadata = metadata;
this.mainWindow = mainWindow;
this.dialogs = dialogs;
this.worldSwitcher = worldSwitcher;
this.seedSearcher = seedSearcher;
this.searchQueryTextArea = createSearchQueryTextArea();
this.worldTypeComboBox = createWorldTypeComboBox();
@ -113,7 +120,7 @@ public class SeedSearcherWindow {
seedSearcher.search(seedSearcherConfiguration, worldSeed -> seedFound(worldSeed, worldType));
} else {
AmidstLogger.warn("invalid configuration");
mainWindow.displayError("invalid configuration");
dialogs.displayError("invalid configuration");
}
}
updateGUI();
@ -137,7 +144,7 @@ public class SeedSearcherWindow {
@CalledOnlyBy(AmidstThread.EDT)
private void seedFound(WorldSeed worldSeed, WorldType worldType) {
mainWindow.displayWorld(worldSeed, worldType);
worldSwitcher.displayWorld(worldSeed, worldType);
updateGUI();
}

View File

@ -172,6 +172,7 @@ public class MojangApi {
}
public String getProfileName() {
String profileName = this.profileName;
if (profileName != null) {
return profileName;
} else {