From b3370739a51516cbb1f7ee006c8027858f98daa6 Mon Sep 17 00:00:00 2001 From: comp500 Date: Tue, 29 Sep 2020 02:14:56 +0100 Subject: [PATCH] Fix Swing multithreading issue, clean up slightly --- .../link/infra/packwiz/installer/Main.kt | 40 +++++--- .../packwiz/installer/ui/InstallWindow.kt | 98 ++++++++++--------- 2 files changed, 74 insertions(+), 64 deletions(-) diff --git a/src/main/kotlin/link/infra/packwiz/installer/Main.kt b/src/main/kotlin/link/infra/packwiz/installer/Main.kt index 7bd42fe..5a89ea4 100644 --- a/src/main/kotlin/link/infra/packwiz/installer/Main.kt +++ b/src/main/kotlin/link/infra/packwiz/installer/Main.kt @@ -18,6 +18,9 @@ import kotlin.system.exitProcess @Suppress("unused") class Main(args: Array) { + // Don't attempt to start a GUI if we are headless + var guiEnabled = !GraphicsEnvironment.isHeadless() + private fun startup(args: Array) { val options = Options() addNonBootstrapOptions(options) @@ -28,19 +31,24 @@ class Main(args: Array) { parser.parse(options, args) } catch (e: ParseException) { e.printStackTrace() - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) - } catch (e1: Exception) { - // Ignore the exceptions, just continue using the ugly L&F + if (guiEnabled) { + EventQueue.invokeAndWait { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) + } catch (ignored: Exception) { + // Ignore the exceptions, just continue using the ugly L&F + } + JOptionPane.showMessageDialog(null, e.message, "packwiz-installer", JOptionPane.ERROR_MESSAGE) + } } - JOptionPane.showMessageDialog(null, e.message, "packwiz-installer", JOptionPane.ERROR_MESSAGE) exitProcess(1) } - // if "headless", GUI creation will fail anyway! - val ui = if (cmd.hasOption("no-gui") || GraphicsEnvironment.isHeadless()) { - CLIHandler() - } else InstallWindow() + if (guiEnabled && cmd.hasOption("no-gui")) { + guiEnabled = false + } + + val ui = if (guiEnabled) InstallWindow() else CLIHandler() val unparsedArgs = cmd.args if (unparsedArgs.size > 1) { @@ -49,15 +57,13 @@ class Main(args: Array) { ui.handleExceptionAndExit(RuntimeException("URI to install from must be specified!")) } - cmd.getOptionValue("title")?.also { - ui.setTitle(it) - } + cmd.getOptionValue("title")?.also(ui::setTitle) val inputStateHandler = InputStateHandler() ui.show(inputStateHandler) val uOptions = UpdateManager.Options().apply { - side = cmd.getOptionValue("side")?.let { UpdateManager.Options.Side.from(it) } ?: side + side = cmd.getOptionValue("side")?.let((UpdateManager.Options.Side)::from) ?: side packFolder = cmd.getOptionValue("pack-folder") ?: packFolder manifestFile = cmd.getOptionValue("meta-file") ?: manifestFile } @@ -113,11 +119,13 @@ class Main(args: Array) { startup(args) } catch (e: Exception) { e.printStackTrace() - EventQueue.invokeLater { - JOptionPane.showMessageDialog(null, + if (guiEnabled) { + EventQueue.invokeLater { + JOptionPane.showMessageDialog(null, "A fatal error occurred: \n" + e.javaClass.canonicalName + ": " + e.message, "packwiz-installer", JOptionPane.ERROR_MESSAGE) - exitProcess(1) + exitProcess(1) + } } // In case the EventQueue is broken, exit after 1 minute Thread.sleep(60 * 1000.toLong()) diff --git a/src/main/kotlin/link/infra/packwiz/installer/ui/InstallWindow.kt b/src/main/kotlin/link/infra/packwiz/installer/ui/InstallWindow.kt index 009e8c7..16944f8 100644 --- a/src/main/kotlin/link/infra/packwiz/installer/ui/InstallWindow.kt +++ b/src/main/kotlin/link/infra/packwiz/installer/ui/InstallWindow.kt @@ -10,10 +10,10 @@ import javax.swing.border.EmptyBorder import kotlin.system.exitProcess class InstallWindow : IUserInterface { - private val frmPackwizlauncher: JFrame - private val lblProgresslabel: JLabel - private val progressBar: JProgressBar - private val btnOptions: JButton + private lateinit var frmPackwizlauncher: JFrame + private lateinit var lblProgresslabel: JLabel + private lateinit var progressBar: JProgressBar + private lateinit var btnOptions: JButton private var inputStateHandler: InputStateHandler? = null private var title = "Updating modpack..." @@ -23,55 +23,57 @@ class InstallWindow : IUserInterface { // TODO: separate JFrame junk from IUserInterface junk? init { - frmPackwizlauncher = JFrame().apply { - title = this@InstallWindow.title - setBounds(100, 100, 493, 95) - defaultCloseOperation = JFrame.EXIT_ON_CLOSE - setLocationRelativeTo(null) + EventQueue.invokeAndWait { + frmPackwizlauncher = JFrame().apply { + title = this@InstallWindow.title + setBounds(100, 100, 493, 95) + defaultCloseOperation = JFrame.EXIT_ON_CLOSE + setLocationRelativeTo(null) - // Progress bar and loading text - add(JPanel().apply { - border = EmptyBorder(10, 10, 10, 10) - layout = BorderLayout(0, 0) + // Progress bar and loading text + add(JPanel().apply { + border = EmptyBorder(10, 10, 10, 10) + layout = BorderLayout(0, 0) - progressBar = JProgressBar().apply { - isIndeterminate = true - } - add(progressBar, BorderLayout.CENTER) - - lblProgresslabel = JLabel("Loading...") - add(lblProgresslabel, BorderLayout.SOUTH) - }, BorderLayout.CENTER) - - // Buttons - add(JPanel().apply { - border = EmptyBorder(0, 5, 0, 5) - layout = GridBagLayout() - - btnOptions = JButton("Optional mods...").apply { - alignmentX = Component.CENTER_ALIGNMENT - - addActionListener { - text = "Loading..." - isEnabled = false - inputStateHandler?.pressOptionsButton() + progressBar = JProgressBar().apply { + isIndeterminate = true } - } - add(btnOptions, GridBagConstraints().apply { - gridx = 0 - gridy = 0 - }) + add(progressBar, BorderLayout.CENTER) - add(JButton("Cancel").apply { - addActionListener { - isEnabled = false - inputStateHandler?.pressCancelButton() + lblProgresslabel = JLabel("Loading...") + add(lblProgresslabel, BorderLayout.SOUTH) + }, BorderLayout.CENTER) + + // Buttons + add(JPanel().apply { + border = EmptyBorder(0, 5, 0, 5) + layout = GridBagLayout() + + btnOptions = JButton("Optional mods...").apply { + alignmentX = Component.CENTER_ALIGNMENT + + addActionListener { + text = "Loading..." + isEnabled = false + inputStateHandler?.pressOptionsButton() + } } - }, GridBagConstraints().apply { - gridx = 0 - gridy = 1 - }) - }, BorderLayout.EAST) + add(btnOptions, GridBagConstraints().apply { + gridx = 0 + gridy = 0 + }) + + add(JButton("Cancel").apply { + addActionListener { + isEnabled = false + inputStateHandler?.pressCancelButton() + } + }, GridBagConstraints().apply { + gridx = 0 + gridy = 1 + }) + }, BorderLayout.EAST) + } } }