mirror of
https://github.com/packwiz/packwiz-installer.git
synced 2025-04-19 21:16:30 +02:00
Refactor GUI code, remove bad SwingWorker junk
This commit is contained in:
parent
f52cd19ad4
commit
f5b22f37a4
@ -6,8 +6,8 @@ import link.infra.packwiz.installer.metadata.SpaceSafeURI
|
|||||||
import link.infra.packwiz.installer.metadata.hash.Hash
|
import link.infra.packwiz.installer.metadata.hash.Hash
|
||||||
import link.infra.packwiz.installer.metadata.hash.HashUtils.getHash
|
import link.infra.packwiz.installer.metadata.hash.HashUtils.getHash
|
||||||
import link.infra.packwiz.installer.metadata.hash.HashUtils.getHasher
|
import link.infra.packwiz.installer.metadata.hash.HashUtils.getHasher
|
||||||
import link.infra.packwiz.installer.ui.ExceptionDetails
|
import link.infra.packwiz.installer.ui.data.ExceptionDetails
|
||||||
import link.infra.packwiz.installer.ui.IOptionDetails
|
import link.infra.packwiz.installer.ui.data.IOptionDetails
|
||||||
import okio.Buffer
|
import okio.Buffer
|
||||||
import okio.HashingSink
|
import okio.HashingSink
|
||||||
import okio.buffer
|
import okio.buffer
|
||||||
|
@ -3,9 +3,8 @@
|
|||||||
package link.infra.packwiz.installer
|
package link.infra.packwiz.installer
|
||||||
|
|
||||||
import link.infra.packwiz.installer.metadata.SpaceSafeURI
|
import link.infra.packwiz.installer.metadata.SpaceSafeURI
|
||||||
import link.infra.packwiz.installer.ui.CLIHandler
|
import link.infra.packwiz.installer.ui.cli.CLIHandler
|
||||||
import link.infra.packwiz.installer.ui.InputStateHandler
|
import link.infra.packwiz.installer.ui.gui.InstallWindow
|
||||||
import link.infra.packwiz.installer.ui.InstallWindow
|
|
||||||
import org.apache.commons.cli.DefaultParser
|
import org.apache.commons.cli.DefaultParser
|
||||||
import org.apache.commons.cli.Options
|
import org.apache.commons.cli.Options
|
||||||
import org.apache.commons.cli.ParseException
|
import org.apache.commons.cli.ParseException
|
||||||
@ -19,7 +18,7 @@ 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
|
// Don't attempt to start a GUI if we are headless
|
||||||
var guiEnabled = !GraphicsEnvironment.isHeadless()
|
private var guiEnabled = !GraphicsEnvironment.isHeadless()
|
||||||
|
|
||||||
private fun startup(args: Array<String>) {
|
private fun startup(args: Array<String>) {
|
||||||
val options = Options()
|
val options = Options()
|
||||||
@ -59,8 +58,7 @@ class Main(args: Array<String>) {
|
|||||||
|
|
||||||
cmd.getOptionValue("title")?.also(ui::setTitle)
|
cmd.getOptionValue("title")?.also(ui::setTitle)
|
||||||
|
|
||||||
val inputStateHandler = InputStateHandler()
|
ui.show()
|
||||||
ui.show(inputStateHandler)
|
|
||||||
|
|
||||||
val uOptions = UpdateManager.Options().apply {
|
val uOptions = UpdateManager.Options().apply {
|
||||||
side = cmd.getOptionValue("side")?.let((UpdateManager.Options.Side)::from) ?: side
|
side = cmd.getOptionValue("side")?.let((UpdateManager.Options.Side)::from) ?: side
|
||||||
@ -76,18 +74,13 @@ class Main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start update process!
|
// Start update process!
|
||||||
// TODO: start in SwingWorker?
|
|
||||||
try {
|
try {
|
||||||
ui.executeManager {
|
UpdateManager(uOptions, ui)
|
||||||
try {
|
|
||||||
UpdateManager(uOptions, ui, inputStateHandler)
|
|
||||||
} catch (e: Exception) { // TODO: better error message?
|
|
||||||
ui.handleExceptionAndExit(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) { // TODO: better error message?
|
} catch (e: Exception) { // TODO: better error message?
|
||||||
ui.handleExceptionAndExit(e)
|
ui.handleExceptionAndExit(e)
|
||||||
}
|
}
|
||||||
|
println("Finished successfully!")
|
||||||
|
ui.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -18,8 +18,7 @@ import link.infra.packwiz.installer.request.HandlerManager.getNewLoc
|
|||||||
import link.infra.packwiz.installer.ui.IUserInterface
|
import link.infra.packwiz.installer.ui.IUserInterface
|
||||||
import link.infra.packwiz.installer.ui.IUserInterface.CancellationResult
|
import link.infra.packwiz.installer.ui.IUserInterface.CancellationResult
|
||||||
import link.infra.packwiz.installer.ui.IUserInterface.ExceptionListResult
|
import link.infra.packwiz.installer.ui.IUserInterface.ExceptionListResult
|
||||||
import link.infra.packwiz.installer.ui.InputStateHandler
|
import link.infra.packwiz.installer.ui.data.InstallProgress
|
||||||
import link.infra.packwiz.installer.ui.InstallProgress
|
|
||||||
import okio.buffer
|
import okio.buffer
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
import java.io.FileReader
|
import java.io.FileReader
|
||||||
@ -34,7 +33,7 @@ import java.util.concurrent.ExecutorCompletionService
|
|||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
class UpdateManager internal constructor(private val opts: Options, val ui: IUserInterface, private val stateHandler: InputStateHandler) {
|
class UpdateManager internal constructor(private val opts: Options, val ui: IUserInterface) {
|
||||||
private var cancelled = false
|
private var cancelled = false
|
||||||
private var cancelledStartGame = false
|
private var cancelledStartGame = false
|
||||||
private var errorsOccurred = false
|
private var errorsOccurred = false
|
||||||
@ -119,7 +118,7 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stateHandler.cancelButton) {
|
if (ui.cancelButtonPressed) {
|
||||||
showCancellationDialog()
|
showCancellationDialog()
|
||||||
handleCancellation()
|
handleCancellation()
|
||||||
}
|
}
|
||||||
@ -142,7 +141,7 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stateHandler.cancelButton) {
|
if (ui.cancelButtonPressed) {
|
||||||
showCancellationDialog()
|
showCancellationDialog()
|
||||||
handleCancellation()
|
handleCancellation()
|
||||||
}
|
}
|
||||||
@ -178,14 +177,14 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
if (manifest.packFileHash?.let { packFileSource.hashIsEqual(it) } == true && invalidatedUris.isEmpty()) {
|
if (manifest.packFileHash?.let { packFileSource.hashIsEqual(it) } == true && invalidatedUris.isEmpty()) {
|
||||||
println("Modpack is already up to date!")
|
println("Modpack is already up to date!")
|
||||||
// todo: --force?
|
// todo: --force?
|
||||||
if (!stateHandler.optionsButton) {
|
if (!ui.optionsButtonPressed) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println("Modpack name: " + pf.name)
|
println("Modpack name: " + pf.name)
|
||||||
|
|
||||||
if (stateHandler.cancelButton) {
|
if (ui.cancelButtonPressed) {
|
||||||
showCancellationDialog()
|
showCancellationDialog()
|
||||||
handleCancellation()
|
handleCancellation()
|
||||||
}
|
}
|
||||||
@ -234,7 +233,7 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
private fun processIndex(indexUri: SpaceSafeURI, indexHash: Hash, hashFormat: String, manifest: ManifestFile, invalidatedUris: List<SpaceSafeURI>) {
|
private fun processIndex(indexUri: SpaceSafeURI, indexHash: Hash, hashFormat: String, manifest: ManifestFile, invalidatedUris: List<SpaceSafeURI>) {
|
||||||
if (manifest.indexFileHash == indexHash && invalidatedUris.isEmpty()) {
|
if (manifest.indexFileHash == indexHash && invalidatedUris.isEmpty()) {
|
||||||
println("Modpack files are already up to date!")
|
println("Modpack files are already up to date!")
|
||||||
if (!stateHandler.optionsButton) {
|
if (!ui.optionsButtonPressed) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -258,7 +257,7 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
ui.handleExceptionAndExit(RuntimeException("Your index hash is invalid! Please run packwiz refresh on the pack again"))
|
ui.handleExceptionAndExit(RuntimeException("Your index hash is invalid! Please run packwiz refresh on the pack again"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (stateHandler.cancelButton) {
|
if (ui.cancelButtonPressed) {
|
||||||
showCancellationDialog()
|
showCancellationDialog()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -295,7 +294,7 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stateHandler.cancelButton) {
|
if (ui.cancelButtonPressed) {
|
||||||
showCancellationDialog()
|
showCancellationDialog()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -326,7 +325,7 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
f.updateFromCache(file)
|
f.updateFromCache(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stateHandler.cancelButton) {
|
if (ui.cancelButtonPressed) {
|
||||||
showCancellationDialog()
|
showCancellationDialog()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -360,7 +359,7 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stateHandler.cancelButton) {
|
if (ui.cancelButtonPressed) {
|
||||||
showCancellationDialog()
|
showCancellationDialog()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -369,7 +368,7 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
val nonFailedFirstTasks = tasks.filter { t -> !t.failed() }.toList()
|
val nonFailedFirstTasks = tasks.filter { t -> !t.failed() }.toList()
|
||||||
val optionTasks = nonFailedFirstTasks.filter(DownloadTask::correctSide).filter(DownloadTask::isOptional).toList()
|
val optionTasks = nonFailedFirstTasks.filter(DownloadTask::correctSide).filter(DownloadTask::isOptional).toList()
|
||||||
// If options changed, present all options again
|
// If options changed, present all options again
|
||||||
if (stateHandler.optionsButton || optionTasks.any(DownloadTask::isNewOptional)) {
|
if (ui.optionsButtonPressed || optionTasks.any(DownloadTask::isNewOptional)) {
|
||||||
// new ArrayList is required so it's an IOptionDetails rather than a DownloadTask list
|
// new ArrayList is required so it's an IOptionDetails rather than a DownloadTask list
|
||||||
val cancelledResult = ui.showOptions(ArrayList(optionTasks))
|
val cancelledResult = ui.showOptions(ArrayList(optionTasks))
|
||||||
try {
|
try {
|
||||||
@ -433,7 +432,7 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
}
|
}
|
||||||
ui.submitProgress(InstallProgress(progress, i + 1, tasks.size))
|
ui.submitProgress(InstallProgress(progress, i + 1, tasks.size))
|
||||||
|
|
||||||
if (stateHandler.cancelButton) { // Stop all tasks, don't launch the game (it's in an invalid state!)
|
if (ui.cancelButtonPressed) { // Stop all tasks, don't launch the game (it's in an invalid state!)
|
||||||
threadPool.shutdown()
|
threadPool.shutdown()
|
||||||
cancelled = true
|
cancelled = true
|
||||||
return
|
return
|
||||||
@ -483,6 +482,7 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: move to UI?
|
||||||
private fun handleCancellation() {
|
private fun handleCancellation() {
|
||||||
if (cancelled) {
|
if (cancelled) {
|
||||||
println("Update cancelled by user!")
|
println("Update cancelled by user!")
|
||||||
|
@ -5,7 +5,7 @@ import okio.Source
|
|||||||
|
|
||||||
class HashingSourceHasher internal constructor(private val type: String) : IHasher {
|
class HashingSourceHasher internal constructor(private val type: String) : IHasher {
|
||||||
// i love naming things
|
// i love naming things
|
||||||
private inner class HashingSourceGeneralHashingSource internal constructor(val delegateHashing: HashingSource) : GeneralHashingSource(delegateHashing) {
|
private inner class HashingSourceGeneralHashingSource(val delegateHashing: HashingSource) : GeneralHashingSource(delegateHashing) {
|
||||||
override val hash: Hash by lazy(LazyThreadSafetyMode.NONE) {
|
override val hash: Hash by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
HashingSourceHash(delegateHashing.hash.hex())
|
HashingSourceHash(delegateHashing.hash.hex())
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ abstract class RequestHandlerZip(private val modeHasFolder: Boolean) : RequestHa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class ZipReader internal constructor(zip: Source) {
|
private inner class ZipReader(zip: Source) {
|
||||||
private val zis = ZipInputStream(zip.buffer().inputStream())
|
private val zis = ZipInputStream(zip.buffer().inputStream())
|
||||||
private val readFiles: MutableMap<SpaceSafeURI, Buffer> = HashMap()
|
private val readFiles: MutableMap<SpaceSafeURI, Buffer> = HashMap()
|
||||||
// Write lock implies access to ZipInputStream - only 1 thread must read at a time!
|
// Write lock implies access to ZipInputStream - only 1 thread must read at a time!
|
||||||
|
@ -1,30 +1,29 @@
|
|||||||
package link.infra.packwiz.installer.ui
|
package link.infra.packwiz.installer.ui
|
||||||
|
|
||||||
|
import link.infra.packwiz.installer.ui.data.ExceptionDetails
|
||||||
|
import link.infra.packwiz.installer.ui.data.IOptionDetails
|
||||||
|
import link.infra.packwiz.installer.ui.data.InstallProgress
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.Future
|
import java.util.concurrent.Future
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
interface IUserInterface {
|
interface IUserInterface {
|
||||||
fun show(handler: InputStateHandler)
|
fun show()
|
||||||
|
fun dispose()
|
||||||
fun handleException(e: Exception)
|
fun handleException(e: Exception)
|
||||||
@JvmDefault
|
|
||||||
fun handleExceptionAndExit(e: Exception) {
|
fun handleExceptionAndExit(e: Exception) {
|
||||||
handleException(e)
|
handleException(e)
|
||||||
exitProcess(1)
|
exitProcess(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmDefault
|
|
||||||
fun setTitle(title: String) {}
|
fun setTitle(title: String) {}
|
||||||
fun submitProgress(progress: InstallProgress)
|
fun submitProgress(progress: InstallProgress)
|
||||||
fun executeManager(task: () -> Unit)
|
|
||||||
// Return true if the installation was cancelled!
|
// Return true if the installation was cancelled!
|
||||||
fun showOptions(options: List<IOptionDetails>): Future<Boolean>
|
fun showOptions(options: List<IOptionDetails>): Future<Boolean>
|
||||||
|
|
||||||
fun showExceptions(exceptions: List<ExceptionDetails>, numTotal: Int, allowsIgnore: Boolean): Future<ExceptionListResult>
|
fun showExceptions(exceptions: List<ExceptionDetails>, numTotal: Int, allowsIgnore: Boolean): Future<ExceptionListResult>
|
||||||
@JvmDefault
|
|
||||||
fun disableOptionsButton() {}
|
fun disableOptionsButton() {}
|
||||||
|
|
||||||
@JvmDefault
|
|
||||||
fun showCancellationDialog(): Future<CancellationResult> {
|
fun showCancellationDialog(): Future<CancellationResult> {
|
||||||
return CompletableFuture<CancellationResult>().apply {
|
return CompletableFuture<CancellationResult>().apply {
|
||||||
complete(CancellationResult.QUIT)
|
complete(CancellationResult.QUIT)
|
||||||
@ -38,4 +37,7 @@ interface IUserInterface {
|
|||||||
enum class CancellationResult {
|
enum class CancellationResult {
|
||||||
QUIT, CONTINUE
|
QUIT, CONTINUE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var optionsButtonPressed: Boolean
|
||||||
|
var cancelButtonPressed: Boolean
|
||||||
}
|
}
|
@ -1,21 +0,0 @@
|
|||||||
package link.infra.packwiz.installer.ui
|
|
||||||
|
|
||||||
class InputStateHandler {
|
|
||||||
// TODO: convert to coroutines/locks?
|
|
||||||
@get:Synchronized
|
|
||||||
var optionsButton = false
|
|
||||||
private set
|
|
||||||
@get:Synchronized
|
|
||||||
var cancelButton = false
|
|
||||||
private set
|
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
fun pressCancelButton() {
|
|
||||||
cancelButton = true
|
|
||||||
}
|
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
fun pressOptionsButton() {
|
|
||||||
optionsButton = true
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package link.infra.packwiz.installer.ui
|
|
||||||
|
|
||||||
import javax.swing.SwingWorker
|
|
||||||
|
|
||||||
// Q: AAA WHAT HAVE YOU DONE THIS IS DISGUSTING
|
|
||||||
// A: it just makes things easier, so i can easily have one interface for CLI/GUI
|
|
||||||
// if someone has a better way to do this please PR it
|
|
||||||
abstract class SwingWorkerButWithPublicPublish<T, V> : SwingWorker<T, V>() {
|
|
||||||
@SafeVarargs
|
|
||||||
fun publishPublic(vararg chunks: V) {
|
|
||||||
publish(*chunks)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +1,26 @@
|
|||||||
package link.infra.packwiz.installer.ui
|
package link.infra.packwiz.installer.ui.cli
|
||||||
|
|
||||||
|
import link.infra.packwiz.installer.ui.IUserInterface
|
||||||
import link.infra.packwiz.installer.ui.IUserInterface.ExceptionListResult
|
import link.infra.packwiz.installer.ui.IUserInterface.ExceptionListResult
|
||||||
|
import link.infra.packwiz.installer.ui.data.ExceptionDetails
|
||||||
|
import link.infra.packwiz.installer.ui.data.IOptionDetails
|
||||||
|
import link.infra.packwiz.installer.ui.data.InstallProgress
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.Future
|
import java.util.concurrent.Future
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
class CLIHandler : IUserInterface {
|
class CLIHandler : IUserInterface {
|
||||||
|
@Volatile
|
||||||
|
override var optionsButtonPressed = false
|
||||||
|
@Volatile
|
||||||
|
override var cancelButtonPressed = false
|
||||||
|
|
||||||
override fun handleException(e: Exception) {
|
override fun handleException(e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun show(handler: InputStateHandler) {}
|
override fun show() {}
|
||||||
|
override fun dispose() {}
|
||||||
override fun submitProgress(progress: InstallProgress) {
|
override fun submitProgress(progress: InstallProgress) {
|
||||||
val sb = StringBuilder()
|
val sb = StringBuilder()
|
||||||
if (progress.hasProgress) {
|
if (progress.hasProgress) {
|
||||||
@ -24,11 +34,6 @@ class CLIHandler : IUserInterface {
|
|||||||
println(sb.toString())
|
println(sb.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun executeManager(task: () -> Unit) {
|
|
||||||
task()
|
|
||||||
println("Finished successfully!")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun showOptions(options: List<IOptionDetails>): Future<Boolean> {
|
override fun showOptions(options: List<IOptionDetails>): Future<Boolean> {
|
||||||
for (opt in options) {
|
for (opt in options) {
|
||||||
opt.optionValue = true
|
opt.optionValue = true
|
@ -1,4 +1,4 @@
|
|||||||
package link.infra.packwiz.installer.ui
|
package link.infra.packwiz.installer.ui.data
|
||||||
|
|
||||||
data class ExceptionDetails(
|
data class ExceptionDetails(
|
||||||
val name: String,
|
val name: String,
|
@ -1,4 +1,4 @@
|
|||||||
package link.infra.packwiz.installer.ui
|
package link.infra.packwiz.installer.ui.data
|
||||||
|
|
||||||
interface IOptionDetails {
|
interface IOptionDetails {
|
||||||
val name: String
|
val name: String
|
@ -1,4 +1,4 @@
|
|||||||
package link.infra.packwiz.installer.ui
|
package link.infra.packwiz.installer.ui.data
|
||||||
|
|
||||||
data class InstallProgress(
|
data class InstallProgress(
|
||||||
val message: String,
|
val message: String,
|
@ -1,5 +1,7 @@
|
|||||||
package link.infra.packwiz.installer.ui
|
package link.infra.packwiz.installer.ui.gui
|
||||||
|
|
||||||
|
import link.infra.packwiz.installer.ui.IUserInterface
|
||||||
|
import link.infra.packwiz.installer.ui.data.ExceptionDetails
|
||||||
import java.awt.BorderLayout
|
import java.awt.BorderLayout
|
||||||
import java.awt.Desktop
|
import java.awt.Desktop
|
||||||
import java.awt.event.WindowAdapter
|
import java.awt.event.WindowAdapter
|
||||||
@ -16,7 +18,7 @@ import javax.swing.border.EmptyBorder
|
|||||||
class ExceptionListWindow(eList: List<ExceptionDetails>, future: CompletableFuture<IUserInterface.ExceptionListResult>, numTotal: Int, allowsIgnore: Boolean, parentWindow: JFrame?) : JDialog(parentWindow, "Failed file downloads", true) {
|
class ExceptionListWindow(eList: List<ExceptionDetails>, future: CompletableFuture<IUserInterface.ExceptionListResult>, numTotal: Int, allowsIgnore: Boolean, parentWindow: JFrame?) : JDialog(parentWindow, "Failed file downloads", true) {
|
||||||
private val lblExceptionStacktrace: JTextArea
|
private val lblExceptionStacktrace: JTextArea
|
||||||
|
|
||||||
private class ExceptionListModel internal constructor(private val details: List<ExceptionDetails>) : AbstractListModel<String>() {
|
private class ExceptionListModel(private val details: List<ExceptionDetails>) : AbstractListModel<String>() {
|
||||||
override fun getSize() = details.size
|
override fun getSize() = details.size
|
||||||
override fun getElementAt(index: Int) = details[index].name
|
override fun getElementAt(index: Int) = details[index].name
|
||||||
fun getExceptionAt(index: Int) = details[index].exception
|
fun getExceptionAt(index: Int) = details[index].exception
|
@ -1,10 +1,13 @@
|
|||||||
package link.infra.packwiz.installer.ui
|
package link.infra.packwiz.installer.ui.gui
|
||||||
|
|
||||||
|
import link.infra.packwiz.installer.ui.IUserInterface
|
||||||
import link.infra.packwiz.installer.ui.IUserInterface.ExceptionListResult
|
import link.infra.packwiz.installer.ui.IUserInterface.ExceptionListResult
|
||||||
|
import link.infra.packwiz.installer.ui.data.ExceptionDetails
|
||||||
|
import link.infra.packwiz.installer.ui.data.IOptionDetails
|
||||||
|
import link.infra.packwiz.installer.ui.data.InstallProgress
|
||||||
import java.awt.*
|
import java.awt.*
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.Future
|
import java.util.concurrent.Future
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
|
||||||
import javax.swing.*
|
import javax.swing.*
|
||||||
import javax.swing.border.EmptyBorder
|
import javax.swing.border.EmptyBorder
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
@ -15,10 +18,12 @@ class InstallWindow : IUserInterface {
|
|||||||
private lateinit var progressBar: JProgressBar
|
private lateinit var progressBar: JProgressBar
|
||||||
private lateinit var btnOptions: JButton
|
private lateinit var btnOptions: JButton
|
||||||
|
|
||||||
private var inputStateHandler: InputStateHandler? = null
|
@Volatile
|
||||||
|
override var optionsButtonPressed = false
|
||||||
|
@Volatile
|
||||||
|
override var cancelButtonPressed = false
|
||||||
|
|
||||||
private var title = "Updating modpack..."
|
private var title = "Updating modpack..."
|
||||||
private var worker: SwingWorkerButWithPublicPublish<Unit, InstallProgress>? = null
|
|
||||||
private val aboutToCrash = AtomicBoolean()
|
|
||||||
|
|
||||||
// TODO: separate JFrame junk from IUserInterface junk?
|
// TODO: separate JFrame junk from IUserInterface junk?
|
||||||
|
|
||||||
@ -55,7 +60,7 @@ class InstallWindow : IUserInterface {
|
|||||||
addActionListener {
|
addActionListener {
|
||||||
text = "Loading..."
|
text = "Loading..."
|
||||||
isEnabled = false
|
isEnabled = false
|
||||||
inputStateHandler?.pressOptionsButton()
|
optionsButtonPressed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
add(btnOptions, GridBagConstraints().apply {
|
add(btnOptions, GridBagConstraints().apply {
|
||||||
@ -66,7 +71,7 @@ class InstallWindow : IUserInterface {
|
|||||||
add(JButton("Cancel").apply {
|
add(JButton("Cancel").apply {
|
||||||
addActionListener {
|
addActionListener {
|
||||||
isEnabled = false
|
isEnabled = false
|
||||||
inputStateHandler?.pressCancelButton()
|
cancelButtonPressed = true
|
||||||
}
|
}
|
||||||
}, GridBagConstraints().apply {
|
}, GridBagConstraints().apply {
|
||||||
gridx = 0
|
gridx = 0
|
||||||
@ -77,10 +82,10 @@ class InstallWindow : IUserInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun show(handler: InputStateHandler) {
|
override fun show() {
|
||||||
inputStateHandler = handler
|
|
||||||
EventQueue.invokeLater {
|
EventQueue.invokeLater {
|
||||||
try {
|
try {
|
||||||
|
// TODO: shouldn't we do this before everything else?
|
||||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())
|
||||||
frmPackwizlauncher.isVisible = true
|
frmPackwizlauncher.isVisible = true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@ -89,9 +94,15 @@ class InstallWindow : IUserInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
EventQueue.invokeAndWait {
|
||||||
|
frmPackwizlauncher.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun handleException(e: Exception) {
|
override fun handleException(e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
EventQueue.invokeLater {
|
EventQueue.invokeAndWait {
|
||||||
JOptionPane.showMessageDialog(null,
|
JOptionPane.showMessageDialog(null,
|
||||||
"An error occurred: \n" + e.javaClass.canonicalName + ": " + e.message,
|
"An error occurred: \n" + e.javaClass.canonicalName + ": " + e.message,
|
||||||
title, JOptionPane.ERROR_MESSAGE)
|
title, JOptionPane.ERROR_MESSAGE)
|
||||||
@ -100,27 +111,17 @@ class InstallWindow : IUserInterface {
|
|||||||
|
|
||||||
override fun handleExceptionAndExit(e: Exception) {
|
override fun handleExceptionAndExit(e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
// TODO: Fix this mess
|
EventQueue.invokeAndWait {
|
||||||
// Used to prevent the done() handler of SwingWorker executing if the invokeLater hasn't happened yet
|
|
||||||
aboutToCrash.set(true)
|
|
||||||
EventQueue.invokeLater {
|
|
||||||
JOptionPane.showMessageDialog(null,
|
JOptionPane.showMessageDialog(null,
|
||||||
"A fatal error occurred: \n" + e.javaClass.canonicalName + ": " + e.message,
|
"A fatal error occurred: \n" + e.javaClass.canonicalName + ": " + e.message,
|
||||||
title, JOptionPane.ERROR_MESSAGE)
|
title, JOptionPane.ERROR_MESSAGE)
|
||||||
exitProcess(1)
|
exitProcess(1)
|
||||||
}
|
}
|
||||||
// Pause forever, so it blocks while we wait for System.exit to take effect
|
|
||||||
try {
|
|
||||||
Thread.currentThread().join()
|
|
||||||
} catch (ex: InterruptedException) { // no u
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setTitle(title: String) {
|
override fun setTitle(title: String) {
|
||||||
this.title = title
|
this.title = title
|
||||||
frmPackwizlauncher.let { frame ->
|
EventQueue.invokeLater { frmPackwizlauncher.title = title }
|
||||||
EventQueue.invokeLater { frame.title = title }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun submitProgress(progress: InstallProgress) {
|
override fun submitProgress(progress: InstallProgress) {
|
||||||
@ -135,45 +136,16 @@ class InstallWindow : IUserInterface {
|
|||||||
sb.append(progress.message)
|
sb.append(progress.message)
|
||||||
// TODO: better logging library?
|
// TODO: better logging library?
|
||||||
println(sb.toString())
|
println(sb.toString())
|
||||||
worker?.publishPublic(progress)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun executeManager(task: Function0<Unit>) {
|
|
||||||
EventQueue.invokeLater {
|
EventQueue.invokeLater {
|
||||||
// TODO: rewrite this stupidity to use channels??!!!
|
if (progress.hasProgress) {
|
||||||
worker = object : SwingWorkerButWithPublicPublish<Unit, InstallProgress>() {
|
progressBar.isIndeterminate = false
|
||||||
override fun doInBackground() {
|
progressBar.value = progress.progress
|
||||||
task.invoke()
|
progressBar.maximum = progress.progressTotal
|
||||||
}
|
} else {
|
||||||
|
progressBar.isIndeterminate = true
|
||||||
override fun process(chunks: List<InstallProgress>) {
|
progressBar.value = 0
|
||||||
// Only process last chunk
|
|
||||||
if (chunks.isNotEmpty()) {
|
|
||||||
val (message, hasProgress, progress, progressTotal) = chunks[chunks.size - 1]
|
|
||||||
if (hasProgress) {
|
|
||||||
progressBar.isIndeterminate = false
|
|
||||||
progressBar.value = progress
|
|
||||||
progressBar.maximum = progressTotal
|
|
||||||
} else {
|
|
||||||
progressBar.isIndeterminate = true
|
|
||||||
progressBar.value = 0
|
|
||||||
}
|
|
||||||
lblProgresslabel.text = message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun done() {
|
|
||||||
if (aboutToCrash.get()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// TODO: a better way to do this?
|
|
||||||
frmPackwizlauncher.dispose()
|
|
||||||
println("Finished successfully!")
|
|
||||||
exitProcess(0)
|
|
||||||
}
|
|
||||||
}.also {
|
|
||||||
it.execute()
|
|
||||||
}
|
}
|
||||||
|
lblProgresslabel.text = progress.message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,9 +179,11 @@ class InstallWindow : IUserInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun disableOptionsButton() {
|
override fun disableOptionsButton() {
|
||||||
btnOptions.apply {
|
EventQueue.invokeLater {
|
||||||
text = "No optional mods"
|
btnOptions.apply {
|
||||||
isEnabled = false
|
text = "No optional mods"
|
||||||
|
isEnabled = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,6 @@
|
|||||||
package link.infra.packwiz.installer.ui
|
package link.infra.packwiz.installer.ui.gui
|
||||||
|
|
||||||
|
import link.infra.packwiz.installer.ui.data.IOptionDetails
|
||||||
|
|
||||||
// Serves as a proxy for IOptionDetails, so that setOptionValue isn't called until OK is clicked
|
// Serves as a proxy for IOptionDetails, so that setOptionValue isn't called until OK is clicked
|
||||||
internal class OptionTempHandler(private val opt: IOptionDetails) : IOptionDetails {
|
internal class OptionTempHandler(private val opt: IOptionDetails) : IOptionDetails {
|
@ -1,5 +1,6 @@
|
|||||||
package link.infra.packwiz.installer.ui
|
package link.infra.packwiz.installer.ui.gui
|
||||||
|
|
||||||
|
import link.infra.packwiz.installer.ui.data.IOptionDetails
|
||||||
import java.awt.BorderLayout
|
import java.awt.BorderLayout
|
||||||
import java.awt.FlowLayout
|
import java.awt.FlowLayout
|
||||||
import java.awt.event.ActionEvent
|
import java.awt.event.ActionEvent
|
||||||
@ -18,7 +19,7 @@ class OptionsSelectWindow internal constructor(optList: List<IOptionDetails>, fu
|
|||||||
private val tableModel: OptionTableModel
|
private val tableModel: OptionTableModel
|
||||||
private val future: CompletableFuture<Boolean>
|
private val future: CompletableFuture<Boolean>
|
||||||
|
|
||||||
private class OptionTableModel internal constructor(givenOpts: List<IOptionDetails>) : TableModel {
|
private class OptionTableModel(givenOpts: List<IOptionDetails>) : TableModel {
|
||||||
private val opts: List<OptionTempHandler>
|
private val opts: List<OptionTempHandler>
|
||||||
|
|
||||||
init {
|
init {
|
Loading…
x
Reference in New Issue
Block a user