comparison src/name/blackcap/exifwasher/Misc.kt @ 5:dc1f4359659d

Got it compiling.
author David Barts <n5jrn@me.com>
date Thu, 09 Apr 2020 18:20:34 -0700
parents 19c381c536ec
children 88d02fa97d78
comparison
equal deleted inserted replaced
4:ba5dc14652da 5:dc1f4359659d
7 import java.awt.Cursor 7 import java.awt.Cursor
8 import java.awt.Toolkit 8 import java.awt.Toolkit
9 import javax.swing.* 9 import javax.swing.*
10 import kotlin.annotation.* 10 import kotlin.annotation.*
11 import kotlin.properties.ReadWriteProperty 11 import kotlin.properties.ReadWriteProperty
12 import kotlin.reflect.KProperty 12 import kotlin.reflect.*
13 13
14 /** 14 /**
15 * Delegate that makes a var that can only be set once. This is commonly 15 * Delegate that makes a var that can only be set once. This is commonly
16 * needed in Swing, because some vars inevitably need to be declared at 16 * needed in Swing, because some vars inevitably need to be declared at
17 * outer levels but initialized in the Swing event dispatch thread. 17 * outer levels but initialized in the Swing event dispatch thread.
18 */ 18 */
19 class SetOnce<T: Any>: ReadWriteProperty<Any?,T> { 19 class SetOnce<T: Any>: ReadWriteProperty<Any?,T> {
20 private var value: T? = null 20 private var setOnceValue: T? = null
21 21
22 override operator fun getValue(thisRef: Any?, property: KProperty<*>): T { 22 override operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
23 if (value == null) { 23 if (setOnceValue == null) {
24 throw RuntimeException("${property.name} has not been initialized") 24 throw RuntimeException("${property.name} has not been initialized")
25 } else { 25 } else {
26 return value!! 26 return setOnceValue!!
27 } 27 }
28 } 28 }
29 29
30 @Synchronized 30 @Synchronized
31 override operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: T): Unit { 31 override operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T): Unit {
32 if (value != null) { 32 if (setOnceValue != null) {
33 throw RuntimeException("${property.name} has already been initialized") 33 throw RuntimeException("${property.name} has already been initialized")
34 } 34 }
35 value = newValue 35 setOnceValue = value
36 } 36 }
37 } 37 }
38 38
39 /** 39 /**
40 * Run something in the Swing thread, asynchronously. 40 * Run something in the Swing thread, asynchronously.
80 80
81 /** 81 /**
82 * Change to the standard wait cursor. 82 * Change to the standard wait cursor.
83 */ 83 */
84 fun Component.useWaitCursor() { 84 fun Component.useWaitCursor() {
85 this.cursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)) 85 this.cursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)
86 } 86 }
87 87
88 /** 88 /**
89 * Return back to the normal cursor(). 89 * Return back to the normal cursor().
90 */ 90 */
91 fun Component.useNormalCursor() { 91 fun Component.useNormalCursor() {
92 this.cursor = Cursor.defaultCursor 92 this.cursor = Cursor.getDefaultCursor()
93 } 93 }
94 94
95 /** 95 /**
96 * Thrown if the programmer botches something in our DSL. 96 * Thrown if the programmer botches something in our DSL.
97 */ 97 */
103 * to execute when complete. 103 * to execute when complete.
104 * 104 *
105 * @param T Type returned by inBackground (Java doInBackground) task. 105 * @param T Type returned by inBackground (Java doInBackground) task.
106 */ 106 */
107 class SwingWorkerBuilder<T>: SwingWorker<T,Unit>() { 107 class SwingWorkerBuilder<T>: SwingWorker<T,Unit>() {
108 private var inBackgroundLambda: (SwingWorkerBuilder.() -> T)? = null 108 private var inBackgroundLambda: (SwingWorkerBuilder<T>.() -> T)? = null
109 private var whenDoneLambda: (SwingWorkerBuilder.() -> Unit)? = null 109 private var whenDoneLambda: (SwingWorkerBuilder<T>.() -> Unit)? = null
110 110
111 private fun setOnce<U>(prop: KMutableProperty<(SwingWorkerBuilder.() -> U)?>, value: SwingWorkerBuilder.() -> U) { 111 private fun <U> setOnce(prop: KMutableProperty0<(SwingWorkerBuilder<T>.() -> U)?>, value: SwingWorkerBuilder<T>.() -> U) {
112 if (prop.get() != null) { 112 if (prop.get() != null) {
113 throw SwingWorkerException(prop.name.removeSuffix("Lambda") + " already defined!") 113 throw SwingWorkerException(prop.name.removeSuffix("Lambda") + " already defined!")
114 } 114 }
115 prop.set(value) 115 prop.set(value)
116 } 116 }
117 117
118 /** 118 /**
119 * Define the inBackground task. 119 * Define the inBackground task.
120 */ 120 */
121 fun inBackground(lambda: SwingWorkerBuilder.() -> T): Unit { 121 fun inBackground(lambda: SwingWorkerBuilder<T>.() -> T): Unit {
122 setOnce<T>(::inBackgroundLambda, lambda) 122 setOnce<T>(::inBackgroundLambda, lambda)
123 } 123 }
124 124
125 /** 125 /**
126 * Define the whenDone task. 126 * Define the whenDone task.
127 */ 127 */
128 fun whenDone(lambda: SwingWorkerBuilder.() -> Unit): Unit { 128 fun whenDone(lambda: SwingWorkerBuilder<T>.() -> Unit): Unit {
129 setOnce<Unit>(::whenDoneLambda, lambda) 129 setOnce<Unit>(::whenDoneLambda, lambda)
130 }
131
132 /**
133 * Validates we've been properly initialized.
134 */
135 fun validate(): Unit {
136 if (inBackgroundLambda == null) {
137 throw SwingWorkerException("inBackground not defined!")
138 }
130 } 139 }
131 140
132 /* standard overrides for SwingWorker follow */ 141 /* standard overrides for SwingWorker follow */
133 142
134 override fun doInBackground(): T = inBackgroundLambda?.invoke(this) 143 override fun doInBackground(): T = inBackgroundLambda!!.invoke(this)
135 144
136 override fun done(): Unit = whenDoneLambda?.invoke(this) 145 override fun done(): Unit = whenDoneLambda?.invoke(this) ?: Unit
137
138 override fun execute(): Unit {
139 if (inBackgroundLambda == null) {
140 throw SwingWorkerException("inBackground not defined!")
141 } else {
142 super.execute()
143 }
144 }
145 } 146 }
146 147
147 /** 148 /**
148 * Provides for an outer swingWorker block to contain the DSL. 149 * Provides for an outer swingWorker block to contain the DSL.
149 */ 150 */
150 fun swingWorker<T>(initializer: SwingWorkerBuilder.() -> Unit): Unit { 151 fun <T> swingWorker(initializer: SwingWorkerBuilder<T>.() -> Unit): Unit {
151 SwingWorkerBuilder<T>().run { 152 SwingWorkerBuilder<T>().run {
152 initializer() 153 initializer()
154 validate()
153 execute() 155 execute()
154 } 156 }
155 } 157 }
156 158
157 /** 159 /**