From d04fd5c75f8537d7024bcaa55765d784cefb4369 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 28 Dec 2023 12:04:02 +0100 Subject: [PATCH] Numerous interface improvements --- megameklab/mmconf/megameklab.save | 75 ++++ .../megameklab/resources/Dialogs.properties | 2 +- .../megameklab/resources/Menu.properties | 5 +- .../resources/PopupMessages.properties | 12 + .../megameklab/resources/Splash.properties | 5 +- megameklab/src/megameklab/MegaMekLab.java | 59 ++- .../src/megameklab/ui/MegaMekLabMainUI.java | 71 ++-- megameklab/src/megameklab/ui/MenuBar.java | 372 +++++++----------- .../src/megameklab/ui/MenuBarOwner.java | 40 +- .../src/megameklab/ui/PopupMessages.java | 109 +++++ megameklab/src/megameklab/ui/StartupGUI.java | 125 ++---- .../megameklab/ui/battleArmor/BAMainUI.java | 31 +- .../megameklab/ui/combatVehicle/CVMainUI.java | 22 +- .../ui/combatVehicle/CVStructureTab.java | 1 + .../megameklab/ui/dialog/MMLFileChooser.java | 4 +- .../src/megameklab/ui/dialog/UiLoader.java | 42 +- .../dialog/settings/ColorSettingsPanel.java | 30 +- .../ui/dialog/settings/MiscSettingsPanel.java | 28 +- .../ui/fighterAero/ASCriticalView.java | 4 +- .../megameklab/ui/fighterAero/ASMainUI.java | 23 +- .../src/megameklab/ui/infantry/CIMainUI.java | 40 +- .../src/megameklab/ui/largeAero/DSMainUI.java | 25 +- .../ui/largeAero/LACriticalView.java | 4 +- .../src/megameklab/ui/largeAero/WSMainUI.java | 23 +- .../ui/mek/BMCriticalTransferHandler.java | 9 +- .../src/megameklab/ui/mek/BMMainUI.java | 24 +- .../ui/protoMek/PMEquipmentDatabaseView.java | 6 +- .../src/megameklab/ui/protoMek/PMMainUI.java | 20 +- .../ui/supportVehicle/SVMainUI.java | 18 +- .../ui/util/BAASCriticalTransferHandler.java | 10 +- .../ui/util/BayWeaponCriticalTree.java | 3 +- .../src/megameklab/ui/util/CritCellUtil.java | 20 +- .../ui/util/CritListCellRenderer.java | 4 +- .../ui/util/CriticalTableModel.java | 8 +- .../ui/util/CriticalTransferHandler.java | 19 +- megameklab/src/megameklab/util/CConfig.java | 239 +++++++---- megameklab/src/megameklab/util/UnitUtil.java | 33 +- 37 files changed, 785 insertions(+), 780 deletions(-) create mode 100644 megameklab/mmconf/megameklab.save create mode 100644 megameklab/resources/megameklab/resources/PopupMessages.properties create mode 100644 megameklab/src/megameklab/ui/PopupMessages.java diff --git a/megameklab/mmconf/megameklab.save b/megameklab/mmconf/megameklab.save new file mode 100644 index 000000000..98f7a70b3 --- /dev/null +++ b/megameklab/mmconf/megameklab.save @@ -0,0 +1,75 @@ +#Client Config +#Thu Dec 28 11:44:58 CET 2023 +ASWindow=643;165;1250;1127 +Save_File_9=C\:\\Users\\Simon\\Desktop\\Arctic Fox AF1D.mtf +rs_condensed_reference=false +techUnofficialNoYear=false +Save_File_2=D\:\\BattleTech\\FOR ALL\\Anvil ANV-TESt234.mtf +Systems-Background=-13421773 +Save_File_1=data\\mechfiles\\fighters\\TRO3075\\Vulcan VLC-8N.blk +Save_File_4=data\\mechfiles\\fighters\\Golden Century\\Tomahawk THK-63-EC.blk +Save_File_3=data\\mechfiles\\mechs\\3085u\\Phoenix\\Rifleman IIC 3.mtf +Save_File_6=data\\mechfiles\\fighters\\XTRs\\Liao\\Transit TR-13 Glare.blk +useTROFormat=true +Save_File_5=data\\mechfiles\\fighters\\TRO3039u\\Transit TR-11.blk +rs_scale_units=HEXES +Save_File_8=data\\mechfiles\\mechs\\3145\\Steiner\\Zeus X ZEU-X3.mtf +mekAutocompact=false +WINDOWLEFT=0 +WINDOWSTATE=0 +Save_File_7=D\:\\BattleTech\\FOR ALL\\test.mtf +rs_color=false +Save_File_Three= +nag_equipment_ctrlclick=false +lookAndFeel=com.formdev.flatlaf.FlatDarculaLaf +MekWindow=610;168;1340;1065 +Weapons-Background=-13434880 +techUseYear=true +File_Chooser_Window= +Save_File_One=D\:\\BattleTech\\FOR ALL\\Anvil ANV-TEST.mtf +Ammo-Background=-13421773 +Equipment-Foreground=-256 +Systems-Foreground=-16750900 +rs_font=Exo +rs_show_quirks=true +BMWindow=633;171;1340;1067 +mekAutofill=true +Save_File_Four=D\:\\BattleTech\\FOR ALL\\Anvil ANV-5M_TES2.mtf +rs_reference=false +techShowExtinct=false +DSWindow= +FullScreen=0 +WINDOWHEIGHT=600 +techYear=3145 +PMWindow= +rs_heat_profile=true +rs_tac_ops_heat=false +Nonhittable-Background=-13421773 +techShowFaction=true +Empty-Background=-16764160 +Weapons-Foreground=-26215 +techProgression=false +mekAutosort=false +rs_show_era=true +Equipment-Background=-13421773 +StartupGui=SPLASH_SCREEN +rs_show_role=true +rs_scale_factor=1 +Ammo-Foreground=-26215 +rs_show_pilot_data=true +Nonhittable-Foreground=-10066330 +Last_directory=D\:\\BattleTech\\FOR ALL +Empty-Foreground=-16738048 +WINDOWTOP=0 +Save_File_10=data\\mechfiles\\vehicles\\3050U\\Zephyr Hovertank (LRM).blk +Save_File_Two=D\:\\BattleTech\\FOR ALL +WSWindow= +CIWindow= +rs_paper_size=US_LETTER +CVWindow= +skipSafetyPrompts=true +WINDOWWIDTH=800 +SVWindow=704;211;1152;1006 +Save-Location-Default=D\:\\BattleTech\\FOR ALL +BAWindow= +rs_progress_bar=true diff --git a/megameklab/resources/megameklab/resources/Dialogs.properties b/megameklab/resources/megameklab/resources/Dialogs.properties index f150d07fb..61948b8e1 100644 --- a/megameklab/resources/megameklab/resources/Dialogs.properties +++ b/megameklab/resources/megameklab/resources/Dialogs.properties @@ -8,7 +8,7 @@ ConfigurationDialog.techProgression.title=Tech Progression ConfigurationDialog.printing.title=Record Sheets and Export ConfigurationDialog.misc.title=General ConfigurationDialog.chkTechProgression.text=Use Variable Tech Level -ConfigurationDialog.chkTechProgression.tooltip=Tech Level changes from Experimental to Advanced to Standard based on the year +ConfigurationDialog.chkTechProgression.tooltip=When this is checked, the tech level of equipment and therefore of the unit changes from Experimental to Advanced to Standard based on the year. If it is unchecked, all equipment and the unit keeps its tech level regardless of the year. ConfigurationDialog.chkTechYear.text=Use game year ConfigurationDialog.chkTechYear.tooltip=Use this year to determine the Tech Level if later than the introduction year. ConfigurationDialog.chkTechShowFaction.text=Allow setting a unit's Faction diff --git a/megameklab/resources/megameklab/resources/Menu.properties b/megameklab/resources/megameklab/resources/Menu.properties index 7bcef4903..88a1e048d 100644 --- a/megameklab/resources/megameklab/resources/Menu.properties +++ b/megameklab/resources/megameklab/resources/Menu.properties @@ -54,6 +54,7 @@ refreshMenu.text=Refresh miRefreshUnitCache.text=Refresh Unit Cache ## Options Menu optionsMenu.text=Options +miImport.text=Import MML Settings... miConfiguration.text=Configuration... ## Themes Menu themesMenu.text=Themes @@ -72,6 +73,7 @@ unitCostBreakdownMenu.text=Unit Cost Breakdown unitWeightBreakdownMenu.text=Unit Weight Breakdown ### Help Menu helpMenu.text=Help +miResetWindow.text=Reset Window Positions miAbout.text=About... miRecordSheetImages.text=Record Sheet Images... @@ -93,13 +95,12 @@ dialog.imagePath.title=Image Path dialog.saveAs.title=Save As dialog.saveAs.message.format=%s %s saved to %s dialog.filter.unitFiles=Unit Files (*.mtf; *.blk; *.hmp) +dialog.importSettings=Import Settings From... message.invalidUnit.format=Warning: Invalid unit, it might load incorrectly!\n%1$s message.invalidUnit.text=Warning: Invalid unit, it might load incorrectly! message.savingInvalidUnit.text=Warning: Saving an invalid unit, it might load incorrectly! message.exportingInvalidUnit.text=Warning: Exporting an invalid unit! -message.abortUnitLoad.text=Warning: Could not create new UI, aborting unit load!\ -Probable cause: Unsupported unit type. # The following values are used programatically by MMLStartUp MMLStartUp.SPLASH_SCREEN=MML Main UI diff --git a/megameklab/resources/megameklab/resources/PopupMessages.properties b/megameklab/resources/megameklab/resources/PopupMessages.properties new file mode 100644 index 000000000..24b52b4a2 --- /dev/null +++ b/megameklab/resources/megameklab/resources/PopupMessages.properties @@ -0,0 +1,12 @@ +mostRecentNotFound=The most recent unit file could not be opened. Starting in MML's main UI instead. +noMostRecentUnit=There is no most recent unit. Starting in MML's main UI instead. +fileReadError=An error occurred while trying to read the file %s. This can happen for various reasons. The file may not exist, MML may lack the rights to read the file or the file may be malformed or not conform to its file extension. The error message is:\n\n%s +invalidUnit=The unit is invalid for the reasons listed below and may load incorrectly!\n\n%s +validUnit=Validation Passed. +fileWriteError=A problem occurred while trying to write the file. The error message is:\n\n%s +unitSaved=%s %s saved to %s +lookAndFeelError=A problem occurred while trying to change the Java Look-and-Feel. The error message is:\n\n%s +uncaughtException=Uncaught %s detected. Please open up an issue containing all logs and the current unit file at https://github.com/MegaMek/megameklab/issues +loadUiError=A problem occurred while trying to create the unit UI, reverting to a new Mek! +locationFull=Could not add %s because the chosen location is full! +invalidLocation=%s can't be placed in %s! \ No newline at end of file diff --git a/megameklab/resources/megameklab/resources/Splash.properties b/megameklab/resources/megameklab/resources/Splash.properties index 46e912e1e..fc05a9b33 100644 --- a/megameklab/resources/megameklab/resources/Splash.properties +++ b/megameklab/resources/megameklab/resources/Splash.properties @@ -9,7 +9,4 @@ btnNewAero.text=New Aero Fighter btnNewDropper.text=New Dropship/Small Craft btnNewLargeCraft.text=New Capital-Scale Craft btnQuit.text=Quit -version.text=MegaMekLab Version -message.invalidUnit.format=Warning: Invalid unit, it might load incorrectly!\n%1$s -message.abortUnitLoad.text=Warning: Could not create new UI, aborting unit load!\ -Probable cause: Unsupported unit type. \ No newline at end of file +version.text=MegaMekLab Version \ No newline at end of file diff --git a/megameklab/src/megameklab/MegaMekLab.java b/megameklab/src/megameklab/MegaMekLab.java index ec73d7381..4bbb6ffbd 100644 --- a/megameklab/src/megameklab/MegaMekLab.java +++ b/megameklab/src/megameklab/MegaMekLab.java @@ -19,7 +19,7 @@ import megamek.MegaMek; import megamek.client.ui.preferences.SuitePreferences; import megamek.common.*; -import megameklab.ui.MenuBar; +import megameklab.ui.PopupMessages; import megameklab.ui.StartupGUI; import megameklab.ui.dialog.UiLoader; import megameklab.util.CConfig; @@ -29,7 +29,6 @@ import javax.swing.*; import java.io.File; import java.util.Locale; -import java.util.ResourceBundle; public class MegaMekLab { private static final SuitePreferences mmlPreferences = new SuitePreferences(); @@ -39,20 +38,14 @@ public static void main(String... args) { // First, create a global default exception handler Thread.setDefaultUncaughtExceptionHandler((thread, t) -> { LogManager.getLogger().error("Uncaught Exception Detected", t); - final String name = t.getClass().getName(); - JOptionPane.showMessageDialog(null, - String.format("Uncaught %s detected. Please open up an issue containing all logs and the current unit file at https://github.com/MegaMek/megameklab/issues", name), - "Uncaught " + name, JOptionPane.ERROR_MESSAGE); + PopupMessages.showUncaughtException(null, t); }); - // Second, let's handle logging MegaMek.initializeLogging(MMLConstants.PROJECT_NAME); MegaMekLab.initializeLogging(MMLConstants.PROJECT_NAME); - - // Third, let's handle suite graphical setup initialization MegaMek.initializeSuiteGraphicalSetups(MMLConstants.PROJECT_NAME); - - // Finally, let's handle startup + ToolTipManager.sharedInstance().setDismissDelay(1000000); + ToolTipManager.sharedInstance().setReshowDelay(50); startup(); } @@ -112,7 +105,7 @@ private static void startup() { UiLoader.loadUi(Entity.ETYPE_INFANTRY, false, false); break; case RECENT_UNIT: - if (loadRecentUnit()) { + if (loadMostRecentUnit()) { return; } // intentional fall through when loading the most recent unit doesn't work @@ -125,7 +118,7 @@ private static void startup() { private static void setLookAndFeel() { try { - String plaf = CConfig.getParam(CConfig.CONFIG_PLAF, UIManager.getSystemLookAndFeelClassName()); + String plaf = CConfig.getParam(CConfig.GUI_PLAF, UIManager.getSystemLookAndFeelClassName()); UIManager.setLookAndFeel(plaf); } catch (Exception ex) { LogManager.getLogger().error("", ex); @@ -140,34 +133,40 @@ public static MMLOptions getMMLOptions() { return mmlOptions; } - private static boolean loadRecentUnit() { - String filePathName = CConfig.getParam(CConfig.CONFIG_SAVE_FILE_1); + /** + * Tries loading the most recent unit. Returns true when successful, false when no such + * unit could be found or the unit doesn't load. + * + * @return True when the most recent unit is successfully loaded + */ + private static boolean loadMostRecentUnit() { + String mostRecentName = CConfig.getRecentFile(1); + if (mostRecentName.isBlank()) { + PopupMessages.showNoMostRecentUnitError(null); + return false; + } - File unitFile = new File(filePathName); - if (!(unitFile.isFile())) { + File unitFile = new File(mostRecentName); + if (!unitFile.isFile()) { + PopupMessages.showMostRecentUnitMissingError(null); return false; } - ResourceBundle resources = ResourceBundle.getBundle("megameklab.resources.Menu"); try { - Entity tempEntity = new MechFileParser(unitFile).getEntity(); - if (tempEntity == null) { + Entity recentUnit = new MechFileParser(unitFile).getEntity(); + if (recentUnit == null) { return false; + } else if (!UnitUtil.validateUnit(recentUnit).isBlank()) { + PopupMessages.showUnitInvalidWarning(null, UnitUtil.validateUnit(recentUnit)); } - if (!UnitUtil.validateUnit(tempEntity).isBlank()) { - JOptionPane.showMessageDialog(null, String.format( - resources.getString("message.invalidUnit.format"), - UnitUtil.validateUnit(tempEntity))); - } - - UiLoader.loadUi(tempEntity); + UiLoader.loadUi(recentUnit, unitFile.toString()); return true; } catch (Exception ex) { - JOptionPane.showMessageDialog(null, String.format( - resources.getString("message.invalidUnit.format"), - ex.getMessage())); + PopupMessages.showFileReadError(null, unitFile.toString(), ex.getMessage()); return false; } } + + private MegaMekLab() { } } diff --git a/megameklab/src/megameklab/ui/MegaMekLabMainUI.java b/megameklab/src/megameklab/ui/MegaMekLabMainUI.java index 37f3af08a..a785a21f3 100644 --- a/megameklab/src/megameklab/ui/MegaMekLabMainUI.java +++ b/megameklab/src/megameklab/ui/MegaMekLabMainUI.java @@ -30,45 +30,49 @@ public abstract class MegaMekLabMainUI extends JFrame implements RefreshListener, EntitySource, MenuBarOwner { private Entity entity = null; + private String fileName = ""; protected MenuBar mmlMenuBar; protected boolean refreshRequired = false; public MegaMekLabMainUI() { setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); addWindowListener(new ExitOnWindowClosingListener(this)); - setResizable(true); - setExtendedState(CConfig.getIntParam("WINDOWSTATE")); + setExtendedState(CConfig.getIntParam(CConfig.GUI_FULLSCREEN)); } protected void finishSetup() { mmlMenuBar = new MenuBar(this); setJMenuBar(mmlMenuBar); reloadTabs(); - setSizeAndLocation(); refreshAll(); } protected void setSizeAndLocation() { + pack(); + restrictToScrenSize(); + CConfig.getMainUiWindowSize(this).ifPresent(this::setSize); + CConfig.getMainUiWindowPosition(this).ifPresent(this::setLocation); + setLocationRelativeTo(null); + } + + private void restrictToScrenSize() { DisplayMode currentMonitor = getGraphicsConfiguration().getDevice().getDisplayMode(); int scaledMonitorW = UIUtil.getScaledScreenWidth(currentMonitor); int scaledMonitorH = UIUtil.getScaledScreenHeight(currentMonitor); + int w = Math.min(getSize().width, scaledMonitorW); + int h = Math.min(getSize().height, scaledMonitorH); + setSize(new Dimension(w, h)); + } - // figure out size dimensions - pack(); - setLocationRelativeTo(null); - int w = getSize().width; - int h = getSize().height; - - if (scaledMonitorW < w) { - w = scaledMonitorW; + @Override + public void setVisible(boolean b) { + if (b) { + setSizeAndLocation(); } - if (scaledMonitorH < h) { - h = scaledMonitorH; + super.setVisible(b); + if (!b && (getFloatingEquipmentDatabase() != null)) { + getFloatingEquipmentDatabase().setVisible(false); } - Dimension size = new Dimension(w, h); - setSize(size); - setPreferredSize(size); - setLocationRelativeTo(null); } @Override @@ -83,7 +87,7 @@ public boolean safetyPrompt() { JOptionPane.WARNING_MESSAGE); // When the user did not actually save the unit, return as if CANCEL was pressed return (savePrompt == JOptionPane.NO_OPTION) - || ((savePrompt == JOptionPane.YES_OPTION) && mmlMenuBar.saveEntity(entity)); + || ((savePrompt == JOptionPane.YES_OPTION) && mmlMenuBar.saveUnit()); } } @@ -93,8 +97,9 @@ public boolean exit() { return false; } - CConfig.setParam("WINDOWSTATE", Integer.toString(getExtendedState())); - CConfig.setParam(CConfig.CONFIG_PLAF, UIManager.getLookAndFeel().getClass().getName()); + CConfig.setParam(CConfig.GUI_FULLSCREEN, Integer.toString(getExtendedState())); + CConfig.setParam(CConfig.GUI_PLAF, UIManager.getLookAndFeel().getClass().getName()); + CConfig.writeMainUiWindowSettings(this); CConfig.saveConfig(); PreferenceManager.getInstance().save(); MegaMek.getMMPreferences().saveToFile(MMLConstants.MM_PREFERENCES_FILE); @@ -117,7 +122,10 @@ public boolean exit() { public abstract void refreshEquipment(); @Override - public abstract void refreshHeader(); + public void refreshHeader() { + String fileInfo = fileName.isBlank() ? "" : " (" + fileName + ")"; + setTitle(getEntity().getChassis() + " " + getEntity().getModel() + fileInfo); + } @Override public abstract void refreshStatus(); @@ -132,7 +140,7 @@ public boolean exit() { public abstract void refreshPreview(); public void setEntity(Entity en) { - entity = en; + setEntity(en, ""); } @Override @@ -140,6 +148,10 @@ public Entity getEntity() { return entity; } + public void setEntity(Entity entity, String currentEntityFilename) { + this.entity = entity; + setFileName(currentEntityFilename); + } @Override public void scheduleRefresh() { @@ -160,4 +172,19 @@ private void performRefresh() { public JFrame getFrame() { return this; } + + @Override + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + refreshHeader(); + } + + @Override + public void refreshMenuBar() { + mmlMenuBar.refreshMenuBar(); + } } \ No newline at end of file diff --git a/megameklab/src/megameklab/ui/MenuBar.java b/megameklab/src/megameklab/ui/MenuBar.java index 124c3ccc4..b1ad6a511 100644 --- a/megameklab/src/megameklab/ui/MenuBar.java +++ b/megameklab/src/megameklab/ui/MenuBar.java @@ -57,20 +57,15 @@ public class MenuBar extends JMenuBar implements ClipboardOwner { private final MenuBarOwner owner; private final ResourceBundle resources = ResourceBundle.getBundle("megameklab.resources.Menu"); - private final MMLFileChooser loadUnitFileChooser = new MMLFileChooser(); private final MMLFileChooser saveUnitFileChooser = new MMLFileChooser(); private final MMLFileChooser loadImageFileChooser = new MMLFileChooser(); - private final JMenu fileMenu = new JMenu(resources.getString("fileMenu.text")); - //endregion Variable Declarations - //region Constructors public MenuBar(MenuBarOwner owner) { this.owner = owner; initialize(); } - //endregion Constructors public @Nullable MegaMekLabMainUI getUnitMainUi() { if (owner instanceof MegaMekLabMainUI) { @@ -94,13 +89,6 @@ private void conditionalExit(boolean okayToExit) { } } - /** - * The main menu bar uses the following Mnemonic keys as of 30-Jun-2022: - * F, H, R, U - * - * It uses the following Control-based keys as of 30-Jun-2022: - * A, C, L, P, R, S, U - */ private void initialize() { getAccessibleContext().setAccessibleName(resources.getString("MenuBar.accessibleName")); add(createFileMenu()); @@ -116,9 +104,6 @@ private void initialize() { saveUnitFileChooser.setDialogTitle(resources.getString("dialog.saveAs.title")); } - /** - * @return the created file menu - */ private JMenu createFileMenu() { fileMenu.removeAll(); fileMenu.setName("fileMenu"); @@ -141,32 +126,14 @@ private JMenu createFileMenu() { fileMenu.add(createOptionsMenu()); fileMenu.addSeparator(); - - int fileNumber = 1; boolean hasCConfigMenuItem = false; + int count = 1; - final JMenuItem miCConfig1 = createCConfigMenuItem(CConfig.CONFIG_SAVE_FILE_1, fileNumber++); - if (miCConfig1 != null) { - fileMenu.add(miCConfig1); - hasCConfigMenuItem = true; - } - - final JMenuItem miCConfig2 = createCConfigMenuItem(CConfig.CONFIG_SAVE_FILE_2, fileNumber++); - if (miCConfig2 != null) { - fileMenu.add(miCConfig2); - hasCConfigMenuItem = true; - } - - final JMenuItem miCConfig3 = createCConfigMenuItem(CConfig.CONFIG_SAVE_FILE_3, fileNumber++); - if (miCConfig3 != null) { - fileMenu.add(miCConfig3); - hasCConfigMenuItem = true; - } - - final JMenuItem miCConfig4 = createCConfigMenuItem(CConfig.CONFIG_SAVE_FILE_4, fileNumber); - if (miCConfig4 != null) { - fileMenu.add(miCConfig4); + for (String file : CConfig.getRecentFiles()) { + final JMenuItem miCConfig = createCConfigMenuItem(file, count); + fileMenu.add(miCConfig); hasCConfigMenuItem = true; + count++; } if (hasCConfigMenuItem) { @@ -175,7 +142,6 @@ private JMenu createFileMenu() { final JMenuItem miExit = new JMenuItem(resources.getString("miExit.text")); miExit.setName("miExit"); - miExit.setMnemonic(KeyEvent.VK_X); miExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, InputEvent.ALT_DOWN_MASK)); miExit.addActionListener(evt -> conditionalExit(owner.exit())); fileMenu.add(miExit); @@ -183,9 +149,6 @@ private JMenu createFileMenu() { return fileMenu; } - /** - * @return the created Switch Unit Type menu - */ private JMenu createSwitchUnitTypeMenu() { final JMenu switchUnitTypeMenu = new JMenu(resources.getString("switchUnitTypeMenu.text")); switchUnitTypeMenu.setName("switchUnitTypeMenu"); @@ -197,7 +160,7 @@ private JMenu createSwitchUnitTypeMenu() { final JMenuItem miSwitchToMek = new JMenuItem(resources.getString("miSwitchToMek.text")); miSwitchToMek.setName("miSwitchToMek"); miSwitchToMek.setMnemonic(KeyEvent.VK_M); - miSwitchToMek.addActionListener(evt -> newUnit(Entity.ETYPE_MECH, false)); + miSwitchToMek.addActionListener(evt -> owner.newUnit(Entity.ETYPE_MECH)); switchUnitTypeMenu.add(miSwitchToMek); } @@ -205,7 +168,7 @@ private JMenu createSwitchUnitTypeMenu() { final JMenuItem miSwitchToFighter = new JMenuItem(resources.getString("miSwitchToFighter.text")); miSwitchToFighter.setName("miSwitchToFighter"); miSwitchToFighter.setMnemonic(KeyEvent.VK_A); - miSwitchToFighter.addActionListener(evt -> newUnit(Entity.ETYPE_AERO, false)); + miSwitchToFighter.addActionListener(evt -> owner.newUnit(Entity.ETYPE_AERO)); switchUnitTypeMenu.add(miSwitchToFighter); } @@ -213,7 +176,7 @@ private JMenu createSwitchUnitTypeMenu() { final JMenuItem item = new JMenuItem(resources.getString("miSwitchToDropShipSmallCraft.text")); item.setName("miSwitchToDropShipSmallCraft"); item.setMnemonic(KeyEvent.VK_D); - item.addActionListener(evt -> newUnit(Entity.ETYPE_DROPSHIP, false)); + item.addActionListener(evt -> owner.newUnit(Entity.ETYPE_DROPSHIP)); switchUnitTypeMenu.add(item); } @@ -221,7 +184,7 @@ private JMenu createSwitchUnitTypeMenu() { final JMenuItem miSwitchToAdvancedAero = new JMenuItem(resources.getString("miSwitchToAdvancedAero.text")); miSwitchToAdvancedAero.setName("miSwitchToAdvancedAero"); miSwitchToAdvancedAero.setMnemonic(KeyEvent.VK_J); - miSwitchToAdvancedAero.addActionListener(evt -> newUnit(Entity.ETYPE_JUMPSHIP, false)); + miSwitchToAdvancedAero.addActionListener(evt -> owner.newUnit(Entity.ETYPE_JUMPSHIP)); switchUnitTypeMenu.add(miSwitchToAdvancedAero); } @@ -229,7 +192,7 @@ private JMenu createSwitchUnitTypeMenu() { final JMenuItem miSwitchToCombatVehicle = new JMenuItem(resources.getString("miSwitchToCombatVehicle.text")); miSwitchToCombatVehicle.setName("miSwitchToCombatVehicle"); miSwitchToCombatVehicle.setMnemonic(KeyEvent.VK_C); - miSwitchToCombatVehicle.addActionListener(evt -> newUnit(Entity.ETYPE_TANK, false)); + miSwitchToCombatVehicle.addActionListener(evt -> owner.newUnit(Entity.ETYPE_TANK)); switchUnitTypeMenu.add(miSwitchToCombatVehicle); } @@ -237,7 +200,7 @@ private JMenu createSwitchUnitTypeMenu() { final JMenuItem miSwitchToSupportVehicle = new JMenuItem(resources.getString("miSwitchToSupportVehicle.text")); miSwitchToSupportVehicle.setName("miSwitchToSupportVehicle"); miSwitchToSupportVehicle.setMnemonic(KeyEvent.VK_S); - miSwitchToSupportVehicle.addActionListener(evt -> newUnit(Entity.ETYPE_SUPPORT_TANK, false)); + miSwitchToSupportVehicle.addActionListener(evt -> owner.newUnit(Entity.ETYPE_SUPPORT_TANK)); switchUnitTypeMenu.add(miSwitchToSupportVehicle); } @@ -245,7 +208,7 @@ private JMenu createSwitchUnitTypeMenu() { final JMenuItem miSwitchToBattleArmor = new JMenuItem(resources.getString("miSwitchToBattleArmor.text")); miSwitchToBattleArmor.setName("miSwitchToBattleArmor"); miSwitchToBattleArmor.setMnemonic(KeyEvent.VK_B); - miSwitchToBattleArmor.addActionListener(evt -> newUnit(Entity.ETYPE_BATTLEARMOR, false)); + miSwitchToBattleArmor.addActionListener(evt -> owner.newUnit(Entity.ETYPE_BATTLEARMOR)); switchUnitTypeMenu.add(miSwitchToBattleArmor); } @@ -253,7 +216,7 @@ private JMenu createSwitchUnitTypeMenu() { final JMenuItem miSwitchToInfantry = new JMenuItem(resources.getString("miSwitchToInfantry.text")); miSwitchToInfantry.setName("miSwitchToInfantry"); miSwitchToInfantry.setMnemonic(KeyEvent.VK_I); - miSwitchToInfantry.addActionListener(evt -> newUnit(Entity.ETYPE_INFANTRY, false)); + miSwitchToInfantry.addActionListener(evt -> owner.newUnit(Entity.ETYPE_INFANTRY)); switchUnitTypeMenu.add(miSwitchToInfantry); } @@ -261,7 +224,7 @@ private JMenu createSwitchUnitTypeMenu() { final JMenuItem miSwitchToProtoMek = new JMenuItem(resources.getString("miSwitchToProtoMek.text")); miSwitchToProtoMek.setName("miSwitchToProtoMek"); miSwitchToProtoMek.setMnemonic(KeyEvent.VK_P); - miSwitchToProtoMek.addActionListener(evt -> newUnit(Entity.ETYPE_PROTOMECH, false)); + miSwitchToProtoMek.addActionListener(evt -> owner.newUnit(Entity.ETYPE_PROTOMECH)); switchUnitTypeMenu.add(miSwitchToProtoMek); } @@ -282,7 +245,7 @@ private JMenu createPrimitiveMenu(final Entity entity) { final JMenuItem miSwitchToMek = new JMenuItem(resources.getString("miSwitchToMek.text")); miSwitchToMek.setName("miSwitchToMek"); miSwitchToMek.setMnemonic(KeyEvent.VK_M); - miSwitchToMek.addActionListener(evt -> newUnit(Entity.ETYPE_MECH, true)); + miSwitchToMek.addActionListener(evt -> owner.newUnit(Entity.ETYPE_MECH, true)); primitiveMenu.add(miSwitchToMek); } @@ -290,7 +253,7 @@ private JMenu createPrimitiveMenu(final Entity entity) { final JMenuItem miSwitchToAero = new JMenuItem(resources.getString("miSwitchToAero.text")); miSwitchToAero.setName("miSwitchToAero"); miSwitchToAero.setMnemonic(KeyEvent.VK_A); - miSwitchToAero.addActionListener(evt -> newUnit(Entity.ETYPE_AERO, true)); + miSwitchToAero.addActionListener(evt -> owner.newUnit(Entity.ETYPE_AERO, true)); primitiveMenu.add(miSwitchToAero); } @@ -298,7 +261,7 @@ private JMenu createPrimitiveMenu(final Entity entity) { final JMenuItem miSwitchToDropShipSmallCraft = new JMenuItem(resources.getString("miSwitchToDropShipSmallCraft.text")); miSwitchToDropShipSmallCraft.setName("miSwitchToDropShipSmallCraft"); miSwitchToDropShipSmallCraft.setMnemonic(KeyEvent.VK_D); - miSwitchToDropShipSmallCraft.addActionListener(evt -> newUnit(Entity.ETYPE_DROPSHIP, true)); + miSwitchToDropShipSmallCraft.addActionListener(evt -> owner.newUnit(Entity.ETYPE_DROPSHIP, true)); primitiveMenu.add(miSwitchToDropShipSmallCraft); } @@ -306,7 +269,7 @@ private JMenu createPrimitiveMenu(final Entity entity) { final JMenuItem miSwitchToJumpShip = new JMenuItem(resources.getString("miSwitchToJumpShip.text")); miSwitchToJumpShip.setName("miSwitchToJumpShip"); miSwitchToJumpShip.setMnemonic(KeyEvent.VK_J); - miSwitchToJumpShip.addActionListener(evt -> newUnit(Entity.ETYPE_JUMPSHIP, true)); + miSwitchToJumpShip.addActionListener(evt -> owner.newUnit(Entity.ETYPE_JUMPSHIP, true)); primitiveMenu.add(miSwitchToJumpShip); } @@ -314,8 +277,6 @@ private JMenu createPrimitiveMenu(final Entity entity) { } /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * C, F * @return the created Load menu */ private JMenu createLoadMenu() { @@ -327,7 +288,7 @@ private JMenu createLoadMenu() { miLoadUnitFromCache.setName("miLoadUnitFromCache"); miLoadUnitFromCache.setMnemonic(KeyEvent.VK_C); miLoadUnitFromCache.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.CTRL_DOWN_MASK)); - miLoadUnitFromCache.addActionListener(evt -> StartupGUI.selectAndLoadUnitFromCache(owner.getFrame())); + miLoadUnitFromCache.addActionListener(evt -> StartupGUI.selectAndLoadUnitFromCache(owner)); loadMenu.add(miLoadUnitFromCache); final JMenuItem miLoadUnitFromFile = new JMenuItem(resources.getString("FromFile.text")); @@ -341,8 +302,6 @@ private JMenu createLoadMenu() { } /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * A, S * @return the created Save menu */ private JMenu createSaveMenu() { @@ -354,7 +313,7 @@ private JMenu createSaveMenu() { miSave.setName("miSave"); miSave.setMnemonic(KeyEvent.VK_S); miSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK)); - miSave.addActionListener(evt -> saveEntity()); + miSave.addActionListener(evt -> saveUnit()); miSave.setEnabled(isUnitGui()); saveMenu.add(miSave); @@ -362,7 +321,7 @@ private JMenu createSaveMenu() { miSaveAs.setName("miSaveAs"); miSaveAs.setMnemonic(KeyEvent.VK_A); miSaveAs.setAccelerator(KeyStroke.getKeyStroke("control shift S")); - miSaveAs.addActionListener(evt -> jMenuSaveAsEntity_actionPerformed()); + miSaveAs.addActionListener(evt -> saveUnitAs()); miSaveAs.setEnabled(isUnitGui()); saveMenu.add(miSaveAs); @@ -370,8 +329,6 @@ private JMenu createSaveMenu() { } /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * I * @return the created Import menu */ private JMenu createImportMenu() { @@ -391,8 +348,6 @@ private JMenu createImportMenu() { } /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * C, H, P, T * @return the created Export menu */ private JMenu createExportMenu() { @@ -409,8 +364,6 @@ private JMenu createExportMenu() { } /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * C, F, L, M, Q, S, U * @return the created PDF Unit Export menu */ private JMenu createPDFUnitExportMenu() { @@ -465,8 +418,6 @@ private JMenu createPDFUnitExportMenu() { } /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * U * @return the created HTML Unit Export menu */ private JMenu createHTMLUnitExportMenu() { @@ -485,8 +436,6 @@ private JMenu createHTMLUnitExportMenu() { } /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * U * @return the created Text Unit Export menu */ private JMenu createTextUnitExportMenu() { @@ -505,8 +454,6 @@ private JMenu createTextUnitExportMenu() { } /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * U * @return the created Clipboard Unit Export menu */ private JMenu createClipboardUnitExportMenu() { @@ -528,8 +475,6 @@ private JMenu createClipboardUnitExportMenu() { } /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * C, F, L, M, Q, S, U * @return the created Print menu */ private JMenu createPrintMenu() { @@ -585,8 +530,6 @@ private JMenu createPrintMenu() { } /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * U * @return the created Refresh menu */ private JMenu createRefreshMenu() { @@ -604,8 +547,6 @@ private JMenu createRefreshMenu() { } /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * C, T * @return the created Options menu */ private JMenu createOptionsMenu() { @@ -613,6 +554,12 @@ private JMenu createOptionsMenu() { optionsMenu.setName("optionsMenu"); optionsMenu.setMnemonic(KeyEvent.VK_O); + final JMenuItem miImport = new JMenuItem(resources.getString("miImport.text")); + miImport.setName("miImport"); + miImport.setMnemonic(KeyEvent.VK_I); + miImport.addActionListener(evt -> importSettings()); + optionsMenu.add(miImport); + final JMenuItem miConfiguration = new JMenuItem(resources.getString("miConfiguration.text")); miConfiguration.setName("miConfiguration"); miConfiguration.setMnemonic(KeyEvent.VK_C); @@ -655,12 +602,8 @@ private JMenu createThemesMenu() { return themesMenu; } - private @Nullable JMenuItem createCConfigMenuItem(final String configSaveFile, + private @Nullable JMenuItem createCConfigMenuItem(final String recentFileName, final int fileNumber) { - final String recentFileName = CConfig.getParam(configSaveFile); - if (recentFileName.isEmpty()) { - return null; - } File recent = new File(recentFileName); String path = recent.getParent(); String mmlDirectory = System.getProperty("user.dir"); @@ -675,15 +618,11 @@ private JMenu createThemesMenu() { final JMenuItem miCConfig = new JMenuItem(text); miCConfig.setName("miCConfig"); miCConfig.addActionListener(evt -> loadUnitFromFile(fileNumber)); - miCConfig.setMnemonic(KeyEvent.VK_1); + miCConfig.setMnemonic(48 + fileNumber); // the number itself, i.e. 1, 2, 3 etc. return miCConfig; } - //endregion File Menu - //region Unit Validation Menu /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * C, F, U * @return the created Unit Validation menu */ private JMenu createUnitValidationMenu() { @@ -712,12 +651,8 @@ private JMenu createUnitValidationMenu() { return unitValidationMenu; } - //endregion Unit Validation Menu - //region Reports Menu /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * B, C, S, W * @return the created reports menu */ private JMenu createReportsMenu() { @@ -775,8 +710,6 @@ private JMenu createUnitBVBreakdownMenu() { } /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * C, F, U * @return the created Unit Cost Breakdown menu */ private JMenu createUnitCostBreakdownMenu() { @@ -807,8 +740,6 @@ private JMenu createUnitCostBreakdownMenu() { } /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * C, F, U * @return the created Unit Weight Breakdown menu */ private JMenu createUnitWeightBreakdownMenu() { @@ -837,12 +768,8 @@ private JMenu createUnitWeightBreakdownMenu() { return unitWeightBreakdownMenu; } - //endregion Reports Menu - //region Help Menu /** - * This menu uses the following Mnemonic keys as of 30-Jun-2022: - * A, R * @return the created Help menu */ private JMenu createHelpMenu() { @@ -850,6 +777,12 @@ private JMenu createHelpMenu() { helpMenu.setName("helpMenu"); helpMenu.setMnemonic(KeyEvent.VK_H); + final JMenuItem miResetWindowPos = new JMenuItem(resources.getString("miResetWindow.text")); + miResetWindowPos.setName("miResetWindows"); + miResetWindowPos.setMnemonic(KeyEvent.VK_W); + miResetWindowPos.addActionListener(evt -> CConfig.resetWindowPositions()); + helpMenu.add(miResetWindowPos); + final JMenuItem miAbout = new JMenuItem(resources.getString("miAbout.text")); miAbout.setName("miAbout"); miAbout.setMnemonic(KeyEvent.VK_A); @@ -864,8 +797,6 @@ private JMenu createHelpMenu() { return helpMenu; } - //endregion Help Menu - //endregion Initialization private void jMenuGetUnitValidationFromCache_actionPerformed() { UnitLoadingDialog unitLoadingDialog = new UnitLoadingDialog(owner.getFrame()); @@ -907,9 +838,7 @@ private void jMenuGetUnitBVFromFile_actionPerformed() { try { UnitUtil.showBVCalculations(owner.getFrame(), new MechFileParser(unitFile).getEntity()); } catch (Exception ex) { - JOptionPane.showMessageDialog(owner.getFrame(), - String.format(resources.getString("message.invalidUnit.format"), - ex.getMessage())); + PopupMessages.showFileReadError(owner.getFrame(), unitFile.toString(), ex.getMessage()); } } @@ -923,15 +852,19 @@ private void jMenuGetUnitValidationFromFile_actionPerformed() { Entity tempEntity = new MechFileParser(unitFile).getEntity(); UnitUtil.showValidation(tempEntity, owner.getFrame()); } catch (Exception ex) { - JOptionPane.showMessageDialog(owner.getFrame(), - String.format(resources.getString("message.invalidUnit.format"), - ex.getMessage())); + PopupMessages.showFileReadError(owner.getFrame(), unitFile.toString(), ex.getMessage()); } } + /** + * Shows a file chooser for a unit file to open. Returns the unit file if one was chosen; + * returns null if none was chosen or the dialog was cancelled. + * + * @return The chosen unit file or null if cancelled or nothing was chosen + */ private @Nullable File chooseUnitFileToLoad() { - loadUnitFileChooser.setCurrentDirectory(new File(CConfig.getParam(CConfig.LAST_DIRECTORY))); - int result = loadUnitFileChooser.showOpenDialog(frame); + loadUnitFileChooser.setCurrentDirectory(new File(CConfig.getParam(CConfig.FILE_LAST_DIRECTORY))); + int result = loadUnitFileChooser.showOpenDialog(owner.getFrame()); return result == JFileChooser.APPROVE_OPTION ? loadUnitFileChooser.getSelectedFile() : null; } @@ -944,9 +877,7 @@ private void jMenuGetUnitBreakdownFromFile_actionPerformed() { try { new CostDisplayDialog(owner.getFrame(), new MechFileParser(unitFile).getEntity()).setVisible(true); } catch (Exception ex) { - JOptionPane.showMessageDialog(owner.getFrame(), - String.format(resources.getString("message.invalidUnit.format"), - ex.getMessage())); + PopupMessages.showFileReadError(owner.getFrame(), unitFile.toString(), ex.getMessage()); } } @@ -960,9 +891,7 @@ private void jMenuGetUnitWeightBreakdownFromFile_actionPerformed() { Entity tempEntity = new MechFileParser(unitFile).getEntity(); UnitUtil.showUnitWeightBreakDown(tempEntity, owner.getFrame()); } catch (Exception ex) { - JOptionPane.showMessageDialog(owner.getFrame(), - String.format(resources.getString("message.invalidUnit.format"), - ex.getMessage())); + PopupMessages.showFileReadError(owner.getFrame(), unitFile.toString(), ex.getMessage()); } } @@ -976,9 +905,7 @@ private void jMenuGetUnitSpecsFromFile_actionPerformed() { Entity tempEntity = new MechFileParser(unitFile).getEntity(); UnitUtil.showUnitSpecs(tempEntity, owner.getFrame()); } catch (Exception ex) { - JOptionPane.showMessageDialog(owner.getFrame(), - String.format(resources.getString("message.invalidUnit.format"), - ex.getMessage())); + PopupMessages.showFileReadError(owner.getFrame(), unitFile.toString(), ex.getMessage()); } } @@ -990,8 +917,9 @@ private void importFluffImageAction() { try { Entity tempEntity = new MechFileParser(unitFile).getEntity(); - if (!UnitUtil.validateUnit(getFrame().getEntity()).isBlank()) { - JOptionPane.showMessageDialog(getFrame(), resources.getString("message.invalidUnit.text")); + String validationResult = UnitUtil.validateUnit(tempEntity); + if (!validationResult.isBlank()) { + PopupMessages.showUnitInvalidWarning(owner.getFrame(), validationResult); } if (!owner.getEntity().getFluff().getMMLImagePath().isBlank()) { @@ -1002,15 +930,16 @@ private void importFluffImageAction() { loadImageFileChooser.setSelectedFile(new File(imageName)); } else { loadImageFileChooser.setCurrentDirectory(new File(ImageHelper.fluffPath)); - loadImageFileChooser.setSelectedFile(new File(getFrame().getEntity().getChassis() + ' ' + getFrame().getEntity().getModel() + ".png")); + loadImageFileChooser.setSelectedFile(new File(getUnitMainUi().getEntity().getChassis() + + ' ' + getUnitMainUi().getEntity().getModel() + ".png")); } - int result = loadImageFileChooser.showSaveDialog(frame); + int result = loadImageFileChooser.showSaveDialog(owner.getFrame()); if ((result == JFileChooser.APPROVE_OPTION) && (loadImageFileChooser.getSelectedFile() != null)) { String relativeFilePath = loadImageFileChooser.getSelectedFile().getAbsolutePath(); relativeFilePath = "." + File.separatorChar + relativeFilePath .substring(new File(System.getProperty("user.dir")).getAbsolutePath().length() + 1); - getFrame().getEntity().getFluff().setMMLImagePath(relativeFilePath); + getUnitMainUi().getEntity().getFluff().setMMLImagePath(relativeFilePath); BLKFile.encode(unitFile.getAbsolutePath(), tempEntity); } } catch (Exception ex) { @@ -1099,8 +1028,6 @@ private void jMenuResetEntity_actionPerformed(ActionEvent event) { return; } - CConfig.updateSaveFiles("Reset Unit"); - CConfig.setParam(CConfig.CONFIG_SAVE_FILE_1, ""); Entity en = owner.getEntity(); if (en instanceof Tank) { getUnitMainUi().createNewUnit(Entity.ETYPE_TANK); @@ -1127,10 +1054,8 @@ private void jMenuResetEntity_actionPerformed(ActionEvent event) { } else { LogManager.getLogger().warn("Received unknown entityType!"); } - setVisible(true); reload(); refresh(); - getUnitMainUi().setVisible(true); getUnitMainUi().repaint(); } @@ -1148,88 +1073,92 @@ public static String createUnitFilename(Entity entity) { return fileName + ((entity instanceof Mech) ? ".mtf" : ".blk"); } - private void saveEntity() { - saveEntity(owner.getEntity()); - } - - public boolean saveEntity(final @Nullable Entity entity) { + /** + * Tries to save the unit directly to its file, if it has a filename already. If + * it hasn't, it performs a Save As... Returns true when it successfully saves the + * unit, false if not. + * + * @return True when the unit was actually saved, false otherwise + */ + public boolean saveUnit() { + Entity entity = owner.getEntity(); if (entity == null) { + LogManager.getLogger().error("Tried to save null entity."); return false; - } else if (!UnitUtil.validateUnit(entity).isBlank()) { - JOptionPane.showMessageDialog(owner.getFrame(), - resources.getString("message.invalidUnit.text")); + } else { + String validationResult = UnitUtil.validateUnit(entity); + if (!validationResult.isBlank()) { + PopupMessages.showUnitInvalidWarning(owner.getFrame(), validationResult); + } } - String fileName = createUnitFilename(entity); UnitUtil.compactCriticals(entity); + owner.refreshAll(); // The crits may have moved - String filePathName = CConfig.getParam(CConfig.CONFIG_SAVE_FILE_1); - - if (filePathName.isBlank() || !filePathName.contains(fileName)) { - if (getFrame().getEntity() instanceof Mech) { - saveUnitFileChooser.setFileFilter(new FileNameExtensionFilter("Mek files", "mtf")); - } else { - saveUnitFileChooser.setFileFilter(new FileNameExtensionFilter("Unit files", "blk")); - } - saveUnitFileChooser.setCurrentDirectory(new File(filePathName)); - saveUnitFileChooser.setSelectedFile(new File(createUnitFilename(getFrame().getEntity()))); - int result = saveUnitFileChooser.showSaveDialog(frame); - if ((result != JFileChooser.APPROVE_OPTION) || (saveUnitFileChooser.getSelectedFile() == null)) { + String filePathName = owner.getFileName(); + // For safety, save automatically only to .mtf or .blk files, otherwise ask + if (!(filePathName.endsWith(".mtf") || filePathName.endsWith(".blk")) || !new File(filePathName).exists()) { + File selectedFile = chooseSaveFile(); + if (selectedFile == null) { return false; } - filePathName = saveUnitFileChooser.getSelectedFile().getPath(); - CConfig.setParam(CConfig.CONFIG_SAVE_LOC, saveUnitFileChooser.getSelectedFile().getParent()); + filePathName = selectedFile.getPath(); } - CConfig.updateSaveFiles(filePathName); + CConfig.setMostRecentFile(filePathName); return saveUnitTo(new File(filePathName)); } - private void jMenuSaveAsEntity_actionPerformed() { - if (!UnitUtil.validateUnit(owner.getEntity()).isBlank()) { - JOptionPane.showMessageDialog(owner.getFrame(), - resources.getString("message.savingInvalidUnit.text")); + private void saveUnitAs() { + String validationResult = UnitUtil.validateUnit(owner.getEntity()); + if (!validationResult.isBlank()) { + PopupMessages.showUnitInvalidWarning(owner.getFrame(), validationResult); } UnitUtil.compactCriticals(owner.getEntity()); + owner.refreshAll(); // The crits may have moved - String filePathName = CConfig.getParam(CConfig.CONFIG_SAVE_LOC); - if (getFrame().getEntity() instanceof Mech) { + File saveFile = chooseSaveFile(); + if (saveFile != null) { + CConfig.setMostRecentFile(saveFile.toString()); + saveUnitTo(saveFile); + } + } + + private @Nullable File chooseSaveFile() { + if (getUnitMainUi().getEntity() instanceof Mech) { saveUnitFileChooser.setFileFilter(new FileNameExtensionFilter("Mek files", "mtf")); } else { saveUnitFileChooser.setFileFilter(new FileNameExtensionFilter("Unit files", "blk")); } - saveUnitFileChooser.setCurrentDirectory(new File(filePathName)); - saveUnitFileChooser.setSelectedFile(new File(createUnitFilename(getFrame().getEntity()))); - int result = saveUnitFileChooser.showSaveDialog(frame); + saveUnitFileChooser.setSelectedFile(new File(createUnitFilename(getUnitMainUi().getEntity()))); + int result = saveUnitFileChooser.showSaveDialog(owner.getFrame()); if ((result != JFileChooser.APPROVE_OPTION) || (saveUnitFileChooser.getSelectedFile() == null)) { - return; + return null; + } else { + return saveUnitFileChooser.getSelectedFile(); } - - File saveFile = saveUnitFileChooser.getSelectedFile(); - CConfig.setParam(CConfig.CONFIG_SAVE_LOC, saveUnitFileChooser.getSelectedFile().getParent()); - - CConfig.updateSaveFiles(filePathName); - saveUnitTo(saveFile); } private boolean saveUnitTo(File file) { - if (getFrame().getEntity() == null) { + if (getUnitMainUi().getEntity() == null) { return false; } try { - if (getFrame().getEntity() instanceof Mech) { + if (getUnitMainUi().getEntity() instanceof Mech) { try (FileOutputStream fos = new FileOutputStream(file); PrintStream ps = new PrintStream(fos)) { ps.println(((Mech) owner.getEntity()).getMtf()); } } else { - BLKFile.encode(file.getPath(), getFrame().getEntity()); + BLKFile.encode(file.getPath(), getUnitMainUi().getEntity()); } - showUnitSavedMessage(file); + PopupMessages.showUnitSavedMessage(owner.getFrame(), getUnitMainUi().getEntity(), file); + getUnitMainUi().setFileName(file.toString()); return true; } catch (Exception ex) { + PopupMessages.showFileWriteError(owner.getFrame(), ex.getMessage()); LogManager.getLogger().error("", ex); return false; } @@ -1246,9 +1175,9 @@ private String entitySummaryText(boolean html) { } private void exportSummary(boolean html) { - if (!UnitUtil.validateUnit(owner.getEntity()).isBlank()) { - JOptionPane.showMessageDialog(owner.getFrame(), - resources.getString("message.exportingInvalidUnit.text")); + String validationResult = UnitUtil.validateUnit(owner.getEntity()); + if (!validationResult.isBlank()) { + PopupMessages.showUnitInvalidWarning(owner.getFrame(), validationResult); } String unitName = owner.getEntity().getChassis() + ' ' + owner.getEntity().getModel(); @@ -1256,7 +1185,7 @@ private void exportSummary(boolean html) { MMLFileChooser fileChooser = new MMLFileChooser(); fileChooser.setDialogTitle(resources.getString("dialog.saveAs.title")); fileChooser.setSelectedFile(new File(unitName + (html ? ".html" : ".txt"))); - int result = fileChooser.showSaveDialog(getFrame()); + int result = fileChooser.showSaveDialog(owner.getFrame()); if ((result != JFileChooser.APPROVE_OPTION) || (fileChooser.getSelectedFile() == null)) { return; } @@ -1265,19 +1194,20 @@ private void exportSummary(boolean html) { PrintStream ps = new PrintStream(fos)) { ps.println(entitySummaryText(html)); } catch (Exception ex) { + PopupMessages.showFileWriteError(owner.getFrame(), ex.getMessage()); LogManager.getLogger().error("", ex); } } private void loadUnitFromFile(int fileNumber) { - String filePathName = System.getProperty("user.dir") + "/data/mechfiles/"; // TODO : remove inline file path - + File unitFile; if (fileNumber > 0) { - filePathName = CConfig.getRecentFile(fileNumber); - } - - File unitFile = new File(filePathName); - if (!(unitFile.isFile())) { + String recentFileName = CConfig.getRecentFile(fileNumber); + if (recentFileName.isBlank()) { + return; + } + unitFile = new File(recentFileName); + } else { unitFile = chooseUnitFileToLoad(); if (unitFile == null) { return; @@ -1285,41 +1215,39 @@ private void loadUnitFromFile(int fileNumber) { } try { - Entity tempEntity = new MechFileParser(unitFile).getEntity(); + Entity loadedUnit = new MechFileParser(unitFile).getEntity(); + + if (loadedUnit == null) { + throw new Exception(); + } - if ((null == tempEntity) || !owner.safetyPrompt()) { + if (!owner.safetyPrompt()) { return; } - if (!UnitUtil.validateUnit(tempEntity).isBlank()) { - JOptionPane.showMessageDialog(owner.getFrame(), String.format( - resources.getString("message.invalidUnit.format"), - UnitUtil.validateUnit(tempEntity))); + String validationResult = UnitUtil.validateUnit(loadedUnit); + if (!validationResult.isBlank()) { + PopupMessages.showUnitInvalidWarning(owner.getFrame(), validationResult); } - if (isStartupGui() || (tempEntity.getEntityType() != owner.getEntity().getEntityType())) { + newRecentUnit(unitFile.toString()); + if (isStartupGui() || (loadedUnit.getEntityType() != owner.getEntity().getEntityType())) { owner.getFrame().setVisible(false); owner.getFrame().dispose(); - UiLoader.loadUi(tempEntity); - return; + UiLoader.loadUi(loadedUnit, unitFile.toString()); } else { - getFrame().setEntity(tempEntity); - UnitUtil.updateLoadedUnit(getFrame().getEntity()); - createFileMenu(); + getUnitMainUi().setEntity(loadedUnit, unitFile.toString()); + UnitUtil.updateLoadedUnit(getUnitMainUi().getEntity()); + reload(); + refresh(); } } catch (Exception ex) { - JOptionPane.showMessageDialog(owner.getFrame(), String.format( - resources.getString("message.invalidUnit.format"), - ex.getMessage())); + PopupMessages.showFileReadError(owner.getFrame(), unitFile.toString(), ex.getMessage()); } - newRecentUnit(unitFile.getAbsolutePath()); - reload(); - refresh(); - getUnitMainUi().setVisible(true); } private void newRecentUnit(String latestUnit) { - CConfig.updateSaveFiles(latestUnit); + CConfig.setMostRecentFile(latestUnit); createFileMenu(); } @@ -1331,19 +1259,6 @@ private void reload() { getUnitMainUi().reloadTabs(); } - /** - * This function will create a new mainUI frame (via the loading dialog) for the - * given unit type and get rid of the existing frame - * @param type an int corresponding to the unit type to construct - */ - private void newUnit(long type, boolean primitive) { - if (owner.safetyPrompt()) { - owner.getFrame().setVisible(false); - owner.getFrame().dispose(); - UiLoader.loadUi(type, primitive, false); - } - } - @Override public void lostOwnership(Clipboard arg0, Transferable arg1) { } @@ -1351,12 +1266,23 @@ private boolean isStartupGui() { return owner instanceof StartupGUI; } - private void showUnitSavedMessage(File file) { - JOptionPane.showMessageDialog(getFrame(), - String.format(resources.getString("dialog.saveAs.message.format"), - getFrame().getEntity().getChassis(), - getFrame().getEntity().getModel(), file)); private boolean isUnitGui() { return !isStartupGui(); } + + public void refreshMenuBar() { + createFileMenu(); + } + + private void importSettings() { + MMLFileChooser fileChooser = new MMLFileChooser(); + fileChooser.setDialogTitle(resources.getString("dialog.importSettings")); + fileChooser.setFileFilter(new FileNameExtensionFilter("MML Settings", "properties")); + fileChooser.setSelectedFile(new File("megameklab.properties")); + int result = fileChooser.showOpenDialog(owner.getFrame()); + if ((result != JFileChooser.APPROVE_OPTION) || (fileChooser.getSelectedFile() == null)) { + return; + } + CConfig.importSettings(fileChooser.getSelectedFile()); + } } \ No newline at end of file diff --git a/megameklab/src/megameklab/ui/MenuBarOwner.java b/megameklab/src/megameklab/ui/MenuBarOwner.java index 9adcdd9e6..43c4d0b42 100644 --- a/megameklab/src/megameklab/ui/MenuBarOwner.java +++ b/megameklab/src/megameklab/ui/MenuBarOwner.java @@ -20,6 +20,7 @@ import megamek.common.Entity; import megamek.common.annotations.Nullable; +import megameklab.ui.dialog.UiLoader; import megameklab.ui.util.AppCloser; import javax.swing.*; @@ -35,6 +36,9 @@ public interface MenuBarOwner extends AppCloser { /** @return The entity currently worked on or null. */ @Nullable Entity getEntity(); + /** @return The file name of the currently worked on unit or an empty String. */ + @Nullable String getFileName(); + /** * This method is called when an action will cause the currently edited unit to be discarded (exit MML, * load a new unit or switch unit type). @@ -61,6 +65,36 @@ default boolean safetyPrompt() { */ default void refreshAll() { } + /** + * Refreshes the menu bar. Updates the recent units in the File menu. + */ + void refreshMenuBar(); + + /** + * Creates a new main UI frame for the given unit type and disposes the + * existing frame (this MenuBarOwner). + * + * @param type an int corresponding to the unit type to construct + */ + default void newUnit(long type) { + newUnit(type, false); + } + + /** + * Creates a new main UI frame for the given unit type and disposes the + * existing frame (this MenuBarOwner). + * + * @param type an int corresponding to the unit type to construct + * @param primitive true when the new unit should be a primitive type + */ + default void newUnit(long type, boolean primitive) { + if (safetyPrompt()) { + getFrame().setVisible(false); + getFrame().dispose(); + UiLoader.loadUi(type, primitive, false); + } + } + /** * Sets the look and feel for the application. * @@ -71,10 +105,8 @@ default void changeTheme(UIManager.LookAndFeelInfo plaf) { try { UIManager.setLookAndFeel(plaf.getClassName()); SwingUtilities.updateComponentTreeUI(getFrame()); - } catch (Exception exception) { - JOptionPane.showMessageDialog(getFrame(), - "Can't change look and feel", "Invalid PLAF", - JOptionPane.ERROR_MESSAGE); + } catch (Exception ex) { + PopupMessages.showLookAndFeelError(getFrame(), ex.getMessage()); } }); } diff --git a/megameklab/src/megameklab/ui/PopupMessages.java b/megameklab/src/megameklab/ui/PopupMessages.java new file mode 100644 index 000000000..f98593662 --- /dev/null +++ b/megameklab/src/megameklab/ui/PopupMessages.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2023 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMekLab. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ +package megameklab.ui; + +import megamek.common.Entity; + +import javax.swing.*; +import java.awt.*; +import java.io.File; +import java.util.ResourceBundle; + +/** + * This class contains static methods that each show a commonly used popup message, such as the + * "unit is invalid" warning or common errors. The parent frame should ideally be not null. + */ +public final class PopupMessages { + + private static final ResourceBundle resources = ResourceBundle.getBundle("megameklab.resources.PopupMessages"); + + public static void showMostRecentUnitMissingError(Component parent) { + showInfoMessage(parent, resources.getString("mostRecentNotFound")); + } + + public static void showNoMostRecentUnitError(Component parent) { + showInfoMessage(parent, resources.getString("noMostRecentUnit")); + } + + public static void showUiLoadError(Component parent) { + showErrorMessage(parent, resources.getString("loadUiError")); + } + + public static void showInvalidLocationInfo(Component parent, String equipmentName, String locationName) { + showErrorMessage(parent, String.format(resources.getString("invalidLocation"), equipmentName, locationName)); + } + + public static void showFileReadError(Component parent, String fileName, String errorMessage) { + showErrorMessage(parent, String.format(resources.getString("fileReadError"), fileName, errorMessage)); + } + + public static void showLocationFullError(Component parent, String equipmentName) { + showErrorMessage(parent, String.format(resources.getString("locationFull"), equipmentName)); + } + + public static void showLocationFullError(Component parent) { + showErrorMessage(parent, String.format(resources.getString("locationFull"), "equipment")); + } + + public static void showUnitInvalidWarning(Component parent) { + showWarningMessage(parent, resources.getString("invalidUnit")); + } + + public static void showUnitInvalidWarning(Component parent, String validationResult) { + showWarningMessage(parent, String.format(resources.getString("invalidUnit"), validationResult)); + } + + public static void showUnitIsValid(Component parent) { + showInfoMessage(parent, resources.getString("validUnit")); + } + + public static void showFileWriteError(Component parent, String errorMessage) { + showErrorMessage(parent, String.format(resources.getString("fileWriteError"), errorMessage)); + } + + public static void showUnitSavedMessage(Component parent, Entity entity, File file) { + showInfoMessage(parent, String.format(resources.getString("unitSaved"), + entity.getChassis(), entity.getModel(), file)); + } + + public static void showLookAndFeelError(Component parent, String errorMessage) { + showErrorMessage(parent, String.format(resources.getString("lookAndFeelError"), errorMessage)); + } + + public static void showUncaughtException(Component parent, Throwable throwable) { + final String name = throwable.getClass().getName(); + showErrorMessage(parent, String.format(resources.getString("uncaughtException"), name)); + } + + // ############ Internal message handlers + + private static void showErrorMessage(Component parent, String message) { + JOptionPane.showMessageDialog(parent, message, "MML encountered a problem", JOptionPane.ERROR_MESSAGE); + } + + private static void showWarningMessage(Component parent, String message) { + JOptionPane.showMessageDialog(parent, message, "Warning", JOptionPane.WARNING_MESSAGE); + } + + private static void showInfoMessage(Component parent, String message) { + JOptionPane.showMessageDialog(parent, message, "Information", JOptionPane.INFORMATION_MESSAGE); + } + + private PopupMessages() { } +} diff --git a/megameklab/src/megameklab/ui/StartupGUI.java b/megameklab/src/megameklab/ui/StartupGUI.java index e0ea7cfbc..17f65d96a 100644 --- a/megameklab/src/megameklab/ui/StartupGUI.java +++ b/megameklab/src/megameklab/ui/StartupGUI.java @@ -20,22 +20,18 @@ import megamek.client.ui.swing.widget.SkinSpecification; import megamek.client.ui.swing.widget.SkinSpecification.UIComponents; import megamek.client.ui.swing.widget.SkinXMLHandler; +import megamek.client.ui.swing.widget.SkinnedJPanel; import megamek.common.Configuration; import megamek.common.Entity; -import megamek.common.annotations.Nullable; -import megamek.common.util.ImageUtil; -import megamek.common.util.fileUtils.MegaMekFile; import megameklab.MMLConstants; import megameklab.ui.dialog.MegaMekLabUnitSelectorDialog; import megameklab.ui.dialog.UiLoader; import megameklab.ui.util.ExitOnWindowClosingListener; import megameklab.util.CConfig; import megameklab.util.UnitUtil; -import org.apache.logging.log4j.LogManager; import javax.swing.*; import java.awt.*; -import java.awt.image.BufferedImage; import java.io.File; import java.util.ResourceBundle; import java.util.TreeMap; @@ -44,9 +40,9 @@ * A startup splash screen for MegaMekLab * @author Taharqa */ -public class StartupGUI extends JPanel implements MenuBarOwner { +public class StartupGUI extends SkinnedJPanel implements MenuBarOwner { JFrame frame; - BufferedImage backgroundIcon; + MenuBar mmlMenuBar; /** A map of resolution widths to file names for the startup screen */ private final TreeMap startupScreenImages = new TreeMap<>(); @@ -58,7 +54,8 @@ public class StartupGUI extends JPanel implements MenuBarOwner { private final ResourceBundle resourceMap = ResourceBundle.getBundle("megameklab.resources.Splash"); - public StartupGUI() { + public StartupGUI() { + super(UIComponents.MainMenuBorder, 1); initComponents(); } @@ -67,26 +64,13 @@ private void initComponents() { frame = new JFrame("MegaMekLab"); setBackground(UIManager.getColor("controlHighlight")); - frame.setJMenuBar(new MenuBar(this)); + mmlMenuBar = new MenuBar(this); + frame.setJMenuBar(mmlMenuBar); Dimension scaledMonitorSize = UIUtil.getScaledScreenSize(frame); JLabel splash = UIUtil.createSplashComponent(startupScreenImages, frame); add(splash, BorderLayout.CENTER); - if (skinSpec.hasBackgrounds()) { - if (skinSpec.backgrounds.size() > 1) { - File file = new MegaMekFile(Configuration.widgetsDir(), - skinSpec.backgrounds.get(1)).getFile(); - if (!file.exists()) { - LogManager.getLogger().error("Background icon doesn't exist: " + file.getAbsolutePath()); - } else { - backgroundIcon = (BufferedImage) ImageUtil.loadImageFromFile(file.toString()); - } - } - } else { - backgroundIcon = null; - } - JLabel labVersion = new JLabel(resourceMap.getString("version.text") + MMLConstants.VERSION, JLabel.CENTER); labVersion.setPreferredSize(new Dimension(250,15)); if (!skinSpec.fontColors.isEmpty()) { @@ -95,7 +79,7 @@ private void initComponents() { MegamekButton btnLoadUnit = new MegamekButton(resourceMap.getString("btnLoadUnit.text"), UIComponents.MainMenuButton.getComp(), true); - btnLoadUnit.addActionListener(evt -> selectAndLoadUnitFromCache(frame)); + btnLoadUnit.addActionListener(evt -> selectAndLoadUnitFromCache(this)); MegamekButton btnNewMek = new MegamekButton(resourceMap.getString("btnNewMek.text"), UIComponents.MainMenuButton.getComp(), true); @@ -232,38 +216,6 @@ private void initComponents() { frame.setLocationRelativeTo(null); frame.setVisible(true); } - - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - if (backgroundIcon == null) { - return; - } - int w = getWidth(); - int h = getHeight(); - int iW = backgroundIcon.getWidth(); - int iH = backgroundIcon.getHeight(); - // If the image isn't loaded, prevent an infinite loop - if ((iW < 1) || (iH < 1)) { - return; - } - for (int x = 0; x < w; x += iW) { - for (int y = 0; y < h; y += iH) { - g.drawImage(backgroundIcon, x, y, null); - } - } - } - - /** - * This function will create a new mainUI frame (via the loading dialog) for the - * given unit type and get rid of the splash screen - * @param type an int corresponding to the unit type to construct - */ - private void newUnit(long type) { - frame.setVisible(false); - frame.dispose(); - UiLoader.loadUi(type, false, false); - } /** * Shows the Unit Selector Window and loads the unit if the user selects one. When the chosen @@ -274,50 +226,43 @@ private void newUnit(long type) { * @param previousFrame The active frame before loading a new unit; can be the StartupGUI or any * MegaMekLabMainUI. */ - public static void selectAndLoadUnitFromCache(@Nullable JFrame previousFrame) { - UnitLoadingDialog unitLoadingDialog = new UnitLoadingDialog(previousFrame); + public static void selectAndLoadUnitFromCache(MenuBarOwner previousFrame) { + UnitLoadingDialog unitLoadingDialog = new UnitLoadingDialog(previousFrame.getFrame()); unitLoadingDialog.setVisible(true); - MegaMekLabUnitSelectorDialog viewer = new MegaMekLabUnitSelectorDialog(previousFrame, unitLoadingDialog); + MegaMekLabUnitSelectorDialog viewer = new MegaMekLabUnitSelectorDialog(previousFrame.getFrame(), unitLoadingDialog); Entity newUnit = viewer.getChosenEntity(); + String fileName = viewer.getChosenMechSummary().getSourceFile().toString(); + if (fileName.toLowerCase().endsWith(".zip")) { + fileName = viewer.getChosenMechSummary().getSourceFile().getAbsolutePath(); + fileName = fileName.substring(0, fileName.lastIndexOf(File.separatorChar) + 1); + fileName = fileName + MenuBar.createUnitFilename(newUnit); + } viewer.setVisible(false); viewer.dispose(); - MegaMekLabMainUI previousUI = null; - if (previousFrame instanceof MegaMekLabMainUI) { - previousUI = (MegaMekLabMainUI) previousFrame; - } - if ((newUnit == null) || - ((previousUI != null) && !previousUI.safetyPrompt())) { + if ((newUnit == null) || !previousFrame.safetyPrompt()) { return; } - if (!UnitUtil.validateUnit(newUnit).trim().isBlank()) { - JOptionPane.showMessageDialog(previousFrame, String.format( - ResourceBundle.getBundle("megameklab.resources.Splash").getString("message.invalidUnit.format"), - UnitUtil.validateUnit(newUnit))); + String validationResult = UnitUtil.validateUnit(newUnit); + if (!validationResult.isBlank()) { + PopupMessages.showUnitInvalidWarning(previousFrame.getFrame(), validationResult); } - if ((previousUI == null) || (newUnit.getEntityType() != previousUI.getEntity().getEntityType())) { - if (previousFrame != null) { - previousFrame.setVisible(false); - previousFrame.dispose(); - } - UiLoader.loadUi(newUnit); + CConfig.setMostRecentFile(fileName); + if (!(previousFrame instanceof MegaMekLabMainUI) + || (newUnit.getEntityType() != previousFrame.getEntity().getEntityType())) { + previousFrame.getFrame().setVisible(false); + previousFrame.getFrame().dispose(); + UiLoader.loadUi(newUnit, fileName); } else { UnitUtil.updateLoadedUnit(newUnit); - if (viewer.getChosenMechSummary().getSourceFile().getName().endsWith(".zip")) { - String fileName = viewer.getChosenMechSummary().getSourceFile().getAbsolutePath(); - fileName = fileName.substring(0, fileName.lastIndexOf(File.separatorChar) + 1); - fileName = fileName + MenuBar.createUnitFilename(newUnit); - CConfig.updateSaveFiles(fileName); - } else { - CConfig.updateSaveFiles(viewer.getChosenMechSummary().getSourceFile().getAbsolutePath()); - } - previousUI.setEntity(newUnit); + previousFrame.refreshMenuBar(); + MegaMekLabMainUI previousUI = (MegaMekLabMainUI) previousFrame; + previousUI.setEntity(newUnit, fileName); previousUI.reloadTabs(); previousUI.refreshAll(); - previousUI.setVisible(true); } } @@ -330,4 +275,14 @@ public JFrame getFrame() { public Entity getEntity() { return null; } + + @Override + public String getFileName() { + return null; + } + + @Override + public void refreshMenuBar() { + mmlMenuBar.refreshMenuBar(); + } } \ No newline at end of file diff --git a/megameklab/src/megameklab/ui/battleArmor/BAMainUI.java b/megameklab/src/megameklab/ui/battleArmor/BAMainUI.java index a28935a9a..edede8971 100644 --- a/megameklab/src/megameklab/ui/battleArmor/BAMainUI.java +++ b/megameklab/src/megameklab/ui/battleArmor/BAMainUI.java @@ -38,10 +38,8 @@ public class BAMainUI extends MegaMekLabMainUI { private FloatingEquipmentDatabaseDialog floatingEquipmentDatabase; public BAMainUI() { - super(); createNewUnit(Entity.ETYPE_BATTLEARMOR); - setTitle(getEntity().getChassis() + " " + getEntity().getModel() + ".blk"); finishSetup(); } @@ -113,9 +111,7 @@ public void refreshAll() { } @Override - public void refreshArmor() { - - } + public void refreshArmor() { } @Override public void refreshBuild() { @@ -132,11 +128,6 @@ public void refreshTransport() { // not used for ba } - @Override - public void refreshHeader() { - setTitle(getEntity().getChassis() + " " + getEntity().getModel() + ".blk"); - } - @Override public void refreshStatus() { statusbar.refresh(); @@ -148,8 +139,7 @@ public void refreshStructure() { } @Override - public void refreshWeapons() { - } + public void refreshWeapons() { } @Override public void refreshPreview() { @@ -157,8 +147,7 @@ public void refreshPreview() { } @Override - public void refreshSummary() { - } + public void refreshSummary() { } @Override public void refreshEquipmentTable() { @@ -168,22 +157,10 @@ public void refreshEquipmentTable() { @Override public ITechManager getTechManager() { - if (structureTab != null) { - return structureTab.getTechManager(); - } - return null; + return (structureTab != null) ? structureTab.getTechManager() : null; } public JDialog getFloatingEquipmentDatabase() { return floatingEquipmentDatabase; } - - @Override - public void setVisible(boolean b) { - super.setVisible(b); - if (!b && (floatingEquipmentDatabase != null)) { - floatingEquipmentDatabase.setVisible(false); - } - } - } \ No newline at end of file diff --git a/megameklab/src/megameklab/ui/combatVehicle/CVMainUI.java b/megameklab/src/megameklab/ui/combatVehicle/CVMainUI.java index 777263be1..e5c2a4c62 100644 --- a/megameklab/src/megameklab/ui/combatVehicle/CVMainUI.java +++ b/megameklab/src/megameklab/ui/combatVehicle/CVMainUI.java @@ -44,7 +44,6 @@ public class CVMainUI extends MegaMekLabMainUI { public CVMainUI() { super(); createNewUnit(Entity.ETYPE_TANK, false, false); - setTitle(getEntity().getChassis() + " " + getEntity().getModel() + ".blk"); finishSetup(); } @@ -100,9 +99,7 @@ public void refreshAll() { } @Override - public void refreshArmor() { - - } + public void refreshArmor() { } @Override public void refreshBuild() { @@ -119,11 +116,6 @@ public void refreshTransport() { // not used for vees } - @Override - public void refreshHeader() { - setTitle(getEntity().getChassis() + " " + getEntity().getModel() + ".blk"); - } - @Override public void refreshStatus() { statusbar.refresh(); @@ -135,8 +127,7 @@ public void refreshStructure() { } @Override - public void refreshWeapons() { - } + public void refreshWeapons() { } @Override public void createNewUnit(long entityType, boolean isPrimitive, boolean isIndustrial, Entity oldEntity) { @@ -226,13 +217,4 @@ public ITechManager getTechManager() { public JDialog getFloatingEquipmentDatabase() { return floatingEquipmentDatabase; } - - @Override - public void setVisible(boolean b) { - super.setVisible(b); - if (!b && (floatingEquipmentDatabase != null)) { - floatingEquipmentDatabase.setVisible(false); - } - } - } \ No newline at end of file diff --git a/megameklab/src/megameklab/ui/combatVehicle/CVStructureTab.java b/megameklab/src/megameklab/ui/combatVehicle/CVStructureTab.java index e8a2f7222..28bafd92b 100644 --- a/megameklab/src/megameklab/ui/combatVehicle/CVStructureTab.java +++ b/megameklab/src/megameklab/ui/combatVehicle/CVStructureTab.java @@ -21,6 +21,7 @@ import megamek.common.verifier.TestEntity; import megamek.common.verifier.TestTank; import megameklab.ui.EntitySource; +import megameklab.ui.PopupMessages; import megameklab.ui.generalUnit.*; import megameklab.ui.listeners.ArmorAllocationListener; import megameklab.ui.listeners.CVBuildListener; diff --git a/megameklab/src/megameklab/ui/dialog/MMLFileChooser.java b/megameklab/src/megameklab/ui/dialog/MMLFileChooser.java index a3a1c7a2b..51a2867cb 100644 --- a/megameklab/src/megameklab/ui/dialog/MMLFileChooser.java +++ b/megameklab/src/megameklab/ui/dialog/MMLFileChooser.java @@ -32,7 +32,7 @@ public class MMLFileChooser extends JFileChooser { public MMLFileChooser() { - super(CConfig.getParam(CConfig.LAST_DIRECTORY)); + super(CConfig.getParam(CConfig.FILE_LAST_DIRECTORY)); } @Override @@ -45,7 +45,7 @@ protected JDialog createDialog(Component parent) throws HeadlessException { public void windowClosed(WindowEvent e) { CConfig.writeFileChooserSettings(dialog); if (getCurrentDirectory().exists()) { - CConfig.setParam(CConfig.LAST_DIRECTORY, getCurrentDirectory().toString()); + CConfig.setParam(CConfig.FILE_LAST_DIRECTORY, getCurrentDirectory().toString()); } super.windowClosed(e); } diff --git a/megameklab/src/megameklab/ui/dialog/UiLoader.java b/megameklab/src/megameklab/ui/dialog/UiLoader.java index 332d8cd7b..e68604095 100644 --- a/megameklab/src/megameklab/ui/dialog/UiLoader.java +++ b/megameklab/src/megameklab/ui/dialog/UiLoader.java @@ -21,6 +21,7 @@ import megamek.client.ui.swing.util.UIUtil; import megamek.common.*; import megameklab.ui.MegaMekLabMainUI; +import megameklab.ui.PopupMessages; import megameklab.ui.battleArmor.BAMainUI; import megameklab.ui.combatVehicle.CVMainUI; import megameklab.ui.fighterAero.ASMainUI; @@ -35,6 +36,7 @@ import javax.swing.*; import java.awt.*; import java.util.Map; +import java.util.Objects; import java.util.ResourceBundle; import java.util.TreeMap; @@ -62,48 +64,50 @@ public class UiLoader { private final boolean primitive; private final boolean industrial; private final Entity newUnit; + private final String fileName; - public static void loadUi(Entity newUnit) { + public static void loadUi(Entity newUnit, String fileName) { if ((newUnit == null) || (newUnit instanceof Mech)) { - new UiLoader(Entity.ETYPE_MECH, false, false, newUnit).show(); + new UiLoader(Entity.ETYPE_MECH, false, false, newUnit, fileName).show(); } else if (newUnit.isSupportVehicle()) { - new UiLoader(Entity.ETYPE_SUPPORT_TANK, false, false, newUnit).show(); + new UiLoader(Entity.ETYPE_SUPPORT_TANK, false, false, newUnit, fileName).show(); } else if (newUnit.hasETypeFlag(Entity.ETYPE_SMALL_CRAFT)) { - new UiLoader(Entity.ETYPE_DROPSHIP, newUnit.isPrimitive(), false, newUnit).show(); + new UiLoader(Entity.ETYPE_DROPSHIP, newUnit.isPrimitive(), false, newUnit, fileName).show(); } else if (newUnit.hasETypeFlag(Entity.ETYPE_JUMPSHIP)) { - new UiLoader(Entity.ETYPE_JUMPSHIP, newUnit.isPrimitive(), false, newUnit).show(); + new UiLoader(Entity.ETYPE_JUMPSHIP, newUnit.isPrimitive(), false, newUnit, fileName).show(); } else if ((newUnit instanceof Aero) && !(newUnit instanceof FixedWingSupport)) { - new UiLoader(Entity.ETYPE_AERO, newUnit.isPrimitive(), false, newUnit).show(); + new UiLoader(Entity.ETYPE_AERO, newUnit.isPrimitive(), false, newUnit, fileName).show(); } else if (newUnit instanceof BattleArmor) { - new UiLoader(Entity.ETYPE_BATTLEARMOR, false, false, newUnit).show(); + new UiLoader(Entity.ETYPE_BATTLEARMOR, false, false, newUnit, fileName).show(); } else if (newUnit instanceof Infantry) { - new UiLoader(Entity.ETYPE_INFANTRY, false, false, newUnit).show(); + new UiLoader(Entity.ETYPE_INFANTRY, false, false, newUnit, fileName).show(); } else if (newUnit instanceof Protomech) { - new UiLoader(Entity.ETYPE_PROTOMECH, false, false, newUnit).show(); + new UiLoader(Entity.ETYPE_PROTOMECH, false, false, newUnit, fileName).show(); } else if ((newUnit instanceof Tank) && !(newUnit instanceof GunEmplacement)) { - new UiLoader(Entity.ETYPE_TANK, false, false, newUnit).show(); + new UiLoader(Entity.ETYPE_TANK, false, false, newUnit, fileName).show(); } else { - JOptionPane.showMessageDialog(null, RESOURCES.getString("message.abortUnitLoad.text")); - new UiLoader(Entity.ETYPE_MECH, false, false, null).show(); + PopupMessages.showUiLoadError(null); + new UiLoader(Entity.ETYPE_MECH, false, false, null, "").show(); } } public static void loadUi(long type, boolean primitive, boolean industrial) { - new UiLoader(type, primitive, industrial, null).show(); + new UiLoader(type, primitive, industrial, null, "").show(); } /** - * - * @param type - the unit type to load the mainUI from, based on the types in StartupGUI.java - * @param primitive - is unit primitive + * @param type - the unit type to load the mainUI from, based on the types in StartupGUI.java + * @param primitive - is unit primitive * @param industrial - is unit industrial - * @param newUnit - a specific Entity to load in rather than default + * @param newUnit - a specific Entity to load in rather than default + * @param fileName - the file name of the new unit; empty String if the unit has no file */ - private UiLoader(long type, boolean primitive, boolean industrial, Entity newUnit) { + private UiLoader(long type, boolean primitive, boolean industrial, Entity newUnit, String fileName) { this.type = type; this.primitive = primitive; this.industrial = industrial; this.newUnit = newUnit; + this.fileName = Objects.requireNonNullElse(fileName, ""); splashImage = new JDialog((JFrame) null, "MML Loading Splash"); splashImage.setUndecorated(true); @@ -122,7 +126,7 @@ private void loadNewUi() { MegaMekLabMainUI newUI = getUI(type, primitive, industrial); if (newUnit != null) { UnitUtil.updateLoadedUnit(newUnit); - newUI.setEntity(newUnit); + newUI.setEntity(newUnit, fileName); newUI.reloadTabs(); newUI.refreshAll(); } diff --git a/megameklab/src/megameklab/ui/dialog/settings/ColorSettingsPanel.java b/megameklab/src/megameklab/ui/dialog/settings/ColorSettingsPanel.java index e256a0f91..cabb2677e 100644 --- a/megameklab/src/megameklab/ui/dialog/settings/ColorSettingsPanel.java +++ b/megameklab/src/megameklab/ui/dialog/settings/ColorSettingsPanel.java @@ -37,12 +37,12 @@ public class ColorSettingsPanel extends JPanel { private final Map allColors = new HashMap<>(); ColorSettingsPanel() { - addColorRow(CConfig.COLOR_WEAPONS); - addColorRow(CConfig.COLOR_EQUIPMENT); - addColorRow(CConfig.COLOR_AMMO); - addColorRow(CConfig.COLOR_SYSTEMS); - addColorRow(CConfig.COLOR_NONHITTABLE); - addColorRow(CConfig.COLOR_EMPTY); + addColorRow(CConfig.GUI_COLOR_WEAPONS); + addColorRow(CConfig.GUI_COLOR_EQUIPMENT); + addColorRow(CConfig.GUI_COLOR_AMMO); + addColorRow(CConfig.GUI_COLOR_SYSTEMS); + addColorRow(CConfig.GUI_COLOR_NONHITTABLE); + addColorRow(CConfig.GUI_COLOR_EMPTY); SpringUtilities.makeCompactGrid(gridPanel, 6, 4, 0, 0, 15, 10); setLayout(new FlowLayout(FlowLayout.LEFT)); setBorder(new EmptyBorder(20, 30, 20, 30)); @@ -61,11 +61,11 @@ private void addColorRow(String colorType) { JButton foregroundButton = new JButton("Foreground"); foregroundButton.addActionListener(e -> - callColorChooser(colorType, CConfig.CONFIG_FOREGROUND, coloredExample)); + callColorChooser(colorType, CConfig.GUI_FOREGROUND, coloredExample)); JButton backgroundButton = new JButton("Background"); backgroundButton.addActionListener(e -> - callColorChooser(colorType, CConfig.CONFIG_BACKGROUND, coloredExample)); + callColorChooser(colorType, CConfig.GUI_BACKGROUND, coloredExample)); gridPanel.add(typeLabel); gridPanel.add(foregroundButton); @@ -75,15 +75,15 @@ private void addColorRow(String colorType) { private String exampleText(String colorType) { switch (colorType) { - case CConfig.COLOR_WEAPONS: + case CConfig.GUI_COLOR_WEAPONS: return "Medium Pulse Laser"; - case CConfig.COLOR_EQUIPMENT: + case CConfig.GUI_COLOR_EQUIPMENT: return "Heat Sink"; - case CConfig.COLOR_AMMO: + case CConfig.GUI_COLOR_AMMO: return "AC/5 Ammo"; - case CConfig.COLOR_SYSTEMS: + case CConfig.GUI_COLOR_SYSTEMS: return "XL Engine"; - case CConfig.COLOR_NONHITTABLE: + case CConfig.GUI_COLOR_NONHITTABLE: return "Endo Steel"; default: return CritCellUtil.EMPTY_CRITCELL_TEXT; @@ -91,10 +91,10 @@ private String exampleText(String colorType) { } private void callColorChooser(String type, String fgOrBg, JLabel exampleLabel) { - Color preset = fgOrBg.equals(CConfig.CONFIG_BACKGROUND) ? exampleLabel.getBackground() : exampleLabel.getForeground(); + Color preset = fgOrBg.equals(CConfig.GUI_BACKGROUND) ? exampleLabel.getBackground() : exampleLabel.getForeground(); Color newColor = JColorChooser.showDialog(this, "Choose a color", preset); if (newColor != null) { - if (fgOrBg.equals(CConfig.CONFIG_BACKGROUND)) { + if (fgOrBg.equals(CConfig.GUI_BACKGROUND)) { exampleLabel.setBackground(newColor); } else { exampleLabel.setForeground(newColor); diff --git a/megameklab/src/megameklab/ui/dialog/settings/MiscSettingsPanel.java b/megameklab/src/megameklab/ui/dialog/settings/MiscSettingsPanel.java index 0e894df4f..7f0e2fe2c 100644 --- a/megameklab/src/megameklab/ui/dialog/settings/MiscSettingsPanel.java +++ b/megameklab/src/megameklab/ui/dialog/settings/MiscSettingsPanel.java @@ -18,7 +18,12 @@ */ package megameklab.ui.dialog.settings; +import megamek.MMConstants; +import megamek.client.ui.Messages; import megamek.client.ui.baseComponents.MMComboBox; +import megamek.client.ui.swing.CommonSettingsDialog; +import megamek.client.ui.swing.HelpDialog; +import megamek.common.preference.PreferenceManager; import megameklab.ui.MMLStartUp; import megameklab.ui.util.SpringUtilities; import megameklab.util.CConfig; @@ -45,21 +50,22 @@ public class MiscSettingsPanel extends JPanel { private final JCheckBox chkSkipSavePrompts = new JCheckBox(); private final JTextField txtUserDir = new JTextField(20); - MiscSettingsPanel() { + MiscSettingsPanel(JFrame parent) { startUpMMComboBox.setRenderer(startUpRenderer); startUpMMComboBox.setSelectedItem(CConfig.getStartUpType()); startUpMMComboBox.setToolTipText(resources.getString("ConfigurationDialog.startup.tooltip")); JLabel startUpLabel = new JLabel(resources.getString("ConfigurationDialog.startup.text")); startUpLabel.setToolTipText(resources.getString("ConfigurationDialog.startup.tooltip")); - MiscSettingsPanel(JFrame parent) { ResourceBundle resourceMap = ResourceBundle.getBundle("megameklab.resources.Dialogs"); - JPanel startUpLine = new JPanel(); + JPanel startUpLine = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); startUpLine.add(startUpLabel); + startUpLine.add(Box.createHorizontalStrut(5)); startUpLine.add(startUpMMComboBox); chkSummaryFormatTRO.setText(resources.getString("ConfigurationDialog.chkSummaryFormatTRO.text")); chkSummaryFormatTRO.setToolTipText(resources.getString("ConfigurationDialog.chkSummaryFormatTRO.tooltip")); + JLabel userDirLabel = new JLabel(resourceMap.getString("ConfigurationDialog.userDir.text")); userDirLabel.setToolTipText(resourceMap.getString("ConfigurationDialog.userDir.tooltip")); txtUserDir.setToolTipText(resourceMap.getString("ConfigurationDialog.userDir.tooltip")); @@ -78,7 +84,7 @@ public class MiscSettingsPanel extends JPanel { } JPanel userDirLine = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); userDirLine.add(userDirLabel); - userDirLine.add(Box.createHorizontalStrut(25)); + userDirLine.add(Box.createHorizontalStrut(5)); userDirLine.add(txtUserDir); userDirLine.add(Box.createHorizontalStrut(10)); userDirLine.add(userDirChooser); @@ -99,7 +105,7 @@ public class MiscSettingsPanel extends JPanel { gridPanel.add(chkSummaryFormatTRO); gridPanel.add(chkSkipSavePrompts); - SpringUtilities.makeCompactGrid(gridPanel, 3, 1, 0, 0, 15, 10); + SpringUtilities.makeCompactGrid(gridPanel, 4, 1, 0, 0, 15, 10); gridPanel.setBorder(new EmptyBorder(20, 30, 20, 30)); setLayout(new FlowLayout(FlowLayout.LEFT)); add(gridPanel); @@ -112,23 +118,23 @@ Map getMiscSettings() { MMLStartUp startUp = startUpMMComboBox.getSelectedItem() == null ? MMLStartUp.SPLASH_SCREEN : startUpMMComboBox.getSelectedItem(); - miscSettings.put(CConfig.STARTUP, startUp.name()); + miscSettings.put(CConfig.MISC_STARTUP, startUp.name()); + // The user directory is stored in MM's client settings, not in CConfig, therefore not added here return miscSettings; } String getUserDir() { return txtUserDir.getText(); } -} DefaultListCellRenderer startUpRenderer = new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - if (value instanceof MMLStartUp) { - value = ((MMLStartUp) value).getDisplayName(); - } - return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + return super.getListCellRendererComponent(list, displayName(value), index, isSelected, cellHasFocus); } }; + private String displayName(Object value) { + return (value instanceof MMLStartUp) ? ((MMLStartUp) value).getDisplayName() : ""; + } } \ No newline at end of file diff --git a/megameklab/src/megameklab/ui/fighterAero/ASCriticalView.java b/megameklab/src/megameklab/ui/fighterAero/ASCriticalView.java index 0bfb2a696..eae64473d 100644 --- a/megameklab/src/megameklab/ui/fighterAero/ASCriticalView.java +++ b/megameklab/src/megameklab/ui/fighterAero/ASCriticalView.java @@ -17,6 +17,7 @@ import megamek.common.*; import megamek.common.verifier.TestAero; import megameklab.ui.EntitySource; +import megameklab.ui.PopupMessages; import megameklab.ui.util.BAASBMDropTargetCriticalList; import megameklab.ui.util.CritCellUtil; import megameklab.ui.util.IView; @@ -210,8 +211,7 @@ private void copyLocation(int from, int to) { try { UnitUtil.copyLocationEquipment(getAero(), from, to); } catch (LocationFullException ex) { - JOptionPane.showMessageDialog(this, "Insufficient space", "Location Full", - JOptionPane.WARNING_MESSAGE); + PopupMessages.showLocationFullError(null); } refreshListener.scheduleRefresh(); } diff --git a/megameklab/src/megameklab/ui/fighterAero/ASMainUI.java b/megameklab/src/megameklab/ui/fighterAero/ASMainUI.java index dcad603ef..d45435202 100644 --- a/megameklab/src/megameklab/ui/fighterAero/ASMainUI.java +++ b/megameklab/src/megameklab/ui/fighterAero/ASMainUI.java @@ -42,10 +42,8 @@ public class ASMainUI extends MegaMekLabMainUI { private FloatingEquipmentDatabaseDialog floatingEquipmentDatabase; public ASMainUI(boolean primitive) { - super(); createNewUnit(Entity.ETYPE_AERO, primitive); - setTitle(getEntity().getChassis() + " " + getEntity().getModel() + ".blk"); finishSetup(); } @@ -161,7 +159,6 @@ public void refreshBuild() { @Override public void refreshEquipment() { equipmentTab.refresh(); - } @Override @@ -175,14 +172,6 @@ public void refreshPreview() { } - @Override - public void refreshHeader() { - - String title = getEntity().getChassis() + " " + getEntity().getModel() + ".blk"; - setTitle(title); - - } - @Override public void refreshStatus() { statusbar.refresh(); @@ -194,8 +183,7 @@ public void refreshStructure() { } @Override - public void refreshWeapons() { - } + public void refreshWeapons() { } @Override public void refreshSummary() { @@ -216,13 +204,4 @@ public ITechManager getTechManager() { public JDialog getFloatingEquipmentDatabase() { return floatingEquipmentDatabase; } - - @Override - public void setVisible(boolean b) { - super.setVisible(b); - if (!b && (floatingEquipmentDatabase != null)) { - floatingEquipmentDatabase.setVisible(false); - } - } - } \ No newline at end of file diff --git a/megameklab/src/megameklab/ui/infantry/CIMainUI.java b/megameklab/src/megameklab/ui/infantry/CIMainUI.java index aea71935e..248862181 100644 --- a/megameklab/src/megameklab/ui/infantry/CIMainUI.java +++ b/megameklab/src/megameklab/ui/infantry/CIMainUI.java @@ -23,6 +23,7 @@ import megamek.common.*; import megamek.common.weapons.infantry.InfantryWeapon; import megameklab.ui.MegaMekLabMainUI; +import megameklab.ui.PopupMessages; import megameklab.ui.generalUnit.PreviewTab; import megameklab.ui.generalUnit.FluffTab; import megameklab.ui.util.TabScrollPane; @@ -38,7 +39,6 @@ public class CIMainUI extends MegaMekLabMainUI { public CIMainUI() { super(); createNewUnit(Entity.ETYPE_INFANTRY); - setTitle(getEntity().getChassis() + " " + getEntity().getModel() + ".mtf"); finishSetup(); } @@ -74,12 +74,11 @@ public void createNewUnit(long entityType, boolean isPrimitive, boolean isIndust getEntity().setArmorTechLevel(TechConstants.T_IS_TW_NON_BOX); ((Infantry) getEntity()).setSquadCount(4); ((Infantry) getEntity()).setSquadSize(7); - ((Infantry) getEntity()).setPrimaryWeapon((InfantryWeapon) EquipmentType - .get("InfantryAssaultRifle")); + ((Infantry) getEntity()).setPrimaryWeapon((InfantryWeapon) EquipmentType.get("InfantryAssaultRifle")); try { - getEntity().addEquipment(EquipmentType.get(EquipmentTypeLookup.INFANTRY_ASSAULT_RIFLE), - Infantry.LOC_INFANTRY); + getEntity().addEquipment(EquipmentType.get(EquipmentTypeLookup.INFANTRY_ASSAULT_RIFLE), Infantry.LOC_INFANTRY); } catch (LocationFullException ex) { + PopupMessages.showLocationFullError(this, EquipmentType.get("InfantryAssaultRifle").getName()); } getEntity().autoSetInternal(); getEntity().setChassis("New"); @@ -94,33 +93,19 @@ public void refreshAll() { } @Override - public void refreshArmor() { - // armorTab.refresh(); - } + public void refreshArmor() { } @Override - public void refreshBuild() { - - } + public void refreshBuild() { } @Override - public void refreshEquipment() { - - } + public void refreshEquipment() { } @Override public void refreshTransport() { // not used for infantry } - @Override - public void refreshHeader() { - String title = getEntity().getChassis() + " " + getEntity().getModel() - + ".blk"; - setTitle(title); - - } - @Override public void refreshStatus() { statusbar.refresh(); @@ -129,13 +114,10 @@ public void refreshStatus() { @Override public void refreshStructure() { structureTab.refresh(); - } @Override - public void refreshWeapons() { - // weaponTab.refresh(); - } + public void refreshWeapons() { } @Override public void refreshPreview() { @@ -148,8 +130,7 @@ public JDialog getFloatingEquipmentDatabase() { } @Override - public void refreshSummary() { - } + public void refreshSummary() { } @Override public void refreshEquipmentTable() { @@ -163,5 +144,4 @@ public ITechManager getTechManager() { } return null; } - -} +} \ No newline at end of file diff --git a/megameklab/src/megameklab/ui/largeAero/DSMainUI.java b/megameklab/src/megameklab/ui/largeAero/DSMainUI.java index 3499c03bc..cc4c3fc5b 100644 --- a/megameklab/src/megameklab/ui/largeAero/DSMainUI.java +++ b/megameklab/src/megameklab/ui/largeAero/DSMainUI.java @@ -43,7 +43,6 @@ public class DSMainUI extends MegaMekLabMainUI { public DSMainUI(boolean primitive) { super(); createNewUnit(Entity.ETYPE_DROPSHIP, primitive, false); - setTitle(getEntity().getChassis() + " " + getEntity().getModel() + ".blk"); finishSetup(); MechSummaryCache.getInstance(); } @@ -125,7 +124,7 @@ public void createNewUnit(long entitytype, boolean isPrimitive, boolean isIndust smallCraft.setTechLevel(lvl.getCompoundTechLevel(oldUnit.isClan())); smallCraft.setMixedTech(oldUnit.isMixedTech()); - smallCraft.setSpheroid(((SmallCraft) oldUnit).isSpheroid()); + smallCraft.setSpheroid(oldUnit.isSpheroid()); smallCraft.setMovementMode(oldUnit.getMovementMode()); } } @@ -189,8 +188,7 @@ public void refreshAll() { } @Override - public void refreshArmor() { - } + public void refreshArmor() { } @Override public void refreshBuild() { @@ -202,12 +200,6 @@ public void refreshEquipment() { equipmentTab.refresh(); } - @Override - public void refreshHeader() { - String title = getEntity().getChassis() + " " + getEntity().getModel() + ".blk"; - setTitle(title); - } - @Override public void refreshStatus() { statusbar.refresh(); @@ -219,8 +211,7 @@ public void refreshStructure() { } @Override - public void refreshWeapons() { - } + public void refreshWeapons() { } @Override public void refreshPreview() { @@ -230,12 +221,4 @@ public void refreshPreview() { public JDialog getFloatingEquipmentDatabase() { return floatingEquipmentDatabase; } - - @Override - public void setVisible(boolean b) { - super.setVisible(b); - if (!b && (floatingEquipmentDatabase != null)) { - floatingEquipmentDatabase.setVisible(false); - } - } -} +} \ No newline at end of file diff --git a/megameklab/src/megameklab/ui/largeAero/LACriticalView.java b/megameklab/src/megameklab/ui/largeAero/LACriticalView.java index cf5e4f0f0..2aac9047e 100644 --- a/megameklab/src/megameklab/ui/largeAero/LACriticalView.java +++ b/megameklab/src/megameklab/ui/largeAero/LACriticalView.java @@ -25,6 +25,7 @@ import megamek.common.verifier.TestEntity; import megamek.common.verifier.TestSmallCraft; import megameklab.ui.EntitySource; +import megameklab.ui.PopupMessages; import megameklab.ui.util.BayWeaponCriticalTree; import megameklab.ui.util.CritCellUtil; import megameklab.ui.util.IView; @@ -264,8 +265,7 @@ private void copyLocation(int from, int to, boolean forward, boolean rear) { try { UnitUtil.copyLocationEquipment(getAero(), from, to, forward, rear); } catch (LocationFullException ex) { - JOptionPane.showMessageDialog(this, "Insufficient space", "Location Full", - JOptionPane.WARNING_MESSAGE); + PopupMessages.showLocationFullError(null); } if (null != refresh) { refresh.refreshAll(); diff --git a/megameklab/src/megameklab/ui/largeAero/WSMainUI.java b/megameklab/src/megameklab/ui/largeAero/WSMainUI.java index 2d050c89c..c1109a92c 100644 --- a/megameklab/src/megameklab/ui/largeAero/WSMainUI.java +++ b/megameklab/src/megameklab/ui/largeAero/WSMainUI.java @@ -48,7 +48,6 @@ public WSMainUI(boolean primitive) { } else { createNewUnit(Entity.ETYPE_WARSHIP, true, false); } - setTitle(getEntity().getChassis() + " " + getEntity().getModel() + ".blk"); finishSetup(); MechSummaryCache.getInstance(); } @@ -205,8 +204,7 @@ public void refreshAll() { } @Override - public void refreshArmor() { - } + public void refreshArmor() { } @Override public void refreshBuild() { @@ -218,12 +216,6 @@ public void refreshEquipment() { equipmentTab.refresh(); } - @Override - public void refreshHeader() { - String title = getEntity().getChassis() + " " + getEntity().getModel() + ".blk"; - setTitle(title); - } - @Override public void refreshStatus() { statusbar.refresh(); @@ -235,8 +227,7 @@ public void refreshStructure() { } @Override - public void refreshWeapons() { - } + public void refreshWeapons() { } @Override public void refreshPreview() { @@ -246,12 +237,4 @@ public void refreshPreview() { public JDialog getFloatingEquipmentDatabase() { return floatingEquipmentDatabase; } - - @Override - public void setVisible(boolean b) { - super.setVisible(b); - if (!b && (floatingEquipmentDatabase != null)) { - floatingEquipmentDatabase.setVisible(false); - } - } -} +} \ No newline at end of file diff --git a/megameklab/src/megameklab/ui/mek/BMCriticalTransferHandler.java b/megameklab/src/megameklab/ui/mek/BMCriticalTransferHandler.java index 7088b85b0..b9ecfcad5 100644 --- a/megameklab/src/megameklab/ui/mek/BMCriticalTransferHandler.java +++ b/megameklab/src/megameklab/ui/mek/BMCriticalTransferHandler.java @@ -22,6 +22,7 @@ import megamek.common.*; import megamek.common.verifier.TestEntity; import megameklab.ui.EntitySource; +import megameklab.ui.PopupMessages; import megameklab.ui.util.AbstractCriticalTransferHandler; import megameklab.ui.util.BAASBMDropTargetCriticalList; import megameklab.ui.util.CriticalTableModel; @@ -218,10 +219,7 @@ public boolean importData(TransferSupport info) { StringBuffer errors = new StringBuffer(); if (!TestEntity.isValidLocation(getUnit(), eq.getType(), location, errors)) { - JOptionPane.showMessageDialog(null, eq.getName() + - " can't be placed in " + getUnit().getLocationAbbr(location) + ":\n" - + errors, - "Invalid Location", JOptionPane.INFORMATION_MESSAGE); + PopupMessages.showInvalidLocationInfo(null, eq.getName(), getUnit().getLocationName(location)); doRefresh(); return false; } @@ -248,8 +246,7 @@ public boolean importData(TransferSupport info) { } return addEquipmentMech((Mech) getUnit(), eq, slotNumber); } catch (LocationFullException lfe) { - JOptionPane.showMessageDialog(null, lfe.getMessage(), - "Location Full", JOptionPane.INFORMATION_MESSAGE); + PopupMessages.showLocationFullError(null); doRefresh(); return false; } catch (Exception ex) { diff --git a/megameklab/src/megameklab/ui/mek/BMMainUI.java b/megameklab/src/megameklab/ui/mek/BMMainUI.java index c4dd2e6ec..1858be618 100644 --- a/megameklab/src/megameklab/ui/mek/BMMainUI.java +++ b/megameklab/src/megameklab/ui/mek/BMMainUI.java @@ -26,8 +26,6 @@ import megameklab.util.UnitUtil; import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; import java.awt.*; public class BMMainUI extends MegaMekLabMainUI { @@ -42,14 +40,9 @@ public class BMMainUI extends MegaMekLabMainUI { private QuirksTab quirksTab; private FloatingEquipmentDatabaseDialog floatingEquipmentDatabase; - public BMMainUI() { - this(false, false); - } - public BMMainUI(boolean primitive, boolean industrial) { super(); createNewUnit(Entity.ETYPE_BIPED_MECH, primitive, industrial); - setTitle(getEntity().getChassis() + " " + getEntity().getModel() + ".mtf"); finishSetup(); } @@ -188,8 +181,7 @@ public void refreshAll() { } @Override - public void refreshArmor() { - } + public void refreshArmor() { } @Override public void refreshBuild() { @@ -209,11 +201,6 @@ public void refreshPreview() { previewTab.refresh(); } - @Override - public void refreshHeader() { - setTitle(getEntity().getChassis() + " " + getEntity().getModel() + ".mtf"); - } - @Override public void refreshStatus() { statusbar.refresh(); @@ -247,13 +234,4 @@ public ITechManager getTechManager() { public JDialog getFloatingEquipmentDatabase() { return floatingEquipmentDatabase; } - - @Override - public void setVisible(boolean b) { - super.setVisible(b); - if (!b && (floatingEquipmentDatabase != null)) { - floatingEquipmentDatabase.setVisible(false); - } - } - } \ No newline at end of file diff --git a/megameklab/src/megameklab/ui/protoMek/PMEquipmentDatabaseView.java b/megameklab/src/megameklab/ui/protoMek/PMEquipmentDatabaseView.java index 8c1ba751d..0b4328785 100644 --- a/megameklab/src/megameklab/ui/protoMek/PMEquipmentDatabaseView.java +++ b/megameklab/src/megameklab/ui/protoMek/PMEquipmentDatabaseView.java @@ -17,11 +17,11 @@ import megamek.common.*; import megamek.common.verifier.TestEntity; import megameklab.ui.EntitySource; +import megameklab.ui.PopupMessages; import megameklab.ui.util.AbstractEquipmentDatabaseView; import megameklab.util.UnitUtil; import org.apache.logging.log4j.LogManager; -import javax.swing.*; import java.util.Collection; import java.util.List; @@ -60,10 +60,8 @@ protected void addEquipment(EquipmentType equip, int count) { UnitUtil.removeHiddenAmmo(mount); } } catch (LocationFullException ex) { + PopupMessages.showLocationFullError(this, equip.getName()); LogManager.getLogger().error("Location full while trying to add " + equip.getName()); - JOptionPane.showMessageDialog( - this, "Could not add " + equip.getName(), - "Location Full", JOptionPane.ERROR_MESSAGE); } } diff --git a/megameklab/src/megameklab/ui/protoMek/PMMainUI.java b/megameklab/src/megameklab/ui/protoMek/PMMainUI.java index 92f2436b6..a0534f1c7 100644 --- a/megameklab/src/megameklab/ui/protoMek/PMMainUI.java +++ b/megameklab/src/megameklab/ui/protoMek/PMMainUI.java @@ -45,7 +45,6 @@ public class PMMainUI extends MegaMekLabMainUI { public PMMainUI() { super(); createNewUnit(Entity.ETYPE_PROTOMECH); - setTitle(getEntity().getChassis() + " " + getEntity().getModel() + ".blk"); finishSetup(); } @@ -157,12 +156,6 @@ public void refreshPreview() { previewTab.refresh(); } - @Override - public void refreshHeader() { - String title = getEntity().getChassis() + " " + getEntity().getModel() + ".blk"; - setTitle(title); - } - @Override public void refreshStatus() { statusbar.refresh(); @@ -174,8 +167,7 @@ public void refreshStructure() { } @Override - public void refreshWeapons() { - } + public void refreshWeapons() { } @Override public void refreshSummary() { @@ -196,12 +188,4 @@ public ITechManager getTechManager() { public JDialog getFloatingEquipmentDatabase() { return floatingEquipmentDatabase; } - - @Override - public void setVisible(boolean b) { - super.setVisible(b); - if (!b && (floatingEquipmentDatabase != null)) { - floatingEquipmentDatabase.setVisible(false); - } - } -} +} \ No newline at end of file diff --git a/megameklab/src/megameklab/ui/supportVehicle/SVMainUI.java b/megameklab/src/megameklab/ui/supportVehicle/SVMainUI.java index f44b0326e..80ff6d48d 100644 --- a/megameklab/src/megameklab/ui/supportVehicle/SVMainUI.java +++ b/megameklab/src/megameklab/ui/supportVehicle/SVMainUI.java @@ -46,7 +46,6 @@ public class SVMainUI extends MegaMekLabMainUI { public SVMainUI() { super(); createNewUnit(Entity.ETYPE_SUPPORT_TANK, false, false); - setTitle(getEntity().getChassis() + " " + getEntity().getModel() + ".blk"); finishSetup(); } @@ -128,15 +127,10 @@ public void refreshTransport() { transportTab.addRefreshedListener(this); int idx = configPane.indexOfTab("Transport"); configPane.removeTabAt(idx); - configPane.insertTab("Transport", null, new TabScrollPane(transportTab), null,idx); + configPane.insertTab("Transport", null, new TabScrollPane(transportTab), null, idx); transportTab.refresh(); } - @Override - public void refreshHeader() { - setTitle(getEntity().getChassis() + " " + getEntity().getModel() + ".blk"); - } - @Override public void refreshStatus() { statusbar.refresh(); @@ -236,12 +230,4 @@ public ITechManager getTechManager() { public JDialog getFloatingEquipmentDatabase() { return floatingEquipmentDatabase; } - - @Override - public void setVisible(boolean b) { - super.setVisible(b); - if (!b && (floatingEquipmentDatabase != null)) { - floatingEquipmentDatabase.setVisible(false); - } - } -} +} \ No newline at end of file diff --git a/megameklab/src/megameklab/ui/util/BAASCriticalTransferHandler.java b/megameklab/src/megameklab/ui/util/BAASCriticalTransferHandler.java index bd5b29bf1..e49e279db 100644 --- a/megameklab/src/megameklab/ui/util/BAASCriticalTransferHandler.java +++ b/megameklab/src/megameklab/ui/util/BAASCriticalTransferHandler.java @@ -23,6 +23,7 @@ import megamek.common.verifier.TestBattleArmor; import megamek.common.weapons.infantry.InfantryWeapon; import megameklab.ui.EntitySource; +import megameklab.ui.PopupMessages; import megameklab.util.UnitUtil; import org.apache.logging.log4j.LogManager; @@ -189,11 +190,7 @@ public boolean importData(TransferSupport info) { } if (!UnitUtil.isValidLocation(getUnit(), eq.getType(), location)) { - JOptionPane.showMessageDialog(null, eq.getName() + - " can't be placed in " + - getUnit().getLocationName(location) + "!", - "Invalid Location", - JOptionPane.INFORMATION_MESSAGE); + PopupMessages.showInvalidLocationInfo(null, eq.getName(), getUnit().getLocationName(location)); return false; } @@ -203,8 +200,7 @@ public boolean importData(TransferSupport info) { return addEquipmentBA((BattleArmor) getUnit(), eq, trooper); } } catch (LocationFullException lfe) { - JOptionPane.showMessageDialog(null, lfe.getMessage(), - "Location Full", JOptionPane.INFORMATION_MESSAGE); + PopupMessages.showLocationFullError(null); return false; } catch (Exception ex) { LogManager.getLogger().error("", ex); diff --git a/megameklab/src/megameklab/ui/util/BayWeaponCriticalTree.java b/megameklab/src/megameklab/ui/util/BayWeaponCriticalTree.java index f2ed83fc9..06760e77a 100644 --- a/megameklab/src/megameklab/ui/util/BayWeaponCriticalTree.java +++ b/megameklab/src/megameklab/ui/util/BayWeaponCriticalTree.java @@ -28,7 +28,6 @@ import org.apache.logging.log4j.LogManager; import javax.swing.*; -import javax.swing.JTree.DropLocation; import javax.swing.border.Border; import javax.swing.border.CompoundBorder; import javax.swing.tree.*; @@ -118,7 +117,7 @@ public void updateRefresh(RefreshListener refresh) { public void rebuild() { List expandedBays = getExpandedBayIds(); - setBackground(CConfig.getBackgroundColor(CConfig.COLOR_WEAPONS)); + setBackground(CConfig.getBackgroundColor(CConfig.GUI_COLOR_WEAPONS)); TreeNode root = initRoot(); model.setRoot(root); setRootVisible(root.getChildCount() == 0); diff --git a/megameklab/src/megameklab/ui/util/CritCellUtil.java b/megameklab/src/megameklab/ui/util/CritCellUtil.java index fc34db3c7..52b252d7e 100644 --- a/megameklab/src/megameklab/ui/util/CritCellUtil.java +++ b/megameklab/src/megameklab/ui/util/CritCellUtil.java @@ -67,20 +67,20 @@ public static void formatCell(JLabel cell, @Nullable Mounted mounted, boolean us Entity entity, int index) { if (useColor) { if (mounted == null) { - cell.setBackground(CConfig.getBackgroundColor(CConfig.COLOR_EMPTY)); - cell.setForeground(CConfig.getForegroundColor(CConfig.COLOR_EMPTY)); + cell.setBackground(CConfig.getBackgroundColor(CConfig.GUI_COLOR_EMPTY)); + cell.setForeground(CConfig.getForegroundColor(CConfig.GUI_COLOR_EMPTY)); } else if (!mounted.getType().isHittable()) { - cell.setBackground(CConfig.getBackgroundColor(CConfig.COLOR_NONHITTABLE)); - cell.setForeground(CConfig.getForegroundColor(CConfig.COLOR_NONHITTABLE)); + cell.setBackground(CConfig.getBackgroundColor(CConfig.GUI_COLOR_NONHITTABLE)); + cell.setForeground(CConfig.getForegroundColor(CConfig.GUI_COLOR_NONHITTABLE)); } else if (mounted.getType() instanceof WeaponType) { - cell.setBackground(CConfig.getBackgroundColor(CConfig.COLOR_WEAPONS)); - cell.setForeground(CConfig.getForegroundColor(CConfig.COLOR_WEAPONS)); + cell.setBackground(CConfig.getBackgroundColor(CConfig.GUI_COLOR_WEAPONS)); + cell.setForeground(CConfig.getForegroundColor(CConfig.GUI_COLOR_WEAPONS)); } else if (mounted.getType() instanceof AmmoType) { - cell.setBackground(CConfig.getBackgroundColor(CConfig.COLOR_AMMO)); - cell.setForeground(CConfig.getForegroundColor(CConfig.COLOR_AMMO)); + cell.setBackground(CConfig.getBackgroundColor(CConfig.GUI_COLOR_AMMO)); + cell.setForeground(CConfig.getForegroundColor(CConfig.GUI_COLOR_AMMO)); } else { - cell.setBackground(CConfig.getBackgroundColor(CConfig.COLOR_EQUIPMENT)); - cell.setForeground(CConfig.getForegroundColor(CConfig.COLOR_EQUIPMENT)); + cell.setBackground(CConfig.getBackgroundColor(CConfig.GUI_COLOR_EQUIPMENT)); + cell.setForeground(CConfig.getForegroundColor(CConfig.GUI_COLOR_EQUIPMENT)); } } diff --git a/megameklab/src/megameklab/ui/util/CritListCellRenderer.java b/megameklab/src/megameklab/ui/util/CritListCellRenderer.java index 3dd9a61d5..c5c03df5a 100644 --- a/megameklab/src/megameklab/ui/util/CritListCellRenderer.java +++ b/megameklab/src/megameklab/ui/util/CritListCellRenderer.java @@ -61,8 +61,8 @@ public Component getListCellRendererComponent(JList list, Object value, int i if (cs != null) { if (cs.getType() == CriticalSlot.TYPE_SYSTEM) { if (useColor) { - setBackground(CConfig.getBackgroundColor(CConfig.COLOR_SYSTEMS)); - setForeground(CConfig.getForegroundColor(CConfig.COLOR_SYSTEMS)); + setBackground(CConfig.getBackgroundColor(CConfig.GUI_COLOR_SYSTEMS)); + setForeground(CConfig.getForegroundColor(CConfig.GUI_COLOR_SYSTEMS)); } if (cs.isArmored()) { setText(getText() + " (A)"); diff --git a/megameklab/src/megameklab/ui/util/CriticalTableModel.java b/megameklab/src/megameklab/ui/util/CriticalTableModel.java index 65abc66b1..c9d41914b 100644 --- a/megameklab/src/megameklab/ui/util/CriticalTableModel.java +++ b/megameklab/src/megameklab/ui/util/CriticalTableModel.java @@ -305,14 +305,14 @@ public Component getTableCellRendererComponent(JTable table, return c; } - String equipmentType = CConfig.COLOR_EQUIPMENT; + String equipmentType = CConfig.GUI_COLOR_EQUIPMENT; if (!mount.getType().isHittable()) { - equipmentType = CConfig.COLOR_NONHITTABLE; + equipmentType = CConfig.GUI_COLOR_NONHITTABLE; } else if (mount.getType() instanceof WeaponType) { - equipmentType = CConfig.COLOR_WEAPONS; + equipmentType = CConfig.GUI_COLOR_WEAPONS; } else if (mount.getType() instanceof AmmoType) { - equipmentType = CConfig.COLOR_AMMO; + equipmentType = CConfig.GUI_COLOR_AMMO; } c.setBackground(CConfig.getBackgroundColor(equipmentType)); diff --git a/megameklab/src/megameklab/ui/util/CriticalTransferHandler.java b/megameklab/src/megameklab/ui/util/CriticalTransferHandler.java index a6810b40b..28835b168 100644 --- a/megameklab/src/megameklab/ui/util/CriticalTransferHandler.java +++ b/megameklab/src/megameklab/ui/util/CriticalTransferHandler.java @@ -17,6 +17,7 @@ import megamek.common.*; import megameklab.ui.EntitySource; +import megameklab.ui.PopupMessages; import megameklab.ui.mek.BMCriticalView; import megameklab.util.UnitUtil; import org.apache.logging.log4j.LogManager; @@ -61,17 +62,12 @@ public boolean importData(TransferSupport info) { .getTransferData(DataFlavor.stringFlavor))); if (!UnitUtil.isValidLocation(getUnit(), mount.getType(), location)) { - JOptionPane.showMessageDialog(null, mount.getName() + - " can't be placed in " + - getUnit().getLocationName(location) + "!", - "Invalid Location", - JOptionPane.INFORMATION_MESSAGE); + PopupMessages.showInvalidLocationInfo(null, mount.getName(), getUnit().getLocationName(location)); return false; } if (!getUnit().addCritical(location, new CriticalSlot(mount))) { - JOptionPane.showMessageDialog(null, "Location Full", - "Location Full", JOptionPane.INFORMATION_MESSAGE); + PopupMessages.showLocationFullError(null, mount.getName()); } else { changeMountStatus(mount, location, false); } @@ -89,17 +85,12 @@ public boolean importData(TransferSupport info) { .getTransferData(DataFlavor.stringFlavor))); if (!UnitUtil.isValidLocation(getUnit(), mount.getType(), location)) { - JOptionPane.showMessageDialog(null, mount.getName() + - " can't be placed in " + - getUnit().getLocationName(location) + "!", - "Invalid Location", - JOptionPane.INFORMATION_MESSAGE); + PopupMessages.showInvalidLocationInfo(null, mount.getName(), getUnit().getLocationName(location)); return false; } if (!UnitUtil.protomechHasRoom(list.getProtomech(), location, mount)) { - JOptionPane.showMessageDialog(null, "Location Full", - "Not enough room", JOptionPane.INFORMATION_MESSAGE); + PopupMessages.showLocationFullError(null, mount.getName()); } else { changeMountStatus(mount, location, false); } diff --git a/megameklab/src/megameklab/util/CConfig.java b/megameklab/src/megameklab/util/CConfig.java index 0e5fe9ef4..d25d07f64 100644 --- a/megameklab/src/megameklab/util/CConfig.java +++ b/megameklab/src/megameklab/util/CConfig.java @@ -17,13 +17,22 @@ import megamek.common.Configuration; import megameklab.ui.MMLStartUp; +import megameklab.ui.MegaMekLabMainUI; +import megameklab.ui.battleArmor.BAMainUI; +import megameklab.ui.combatVehicle.CVMainUI; +import megameklab.ui.fighterAero.ASMainUI; +import megameklab.ui.infantry.CIMainUI; +import megameklab.ui.largeAero.DSMainUI; +import megameklab.ui.mek.BMMainUI; +import megameklab.ui.protoMek.PMMainUI; +import megameklab.ui.supportVehicle.SVMainUI; import org.apache.logging.log4j.LogManager; -import java.util.ArrayList; -import java.util.List; import javax.swing.*; import java.awt.*; import java.io.*; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import java.util.Properties; import java.util.stream.Collectors; @@ -37,28 +46,36 @@ public final class CConfig { public static final String CONFIG_FILE = "./mmconf/megameklab.properties"; public static final String CONFIG_BACKUP_FILE = "./mmconf/megameklab.properties.bak"; - public static final String STARTUP = "StartupGui"; - - public static final String COLOR_WEAPONS = "Weapons"; - public static final String COLOR_AMMO = "Ammo"; - public static final String COLOR_EQUIPMENT = "Equipment"; - public static final String COLOR_SYSTEMS = "Systems"; - public static final String COLOR_EMPTY = "Empty"; - public static final String COLOR_NONHITTABLE = "Nonhittable"; - - public static final int RECENT_FILE_COUNT = 4; - public static final String RECENT_FILE_PREFIX = "Save_File_"; - public static final String CONFIG_SAVE_FILE_1 = RECENT_FILE_PREFIX + "1"; - public static final String CONFIG_SAVE_FILE_2 = RECENT_FILE_PREFIX + "2"; - public static final String CONFIG_SAVE_FILE_3 = RECENT_FILE_PREFIX + "3"; - public static final String CONFIG_SAVE_FILE_4 = RECENT_FILE_PREFIX + "4"; - public static final String LAST_DIRECTORY = "Last_directory"; + public static final String MISC_STARTUP = "StartupGui"; + public static final String MISC_SUMMARY_FORMAT_TRO = "useTROFormat"; + public static final String MISC_SKIP_SAFETY_PROMPTS = "skipSafetyPrompts"; + public static final String GUI_PLAF = "lookAndFeel"; + public static final String GUI_COLOR_WEAPONS = "Weapons"; + public static final String GUI_COLOR_AMMO = "Ammo"; + public static final String GUI_COLOR_EQUIPMENT = "Equipment"; + public static final String GUI_COLOR_SYSTEMS = "Systems"; + public static final String GUI_COLOR_EMPTY = "Empty"; + public static final String GUI_COLOR_NONHITTABLE = "Nonhittable"; + public static final String GUI_FOREGROUND = "-Foreground"; + public static final String GUI_BACKGROUND = "-Background"; + + public static final String GUI_FULLSCREEN = "FullScreen"; + public static final String GUI_BM_MAINUI_WINDOW = "BMWindow"; + public static final String GUI_CV_MAINUI_WINDOW = "CVWindow"; + public static final String GUI_AS_MAINUI_WINDOW = "ASWindow"; + public static final String GUI_SV_MAINUI_WINDOW = "SVWindow"; + public static final String GUI_PM_MAINUI_WINDOW = "PMWindow"; + public static final String GUI_BA_MAINUI_WINDOW = "BAWindow"; + public static final String GUI_CI_MAINUI_WINDOW = "CIWindow"; + public static final String GUI_DS_MAINUI_WINDOW = "DSWindow"; + public static final String GUI_WS_MAINUI_WINDOW = "WSWindow"; + + public static final int RECENT_FILE_COUNT = 10; + public static final String FILE_RECENT_PREFIX = "Save_File_"; + public static final String FILE_LAST_DIRECTORY = "Last_directory"; public static final String FILE_CHOOSER_WINDOW = "File_Chooser_Window"; - public static final String CONFIG_FOREGROUND = "-Foreground"; - public static final String CONFIG_BACKGROUND = "-Background"; - public static final String TECH_PROGRESSION = "techProgression"; public static final String TECH_USE_YEAR = "techUseYear"; public static final String TECH_YEAR = "techYear"; @@ -66,12 +83,6 @@ public final class CConfig { public static final String TECH_EXTINCT = "techShowExtinct"; public static final String TECH_UNOFFICAL_NO_YEAR = "techUnofficialNoYear"; - public static final String MISC_SUMMARY_FORMAT_TRO = "useTROFormat"; - public static final String MISC_SKIP_SAFETY_PROMPTS = "skipSafetyPrompts"; - - public static final String CONFIG_SAVE_LOC = "Save-Location-Default"; - public static final String CONFIG_PLAF = "lookAndFeel"; - public static final String RS_PAPER_SIZE = "rs_paper_size"; public static final String RS_COLOR = "rs_color"; public static final String RS_FONT = "rs_font"; @@ -93,12 +104,8 @@ public final class CConfig { public static final String MEK_AUTOSORT = "mekAutosort"; public static final String MEK_AUTOCOMPACT = "mekAutocompact"; - /** - * Player configuration values. - */ private static final Properties config = getDefaults(); - // METHODS /** * Private method that loads hardcoded defaults. These are loaded before the * players config values, adding any new configs in their default position @@ -106,16 +113,7 @@ public final class CConfig { */ private static Properties getDefaults() { Properties defaults = new Properties(); - - // Window Locations - defaults.setProperty("WINDOWSTATE", "0"); - defaults.setProperty("WINDOWHEIGHT", "600"); - defaults.setProperty("WINDOWWIDTH", "800"); - defaults.setProperty("WINDOWLEFT", "0"); - defaults.setProperty("WINDOWTOP", "0"); - defaults.setProperty(CONFIG_SAVE_LOC, - new File(System.getProperty("user.dir") - + "/data/mechfiles/").getAbsolutePath()); + defaults.setProperty(GUI_FULLSCREEN, Boolean.toString(false)); defaults.setProperty(MISC_SUMMARY_FORMAT_TRO, Boolean.toString(true)); defaults.setProperty(MISC_SKIP_SAFETY_PROMPTS, Boolean.toString(false)); defaults.setProperty(RS_PROGRESS_BAR, Boolean.toString(true)); @@ -130,9 +128,9 @@ private static Properties getDefaults() { defaults.setProperty(MEK_AUTOFILL, Boolean.toString(true)); defaults.setProperty(MEK_AUTOSORT, Boolean.toString(true)); defaults.setProperty(MEK_AUTOCOMPACT, Boolean.toString(true)); - defaults.setProperty(LAST_DIRECTORY, Configuration.unitsDir().toString()); + defaults.setProperty(FILE_LAST_DIRECTORY, Configuration.unitsDir().toString()); defaults.setProperty(FILE_CHOOSER_WINDOW, ""); - defaults.setProperty(STARTUP, MMLStartUp.SPLASH_SCREEN.name()); + defaults.setProperty(MISC_STARTUP, MMLStartUp.SPLASH_SCREEN.name()); return defaults; } @@ -144,6 +142,14 @@ public static void load() { loadConfigFile(); } + public static void importSettings(File settingsFile) { + try (FileInputStream fis = new FileInputStream(settingsFile)) { + config.load(fis); + } catch (Exception ex) { + LogManager.getLogger().error("", ex); + } + } + /** * Loads the Config file. */ @@ -167,7 +173,7 @@ public static void loadConfigFile() { LogManager.getLogger().error("", ex); } } - + /** * Creates a new Config file, and directories, if it is missing. */ @@ -197,10 +203,10 @@ public static void ensureConfigFileExists() { /** * Get a config value, with a default value to be used if the value is not found. - * + * * @param param The key * @param defaultVal The value to return if the entry is not found - * @return The value associated with the key + * @return The value associated with the key */ public static String getParam(String param, String defaultVal) { if (param.endsWith(":")) { @@ -212,12 +218,12 @@ public static String getParam(String param, String defaultVal) { } return tparam; } - + /** * Get a config value. - * - * @param param The key - * @return The value associated with the key. If not found, an empty String is returned + * + * @param param The key + * @return The value associated with the key. If not found, an empty String is returned */ public static String getParam(String param) { return getParam(param, ""); @@ -225,6 +231,7 @@ public static String getParam(String param) { /** * Set a config value. + * * @param param the name of the parameter * @param value the value to set the parameter to */ @@ -242,21 +249,19 @@ public static void setParam(String param, String value) { * @return The integer value of the property */ public static int getIntParam(String param, int defaultVal) { - int toReturn; try { - toReturn = Integer.parseInt(CConfig.getParam(param)); + return Integer.parseInt(CConfig.getParam(param)); } catch (Exception ex) { return defaultVal; } - return toReturn; } /** * Return the int value of a given config property. Return a 0 if the * property is a non-number. * - * @param param The parameter name - * @return The integer value of the property + * @param param The parameter name + * @return The integer value of the property */ public static int getIntParam(String param) { return getIntParam(param, 0); @@ -301,26 +306,22 @@ public static void saveConfig() { } public static Color getForegroundColor(String fieldName) { - Color masterColor = Color.black; try { - masterColor = Color.getColor("", Integer.parseInt(CConfig.getParam(fieldName + CConfig.CONFIG_FOREGROUND))); - } catch (Exception ignored) { + return Color.getColor("", Integer.parseInt(CConfig.getParam(fieldName + CConfig.GUI_FOREGROUND))); + } catch (Exception e) { + return Color.BLACK; } - return masterColor; } public static Color getBackgroundColor(String fieldName) { - Color masterColor = Color.WHITE; - try { - masterColor = Color.getColor("", Integer.parseInt(CConfig.getParam(fieldName + CConfig.CONFIG_BACKGROUND))); - } catch (Exception ignored) { - + return Color.getColor("", Integer.parseInt(CConfig.getParam(fieldName + CConfig.GUI_BACKGROUND))); + } catch (Exception e) { + return Color.WHITE; } - return masterColor; } - public static void updateSaveFiles(final String newFile) { + public static void setMostRecentFile(final String newFile) { if ((newFile == null) || newFile.isBlank()) { return; } @@ -333,20 +334,22 @@ public static void updateSaveFiles(final String newFile) { CConfig.saveConfig(); } - private static List getRecentFiles() { + public static List getRecentFiles() { List result = new ArrayList<>(); for (int i = 1; i <= RECENT_FILE_COUNT; i++) { - result.add(getRecentFile(i)); + if (!getRecentFile(i).isBlank()) { + result.add(getRecentFile(i)); + } } return result; } private static void setRecentFiles(List files) { - for (int i = 1; i <= RECENT_FILE_COUNT; i++) { + for (int i = 0; i < RECENT_FILE_COUNT; i++) { if (i < files.size()) { - setParam(RECENT_FILE_PREFIX + i, files.get(i)); + setParam(FILE_RECENT_PREFIX + (i + 1), files.get(i)); } else { - setParam(RECENT_FILE_PREFIX + i, ""); + setParam(FILE_RECENT_PREFIX + (i + 1), ""); } } } @@ -363,7 +366,7 @@ public static RSScale scaleUnits() { * * @param val The base distance (standard hexes) * @param showUnits Whether to append the unit abbreviation - * @return A String representation of the scaled value + * @return A String representation of the scaled value */ public static String formatScale(double val, boolean showUnits) { int retVal = (int) Math.round(val * getIntParam(RS_SCALE_FACTOR, 1)); @@ -375,8 +378,58 @@ public static String formatScale(double val, boolean showUnits) { } public static Optional getFileChooserSize() { + return getWindowSize(FILE_CHOOSER_WINDOW); + } + + public static Optional getFileChooserPosition() { + return getWindowPosition(FILE_CHOOSER_WINDOW); + } + + public static void writeFileChooserSettings(JDialog dialog) { + writeWindowSettings(FILE_CHOOSER_WINDOW, dialog); + } + + public static Optional getMainUiWindowSize(MegaMekLabMainUI mainUi) { + return getWindowSize(settingForMainUi(mainUi)); + } + + public static Optional getMainUiWindowPosition(MegaMekLabMainUI mainUi) { + return getWindowPosition(settingForMainUi(mainUi)); + } + + public static void writeMainUiWindowSettings(MegaMekLabMainUI mainUi) { + writeWindowSettings(settingForMainUi(mainUi), mainUi); + } + + public static String getRecentFile(int recentFileNumber) { + return CConfig.getParam(CConfig.FILE_RECENT_PREFIX + recentFileNumber); + } + + public static MMLStartUp getStartUpType() { + return MMLStartUp.parse(CConfig.getParam(CConfig.MISC_STARTUP)); + } + + public static void resetWindowPositions() { + setParam(GUI_FULLSCREEN, Boolean.toString(false)); + setParam(FILE_CHOOSER_WINDOW, ""); + setParam(GUI_BM_MAINUI_WINDOW, ""); + setParam(GUI_CV_MAINUI_WINDOW, ""); + setParam(GUI_AS_MAINUI_WINDOW, ""); + setParam(GUI_SV_MAINUI_WINDOW, ""); + setParam(GUI_PM_MAINUI_WINDOW, ""); + setParam(GUI_BA_MAINUI_WINDOW, ""); + setParam(GUI_CI_MAINUI_WINDOW, ""); + setParam(GUI_DS_MAINUI_WINDOW, ""); + setParam(GUI_WS_MAINUI_WINDOW, ""); + saveConfig(); + } + + // Internals #################### + + + private static Optional getWindowSize(String cconfigSetting) { try { - String[] fileChooserSettings = getParam(FILE_CHOOSER_WINDOW).split(";"); + String[] fileChooserSettings = getParam(cconfigSetting).split(";"); int sizeX = Integer.parseInt(fileChooserSettings[2]); int sizeY = Integer.parseInt(fileChooserSettings[3]); return Optional.of(new Dimension(sizeX, sizeY)); @@ -385,9 +438,9 @@ public static Optional getFileChooserSize() { } } - public static Optional getFileChooserPosition() { + private static Optional getWindowPosition(String cconfigSetting) { try { - String[] fileChooserSettings = getParam(FILE_CHOOSER_WINDOW).split(";"); + String[] fileChooserSettings = getParam(cconfigSetting).split(";"); int posX = Integer.parseInt(fileChooserSettings[0]); int posY = Integer.parseInt(fileChooserSettings[1]); return Optional.of(new Point(posX, posY)); @@ -396,20 +449,34 @@ public static Optional getFileChooserPosition() { } } - public static void writeFileChooserSettings(JDialog dialog) { - Dimension size = dialog.getSize(); - Point pos = dialog.getLocation(); - setParam(FILE_CHOOSER_WINDOW, pos.x + ";" + pos.y + ";" + size.width + ";" + size.height); + private static void writeWindowSettings(String cconfigSetting, Component component) { + Dimension size = component.getSize(); + Point pos = component.getLocation(); + setParam(cconfigSetting, pos.x + ";" + pos.y + ";" + size.width + ";" + size.height); } - public static String getRecentFile(int recentFileNumber) { - String fileName = CConfig.getParam(CConfig.RECENT_FILE_PREFIX + recentFileNumber); - return (fileName == null) ? "" : fileName; + private static String settingForMainUi(MegaMekLabMainUI ui) { + if (ui instanceof BMMainUI) { + return GUI_BM_MAINUI_WINDOW; + } else if (ui instanceof CVMainUI) { + return GUI_CV_MAINUI_WINDOW; + } else if (ui instanceof DSMainUI) { + return GUI_DS_MAINUI_WINDOW; + } else if (ui instanceof ASMainUI) { + return GUI_AS_MAINUI_WINDOW; + } else if (ui instanceof PMMainUI) { + return GUI_PM_MAINUI_WINDOW; + } else if (ui instanceof BAMainUI) { + return GUI_BA_MAINUI_WINDOW; + } else if (ui instanceof CIMainUI) { + return GUI_CI_MAINUI_WINDOW; + } else if (ui instanceof SVMainUI) { + return GUI_SV_MAINUI_WINDOW; + } else { + return GUI_WS_MAINUI_WINDOW; + } } - public static MMLStartUp getStartUpType() { - return MMLStartUp.parse(CConfig.getParam(CConfig.STARTUP)); + private CConfig() { } - - private CConfig() { } } diff --git a/megameklab/src/megameklab/util/UnitUtil.java b/megameklab/src/megameklab/util/UnitUtil.java index f313a8666..e85e0f827 100644 --- a/megameklab/src/megameklab/util/UnitUtil.java +++ b/megameklab/src/megameklab/util/UnitUtil.java @@ -52,6 +52,7 @@ import megamek.common.weapons.tag.CLLightTAG; import megamek.common.weapons.tag.CLTAG; import megamek.common.weapons.tag.ISTAG; +import megameklab.ui.PopupMessages; import megameklab.ui.mek.BMUtils; import org.apache.logging.log4j.LogManager; @@ -1889,13 +1890,8 @@ public static Mounted createSpreadMounts(Mech unit, EquipmentType equip) { } } } catch (LocationFullException lfe) { + PopupMessages.showLocationFullError(null, mount.getName()); LogManager.getLogger().error(lfe); - JOptionPane.showMessageDialog( - null, - lfe.getMessage(), - mount.getName() + " does not fit into " - + unit.getLocationName(locations.get(0)), - JOptionPane.INFORMATION_MESSAGE); unit.getMisc().remove(mount); unit.getEquipment().remove(mount); return null; @@ -3448,12 +3444,10 @@ public static boolean protomechHasRoom(Protomech proto, int location, Mounted mo public static void showValidation(Entity entity, JFrame frame) { final String validation = UnitUtil.validateUnit(entity); - if (!validation.isBlank()) { - JOptionPane.showMessageDialog(frame, validation, "Unit Validation", - JOptionPane.ERROR_MESSAGE); + if (validation.isBlank()) { + PopupMessages.showUnitIsValid(frame); } else { - JOptionPane.showMessageDialog(frame, "Validation Passed", - "Unit Validation", JOptionPane.INFORMATION_MESSAGE); + PopupMessages.showUnitInvalidWarning(frame, validation); } } @@ -3494,13 +3488,7 @@ public static void showUnitSpecs(Entity unit, JFrame frame) { jdialog.add(scroll); - Dimension size = new Dimension(CConfig.getIntParam("WINDOWWIDTH") / 2, - CConfig.getIntParam("WINDOWHEIGHT")); - - jdialog.setPreferredSize(size); - jdialog.setMinimumSize(size); - scroll.setPreferredSize(size); - scroll.setMinimumSize(size); + jdialog.pack(); jdialog.setLocationRelativeTo(frame); jdialog.setVisible(true); @@ -3533,14 +3521,7 @@ public static void showUnitWeightBreakDown(Entity unit, JFrame frame) { JDialog jdialog = new JDialog(); jdialog.add(scroll); - Dimension size = new Dimension(CConfig.getIntParam("WINDOWWIDTH") / 2, - CConfig.getIntParam("WINDOWHEIGHT")); - - jdialog.setPreferredSize(size); - jdialog.setMinimumSize(size); - scroll.setPreferredSize(size); - scroll.setMinimumSize(size); - + jdialog.pack(); jdialog.setLocationRelativeTo(frame); jdialog.setVisible(true);