Mercurial > cgi-bin > hgweb.cgi > ClipMan
annotate src/name/blackcap/clipman/Misc.kt @ 52:c8ec2d7af3fb
Correct bad APPDATA code.
author | davidb |
---|---|
date | Tue, 14 Apr 2020 15:17:45 -0700 |
parents | 3f8409470fdf |
children |
rev | line source |
---|---|
27 | 1 /* |
2 * Miscellaneous utility stuff. | |
3 */ | |
4 package name.blackcap.clipman | |
5 | |
6 import java.awt.Dimension | |
7 import java.awt.Toolkit | |
41
33fbe3a78d84
Got the settings stuff compiling (untested).
David Barts <n5jrn@me.com>
parents:
31
diff
changeset
|
8 import java.nio.charset.Charset |
27 | 9 import javax.swing.* |
10 import javax.swing.text.JTextComponent | |
47
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
11 import kotlin.annotation.* |
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
12 import kotlin.properties.ReadWriteProperty |
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
13 import kotlin.reflect.* |
27 | 14 |
15 /** | |
31 | 16 * Name of the character set (encoding) we preferentially use for many |
17 * things. | |
18 */ | |
19 val CHARSET_NAME = "UTF-8" | |
41
33fbe3a78d84
Got the settings stuff compiling (untested).
David Barts <n5jrn@me.com>
parents:
31
diff
changeset
|
20 val CHARSET = Charset.forName(CHARSET_NAME) |
31 | 21 |
22 /** | |
47
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
23 * Delegate that makes a var that can only be set once. This is commonly |
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
24 * needed in Swing, because some vars inevitably need to be declared at |
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
25 * outer levels but initialized in the Swing event dispatch thread. |
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
26 * |
27 | 27 * @param <T> type of the associated value |
28 */ | |
50
3f8409470fdf
Input type to SetOnceImpl cannot be nullable.
David Barts <n5jrn@me.com>
parents:
47
diff
changeset
|
29 class SetOnceImpl<T: Any>: ReadWriteProperty<Any?,T> { |
47
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
30 private var setOnceValue: T? = null |
27 | 31 |
47
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
32 override operator fun getValue(thisRef: Any?, property: KProperty<*>): T { |
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
33 if (setOnceValue == null) { |
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
34 throw RuntimeException("${property.name} has not been initialized") |
27 | 35 } else { |
47
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
36 return setOnceValue!! |
27 | 37 } |
38 } | |
47
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
39 |
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
40 @Synchronized |
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
41 override operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T): Unit { |
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
42 if (setOnceValue != null) { |
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
43 throw RuntimeException("${property.name} has already been initialized") |
27 | 44 } |
47
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
45 setOnceValue = value |
27 | 46 } |
47 } | |
48 | |
49 /** | |
47
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
50 * Normal way to create a setOnce var: |
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
51 * var something: SomeType by setOnce() |
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
52 */ |
50
3f8409470fdf
Input type to SetOnceImpl cannot be nullable.
David Barts <n5jrn@me.com>
parents:
47
diff
changeset
|
53 fun <T: Any> setOnce(): SetOnceImpl<T> = SetOnceImpl<T>() |
47
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
54 |
19d9da731c43
Recoded; cleaned up root namespace, removed race conditions.
David Barts <n5jrn@me.com>
parents:
41
diff
changeset
|
55 /** |
27 | 56 * Run something in the Swing thread, asynchronously. |
57 * @param block lambda containing code to run | |
58 */ | |
59 fun inSwingThread(block: () -> Unit) { | |
60 SwingUtilities.invokeLater(Runnable(block)) | |
61 } | |
62 | |
63 /** | |
64 * Run something in the Swing thread, synchronously. | |
65 * @param block lambda containing code to run | |
66 */ | |
67 fun inSynSwingThread(block: () -> Unit) { | |
68 SwingUtilities.invokeAndWait(Runnable(block)) | |
69 } | |
70 | |
71 /** | |
72 * Autosize a JTextComponent to a given width. | |
73 * @param width the width | |
74 */ | |
75 fun JTextComponent.autoSize(width: Int): Unit { | |
76 val SLOP = 10 | |
77 val dim = Dimension(width, width) | |
78 preferredSize = dim | |
79 size = dim | |
80 val r = modelToView(document.length) | |
81 preferredSize = Dimension(width, r.y + r.height + SLOP) | |
82 } | |
83 | |
84 /** | |
85 * Make a shortcut for a menu item, using the standard combining key | |
86 * (control, command, etc.) for the system we're on. | |
87 * @param key KeyEvent constant describing the key | |
88 */ | |
89 fun JMenuItem.makeShortcut(key: Int): Unit { | |
90 val SC_KEY_MASK = Toolkit.getDefaultToolkit().menuShortcutKeyMask | |
91 setAccelerator(KeyStroke.getKeyStroke(key, SC_KEY_MASK)) | |
92 } | |
93 | |
94 /** | |
95 * Given a MenuElement object, get the item whose text matches the | |
96 * specified text. | |
97 * @param text to match | |
98 * @return first matched element, null if no match found | |
99 */ | |
100 fun MenuElement.getItem(name: String) : JMenuItem? { | |
101 subElements.forEach { | |
102 val jMenuItem = it.component as? JMenuItem | |
103 if (jMenuItem?.text == name) { | |
104 return jMenuItem | |
105 } | |
106 } | |
107 return null | |
108 } |