]> uap-core.de Git - rssreader.git/commitdiff
add kotlin dispatcher
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 20 Jul 2025 10:48:39 +0000 (12:48 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 20 Jul 2025 10:48:39 +0000 (12:48 +0200)
rss-application/src/main/kotlin/de/unixwork/rssreader/App.kt
rss-application/src/main/kotlin/de/unixwork/rssreader/MainWindow.kt
ui-java/src/main/java/de/unixwork/ui/Toolkit.java
ui-kotlin/pom.xml
ui-kotlin/src/main/kotlin/de/unixwork/ui/kotlin/BlockingToolkitDispatcher.kt [new file with mode: 0644]
ui-kotlin/src/main/kotlin/de/unixwork/ui/kotlin/ToolkitDispatcher.kt [new file with mode: 0644]
ui-kotlin/src/main/kotlin/de/unixwork/ui/kotlin/Toplevel.kt
ui-kotlin/src/test/kotlin/de/unixwork/ui/kotlin/demo/Test.kt

index 4d1b0a5ea7a1fbfdbf7c56708073abbbc84d6fde..744fc912cb92aab5c3c49574c0ae0b3bcb9a0c29 100644 (file)
@@ -8,6 +8,10 @@ class App : Application {
         val window = MainWindow()
         window.show()
     }
+
+    override fun shutdown() {
+        System.exit(0)
+    }
 }
 
 fun main() {
index 094bfab7d000a8ea3c98b106c74db6c2583ddb08..f3c1a65b272cb4695711504dc77d6f6641a34580 100644 (file)
@@ -10,6 +10,7 @@ class MainWindow {
 
     init {
         window = sidebarWindow("RSS Reader") {
+
             sidebar {
                 vbox(fill = true) {
                     sourcelist { elm: Object ->
@@ -23,6 +24,7 @@ class MainWindow {
                 }
             }
 
+
             hsplitpane(initialPosition = 300) {
                 vbox {
                     listview<String>(varname = "items", fill = true) { elm, col ->
@@ -34,6 +36,7 @@ class MainWindow {
                     webview(varname = "webview", fill = true)
                 }
             }
+
         }
     }
 
index 90d2a5d31f831f99dd2e1505e5d9d932a9a42156..b2c7f9fbcfb272fb56f7126a50dc9f4db512aeaf 100644 (file)
@@ -183,7 +183,7 @@ public class Toolkit {
         // threadfunc wrapper
         try {
             MethodHandle threadFuncCallback = MethodHandles.lookup().findStatic(
-                    Thread.class,
+                    Toolkit.class,
                     "threadFunc",
                     MethodType.methodType(int.class, MemorySegment.class));
             FunctionDescriptor threadFuncDescriptor = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS);
index df08ad2b242b9c6912531fc112029500c4c6e04b..03f2d8130477d4221a9c58e8bd5e110b3162f6fd 100644 (file)
             <artifactId>kotlin-stdlib</artifactId>
             <version>2.1.20</version>
         </dependency>
+        <dependency>
+            <groupId>org.jetbrains.kotlinx</groupId>
+            <artifactId>kotlinx-coroutines-core</artifactId>
+            <version>1.10.2</version>
+        </dependency>
                
                <dependency>
             <groupId>de.unixwork</groupId>
diff --git a/ui-kotlin/src/main/kotlin/de/unixwork/ui/kotlin/BlockingToolkitDispatcher.kt b/ui-kotlin/src/main/kotlin/de/unixwork/ui/kotlin/BlockingToolkitDispatcher.kt
new file mode 100644 (file)
index 0000000..2066fe1
--- /dev/null
@@ -0,0 +1,23 @@
+package de.unixwork.ui.kotlin
+
+import de.unixwork.ui.Toolkit
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Runnable
+import java.util.concurrent.Executor
+
+object BlockingToolkitDispatcher : CoroutineDispatcher() {
+    override fun dispatch(context: kotlin.coroutines.CoroutineContext, block: Runnable) {
+        val latch = java.util.concurrent.CountDownLatch(1)
+
+        Toolkit.getInstance().invokeMainThread {
+            try {
+                block.run()
+            } finally {
+                latch.countDown()
+            }
+        }
+
+        // Block the calling thread until execution finishes
+        latch.await()
+    }
+}
\ No newline at end of file
diff --git a/ui-kotlin/src/main/kotlin/de/unixwork/ui/kotlin/ToolkitDispatcher.kt b/ui-kotlin/src/main/kotlin/de/unixwork/ui/kotlin/ToolkitDispatcher.kt
new file mode 100644 (file)
index 0000000..aca7b7e
--- /dev/null
@@ -0,0 +1,14 @@
+package de.unixwork.ui.kotlin
+
+import de.unixwork.ui.Toolkit
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Runnable
+import java.util.concurrent.Executor
+
+object ToolkitDispatcher : CoroutineDispatcher() {
+    override fun dispatch(context: kotlin.coroutines.CoroutineContext, block: Runnable) {
+        Toolkit.getInstance().invokeMainThread {
+            block.run()
+        }
+    }
+}
\ No newline at end of file
index 6fe4517dd8c2464fab487230f49c524eb163973c..20bfbb96cd2cb181173226bea8216a1207acfe60 100644 (file)
@@ -2,12 +2,10 @@ package de.unixwork.ui.kotlin
 
 import de.unixwork.ui.Alignment
 import de.unixwork.ui.Button
-import de.unixwork.ui.ButtonBuilder
 import de.unixwork.ui.Container
 import de.unixwork.ui.ContainerBuilder
 import de.unixwork.ui.ContainerUI
 import de.unixwork.ui.EventHandler
-import de.unixwork.ui.EventWrapper.eventHandler
 import de.unixwork.ui.LabelBuilder
 import de.unixwork.ui.LabelStyle
 import de.unixwork.ui.ListValueConverter
@@ -24,13 +22,12 @@ import de.unixwork.ui.UiString
 import de.unixwork.ui.UiWidget
 import de.unixwork.ui.WebView
 import de.unixwork.ui.Label
-import java.lang.foreign.MemorySegment
 
 class Toplevel(obj: UiObject) {
-    private val obj: UiObject = obj
+    val ui: UiObject = obj
 
     fun show() {
-        obj.show()
+        ui.show()
     }
 
     operator fun invoke(block: Toplevel.() -> Unit) {
@@ -124,7 +121,7 @@ class Toplevel(obj: UiObject) {
         ui: ContainerUI? = null
     ): UiWidget {
         return createContainer(
-            container = Container.hbox(obj),
+            container = Container.hbox(this@Toplevel.ui),
             fill = fill,
             hexpand = hexpand,
             vexpand = vexpand,
@@ -158,7 +155,7 @@ class Toplevel(obj: UiObject) {
         ui: ContainerUI? = null
     ): UiWidget {
         return createContainer(
-            container = Container.vbox(obj),
+            container = Container.vbox(this@Toplevel.ui),
             fill = fill,
             hexpand = hexpand,
             vexpand = vexpand,
@@ -198,7 +195,7 @@ class Toplevel(obj: UiObject) {
         ui: ContainerUI? = null
     ): UiWidget {
         return createContainer(
-            container = Container.grid(obj),
+            container = Container.grid(this@Toplevel.ui),
             fill = fill,
             hexpand = hexpand,
             vexpand = vexpand,
@@ -225,7 +222,7 @@ class Toplevel(obj: UiObject) {
         ui: ContainerUI? = null
     ) {
         ui?.callback()
-        Container.newline(obj)
+        Container.newline(this@Toplevel.ui)
     }
 
     private fun createSplitpane(
@@ -249,9 +246,9 @@ class Toplevel(obj: UiObject) {
         ui: ContainerUI? = null
     ): UiWidget {
         val container = if(horizontal) {
-            Container.hsplitview(obj)
+            Container.hsplitview(this@Toplevel.ui)
         } else {
-            Container.vsplitview(obj)
+            Container.vsplitview(this@Toplevel.ui)
         }
 
         if(hexpand) {
@@ -392,7 +389,7 @@ class Toplevel(obj: UiObject) {
         spacing: Int = -1,
         ui: ContainerUI? = null
     ): UiWidget {
-        val container = Container.sidebar(obj)
+        val container = Container.sidebar(this@Toplevel.ui)
 
         if(margin > 0) {
             container.margin(margin)
@@ -426,7 +423,7 @@ class Toplevel(obj: UiObject) {
         styleClass: String? = null,
         onClick: EventHandler? = null
     ): UiWidget {
-        val button = Button.button(obj)
+        val button = Button.button(ui)
         label?.let {
             button.label(it)
         }
@@ -561,7 +558,7 @@ class Toplevel(obj: UiObject) {
         onChange: EventHandler? = null
     ): UiWidget {
         return createToggleButton(
-            button = Button.toggleButton(obj),
+            button = Button.toggleButton(ui),
             label = label,
             stockId = stockId,
             icon = icon,
@@ -600,7 +597,7 @@ class Toplevel(obj: UiObject) {
         onChange: EventHandler? = null
     ): UiWidget {
         return createToggleButton(
-            button = Button.checkbox(obj),
+            button = Button.checkbox(ui),
             label = label,
             stockId = stockId,
             icon = icon,
@@ -639,7 +636,7 @@ class Toplevel(obj: UiObject) {
         onChange: EventHandler? = null
     ): UiWidget {
         return createToggleButton(
-            button = Button.switchButton(obj),
+            button = Button.switchButton(ui),
             label = label,
             stockId = stockId,
             icon = icon,
@@ -678,7 +675,7 @@ class Toplevel(obj: UiObject) {
         onChange: EventHandler? = null
     ): UiWidget {
         return createToggleButton(
-            button = Button.radioButton(obj),
+            button = Button.radioButton(ui),
             label = label,
             stockId = stockId,
             icon = icon,
@@ -713,7 +710,7 @@ class Toplevel(obj: UiObject) {
         styleClass: String? = null,
         getvalue: ListValueConverter<T>? = null
     ): UiWidget {
-        val list = ListView.list<T>(obj)
+        val list = ListView.list<T>(ui)
         varname?.let {
             list.varname(varname)
         }
@@ -771,7 +768,7 @@ class Toplevel(obj: UiObject) {
         styleClass: String? = null,
         getvalue: SubListValueConverter<T>? = null
     ): UiWidget {
-        val list = ListView.sourcelist<T>(obj)
+        val list = ListView.sourcelist<T>(ui)
         varname?.let {
             list.varname(varname)
         }
@@ -887,7 +884,7 @@ class Toplevel(obj: UiObject) {
         styleClass: String? = null,
         onChange: EventHandler? = null
     ): UiWidget {
-        val textfield = Text.textfield(obj)
+        val textfield = Text.textfield(ui)
         return createTextField(
             textfield = textfield,
             varname = varname,
@@ -921,7 +918,7 @@ class Toplevel(obj: UiObject) {
         styleClass: String? = null,
         onChange: EventHandler? = null
     ): UiWidget {
-        val textfield = Text.passwordfield(obj)
+        val textfield = Text.passwordfield(ui)
         return createTextField(
             textfield = textfield,
             varname = varname,
@@ -955,7 +952,7 @@ class Toplevel(obj: UiObject) {
         styleClass: String? = null,
         onChange: EventHandler? = null
     ): UiWidget {
-        val textfield = Text.framelessTextfield(obj)
+        val textfield = Text.framelessTextfield(ui)
         return createTextField(
             textfield = textfield,
             varname = varname,
@@ -989,7 +986,7 @@ class Toplevel(obj: UiObject) {
         styleClass: String? = null,
         onChange: EventHandler? = null
     ): UiWidget {
-        val webview = WebView.webview(obj)
+        val webview = WebView.webview(ui)
         varname?.let {
             webview.varname(it)
         }
@@ -1114,7 +1111,7 @@ class Toplevel(obj: UiObject) {
         name: String? = null,
         styleClass: String? = null
         ): UiWidget {
-        val labelBuilder = Label.label(obj)
+        val labelBuilder = Label.label(ui)
         return createLabel(
             label = labelBuilder,
             labelStr = label,
@@ -1151,7 +1148,7 @@ class Toplevel(obj: UiObject) {
         name: String? = null,
         styleClass: String? = null
     ): UiWidget {
-        val labelBuilder = Label.llabel(obj)
+        val labelBuilder = Label.llabel(ui)
         return createLabel(
             label = labelBuilder,
             labelStr = label,
@@ -1187,7 +1184,7 @@ class Toplevel(obj: UiObject) {
         name: String? = null,
         styleClass: String? = null
     ): UiWidget {
-        val labelBuilder = Label.rlabel(obj)
+        val labelBuilder = Label.rlabel(ui)
         return createLabel(
             label = labelBuilder,
             labelStr = label,
index 2da3998b1c28d708e77ed3c6462cb37182cd1db5..04b4e67b8c6817c6d07940499a89b7cca2b32a6c 100644 (file)
@@ -4,18 +4,28 @@ import de.unixwork.ui.Application
 import de.unixwork.ui.ToolbarPosition
 import de.unixwork.ui.Toolkit
 import de.unixwork.ui.kotlin.*
-
+import kotlinx.coroutines.*
 
 class Test : Application {
     override fun startup() {
         toolbarItem(name = "button1", label = "Test")
         addToolbarDefault("button1", ToolbarPosition.RIGHT);
 
-        val window = window("Test Window") {
+        val win = window("Test Window") {
+            val mystr = ui.string()
             grid {
                 vbox(vexpand = true, vfill = true) {
-                    button("B1")
-                    button("B2")
+                    button("B1") {
+                        CoroutineScope(Dispatchers.IO).launch {
+                            repeat(100) { index ->
+                                delay(5000L)
+                                withContext(BlockingToolkitDispatcher) {
+                                    mystr.setString("iteration " + index)
+                                }
+                            }
+                        }
+                    }
+                    textfield(value = mystr)
                     button("B3")
                 }
                 grid(columnspacing = 10, rowspacing = 10, hexpand = true, hfill = true, vexpand = true) {
@@ -35,7 +45,7 @@ class Test : Application {
             }
         }
 
-        window.show()
+        win.show()
     }
 }