Fix Swing multithreading issue, clean up slightly

This commit is contained in:
comp500 2020-09-29 02:14:56 +01:00
parent ecc6f0440a
commit b3370739a5
2 changed files with 74 additions and 64 deletions

View File

@ -18,6 +18,9 @@ import kotlin.system.exitProcess
@Suppress("unused") @Suppress("unused")
class Main(args: Array<String>) { class Main(args: Array<String>) {
// Don't attempt to start a GUI if we are headless
var guiEnabled = !GraphicsEnvironment.isHeadless()
private fun startup(args: Array<String>) { private fun startup(args: Array<String>) {
val options = Options() val options = Options()
addNonBootstrapOptions(options) addNonBootstrapOptions(options)
@ -28,19 +31,24 @@ class Main(args: Array<String>) {
parser.parse(options, args) parser.parse(options, args)
} catch (e: ParseException) { } catch (e: ParseException) {
e.printStackTrace() e.printStackTrace()
try { if (guiEnabled) {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) EventQueue.invokeAndWait {
} catch (e1: Exception) { try {
// Ignore the exceptions, just continue using the ugly L&F 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) exitProcess(1)
} }
// if "headless", GUI creation will fail anyway! if (guiEnabled && cmd.hasOption("no-gui")) {
val ui = if (cmd.hasOption("no-gui") || GraphicsEnvironment.isHeadless()) { guiEnabled = false
CLIHandler() }
} else InstallWindow()
val ui = if (guiEnabled) InstallWindow() else CLIHandler()
val unparsedArgs = cmd.args val unparsedArgs = cmd.args
if (unparsedArgs.size > 1) { if (unparsedArgs.size > 1) {
@ -49,15 +57,13 @@ class Main(args: Array<String>) {
ui.handleExceptionAndExit(RuntimeException("URI to install from must be specified!")) ui.handleExceptionAndExit(RuntimeException("URI to install from must be specified!"))
} }
cmd.getOptionValue("title")?.also { cmd.getOptionValue("title")?.also(ui::setTitle)
ui.setTitle(it)
}
val inputStateHandler = InputStateHandler() val inputStateHandler = InputStateHandler()
ui.show(inputStateHandler) ui.show(inputStateHandler)
val uOptions = UpdateManager.Options().apply { 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 packFolder = cmd.getOptionValue("pack-folder") ?: packFolder
manifestFile = cmd.getOptionValue("meta-file") ?: manifestFile manifestFile = cmd.getOptionValue("meta-file") ?: manifestFile
} }
@ -113,11 +119,13 @@ class Main(args: Array<String>) {
startup(args) startup(args)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
EventQueue.invokeLater { if (guiEnabled) {
JOptionPane.showMessageDialog(null, EventQueue.invokeLater {
JOptionPane.showMessageDialog(null,
"A fatal error occurred: \n" + e.javaClass.canonicalName + ": " + e.message, "A fatal error occurred: \n" + e.javaClass.canonicalName + ": " + e.message,
"packwiz-installer", JOptionPane.ERROR_MESSAGE) "packwiz-installer", JOptionPane.ERROR_MESSAGE)
exitProcess(1) exitProcess(1)
}
} }
// In case the EventQueue is broken, exit after 1 minute // In case the EventQueue is broken, exit after 1 minute
Thread.sleep(60 * 1000.toLong()) Thread.sleep(60 * 1000.toLong())

View File

@ -10,10 +10,10 @@ import javax.swing.border.EmptyBorder
import kotlin.system.exitProcess import kotlin.system.exitProcess
class InstallWindow : IUserInterface { class InstallWindow : IUserInterface {
private val frmPackwizlauncher: JFrame private lateinit var frmPackwizlauncher: JFrame
private val lblProgresslabel: JLabel private lateinit var lblProgresslabel: JLabel
private val progressBar: JProgressBar private lateinit var progressBar: JProgressBar
private val btnOptions: JButton private lateinit var btnOptions: JButton
private var inputStateHandler: InputStateHandler? = null private var inputStateHandler: InputStateHandler? = null
private var title = "Updating modpack..." private var title = "Updating modpack..."
@ -23,55 +23,57 @@ class InstallWindow : IUserInterface {
// TODO: separate JFrame junk from IUserInterface junk? // TODO: separate JFrame junk from IUserInterface junk?
init { init {
frmPackwizlauncher = JFrame().apply { EventQueue.invokeAndWait {
title = this@InstallWindow.title frmPackwizlauncher = JFrame().apply {
setBounds(100, 100, 493, 95) title = this@InstallWindow.title
defaultCloseOperation = JFrame.EXIT_ON_CLOSE setBounds(100, 100, 493, 95)
setLocationRelativeTo(null) defaultCloseOperation = JFrame.EXIT_ON_CLOSE
setLocationRelativeTo(null)
// Progress bar and loading text // Progress bar and loading text
add(JPanel().apply { add(JPanel().apply {
border = EmptyBorder(10, 10, 10, 10) border = EmptyBorder(10, 10, 10, 10)
layout = BorderLayout(0, 0) layout = BorderLayout(0, 0)
progressBar = JProgressBar().apply { progressBar = JProgressBar().apply {
isIndeterminate = true 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()
} }
} add(progressBar, BorderLayout.CENTER)
add(btnOptions, GridBagConstraints().apply {
gridx = 0
gridy = 0
})
add(JButton("Cancel").apply { lblProgresslabel = JLabel("Loading...")
addActionListener { add(lblProgresslabel, BorderLayout.SOUTH)
isEnabled = false }, BorderLayout.CENTER)
inputStateHandler?.pressCancelButton()
// 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 { add(btnOptions, GridBagConstraints().apply {
gridx = 0 gridx = 0
gridy = 1 gridy = 0
}) })
}, BorderLayout.EAST)
add(JButton("Cancel").apply {
addActionListener {
isEnabled = false
inputStateHandler?.pressCancelButton()
}
}, GridBagConstraints().apply {
gridx = 0
gridy = 1
})
}, BorderLayout.EAST)
}
} }
} }