swing-ui 1.1.7 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SwingUI.js CHANGED
@@ -41,14 +41,12 @@ export class SwingUI
41
41
  #_msg_queue = [];
42
42
  #queue_limit = 100; // send queued messages after queue size reaches this limit (0 = no message queue)
43
43
  #msgCompressThreshold = 1000; // compress messages longer than this
44
- #textDecoder = new TextDecoder("utf8");
45
44
 
46
45
  #jvm = {
47
46
  stdio: {}, JBridge: null, process: null, eventListener: e =>
48
47
  {
49
48
  }
50
49
  };
51
- #guiManagerWorker = null; // for GUI Process manager worker
52
50
  #exiting = false;
53
51
 
54
52
  /**
@@ -88,9 +86,9 @@ export class SwingUI
88
86
  11: "Failed to set menu menu. Passed parameter must be of type MenuBar()"
89
87
  };
90
88
 
91
- //region For Worker IPC only
89
+ //region For Worker IPC
92
90
 
93
- #useWorkerThread = false;
91
+ #guiManagerWorker = null;
94
92
  #worker_port1 = null;
95
93
  #worker_port2 = null;
96
94
 
@@ -156,21 +154,15 @@ export class SwingUI
156
154
  }
157
155
  }();
158
156
 
159
- /**
160
- * Detects best compatible base64 decoder
161
- */
162
- #decodeBase64 = typeof Uint8Array.fromBase64 === 'function' ? b64 => Uint8Array.fromBase64(b64) : typeof Buffer !== 'undefined' ? b64 => Buffer.from(b64, 'base64') : b64 => Uint8Array.from(atob(b64), c => c.charCodeAt(0));
163
-
164
157
  //region Internal
165
158
 
166
159
  /**
167
160
  * <b>NOTE:</b> Do not instantiate this class. It's already instantiated and assigned to a global variable `ui`.
168
161
  * @internal
169
162
  */
170
- constructor(module_dir, JBridge)
163
+ constructor(module_dir)
171
164
  {
172
165
  this.#module_dir = module_dir;
173
- this.#jvm.JBridge = JBridge;
174
166
  this.rootDirectory; // detect project dir now
175
167
 
176
168
  // ensure cleanup
@@ -189,192 +181,102 @@ export class SwingUI
189
181
  */
190
182
  async InitGUIProcess()
191
183
  {
192
- if(this.runtime === "bun" || this.os === "darwin") this.#useWorkerThread = true;
193
-
194
184
  const env = this.env;
195
185
 
196
186
  if(process.argv.some(arg => arg.startsWith("--java-dir="))) env.JAVA_HOME = process.argv.find(arg => arg.startsWith("--java-dir=")).split("=")[1];
197
187
 
198
- if(this.#useWorkerThread)
199
- {
200
- this.#msgCompressThreshold = 500; // reduce the threshold
201
-
202
- const {port1, port2} = new MessageChannel();
203
- this.#worker_port1 = port1;
204
- this.#worker_port2 = port2;
205
-
206
- // start IPC Worker
207
- const workerPath = path.join(this.#module_dir, "ui-process-manager.js");
208
-
209
- // set a value for the thread to wait for the worker to start
210
- Atomics.store(this.#sharedBuffSignal, SwingUI.WorkerSignalIndex.ExecutionControl, SwingUI.WorkerSignal.Block);
211
-
212
- const options = {
213
- type: "module",
214
- workerData: {
215
- signalBuffer: this.#sharedBuffSignal,
216
- responsePort: this.#worker_port2,
217
- moduleDir: this.#module_dir,
218
- rootDir: this.rootDirectory,
219
- debugJava: process.argv.some(arg => arg === "--debug-java"),
220
- verbose: process.argv.some(arg => arg === "--v"),
221
- os: this.os,
222
- runtime: this.runtime
223
- },
224
- transferList: [this.#worker_port2],
225
- stdout: true,
226
- stderr: true,
227
- env: env
228
- };
188
+ this.#msgCompressThreshold = 500; // reduce the threshold
189
+
190
+ const {port1, port2} = new MessageChannel();
191
+ this.#worker_port1 = port1;
192
+ this.#worker_port2 = port2;
193
+
194
+ // start IPC Worker
195
+ const workerPath = path.join(this.#module_dir, "ui-process-manager.js");
196
+
197
+ // set a value for the thread to wait for the worker to start
198
+ Atomics.store(this.#sharedBuffSignal, SwingUI.WorkerSignalIndex.ExecutionControl, SwingUI.WorkerSignal.Block);
199
+
200
+ const options = {
201
+ type: "module",
202
+ workerData: {
203
+ signalBuffer: this.#sharedBuffSignal,
204
+ responsePort: this.#worker_port2,
205
+ moduleDir: this.#module_dir,
206
+ rootDir: this.rootDirectory,
207
+ debugJava: process.argv.some(arg => arg === "--debug-java"),
208
+ verbose: process.argv.some(arg => arg === "--v"),
209
+ os: this.os,
210
+ runtime: this.runtime
211
+ },
212
+ transferList: [this.#worker_port2],
213
+ stdout: true,
214
+ stderr: true,
215
+ env: env
216
+ };
229
217
 
230
- this.#guiManagerWorker = new Worker(workerPath, options);
218
+ this.#guiManagerWorker = new Worker(workerPath, options);
231
219
 
232
- // forward worker logs to the main process
233
- if(this.#guiManagerWorker.stdout != null) // e.g.. bun, and deno on macOS don't have stdout
234
- {
235
- this.#guiManagerWorker.stdout.on("data", chunk => console.log(chunk.toString()));
236
- this.#guiManagerWorker.stderr.on("data", chunk => console.error(chunk.toString()));
237
- }
220
+ // forward worker logs to the main process
221
+ if(this.#guiManagerWorker.stdout != null) // e.g.. bun, and deno on macOS don't have stdout
222
+ {
223
+ this.#guiManagerWorker.stdout.on("data", chunk => console.log(chunk.toString()));
224
+ this.#guiManagerWorker.stderr.on("data", chunk => console.error(chunk.toString()));
225
+ }
238
226
 
239
- this.#guiManagerWorker.on("message", (msg) =>
227
+ this.#guiManagerWorker.on("message", (msg) =>
228
+ {
229
+ switch(msg.type)
240
230
  {
241
- switch(msg.type)
231
+ case "data":
242
232
  {
243
- case "data":
244
- {
245
- this.#inputLinesBuffer.push(msg.data);
246
- if(this.#inputLinesBuffer.length < 2) queueMicrotask(() => {this.#processInputData();});
247
- break;
248
- }
249
- case "exit":
250
- {
251
- this.exit(0);
252
- break;
253
- }
254
- case "worker_log":
255
- {
256
- console.log(`WORKER THREAD: ${msg.data}`);
257
- break;
258
- }
259
- case "worker_debug":
260
- {
261
- console.debug(`WORKER THREAD: ${msg.data}`);
262
- break;
263
- }
264
- case "worker_warn":
265
- {
266
- console.warn(`WORKER THREAD: ${msg.data}`);
267
- break;
268
- }
269
- case "worker_info":
270
- {
271
- console.info(`WORKER THREAD: ${msg.data}`);
272
- break;
273
- }
274
- case "worker_error":
275
- {
276
- console.error(`WORKER THREAD ERROR: ${msg.data}`);
277
- break;
278
- }
233
+ this.#inputLinesBuffer.push(msg.data);
234
+ if(this.#inputLinesBuffer.length < 2) queueMicrotask(() => {this.#processInputData();});
235
+ break;
279
236
  }
280
- });
281
- this.#guiManagerWorker.on("online", () => {});
282
- this.#guiManagerWorker.on("error", (err) => console.error("[SwingUI] GUI Worker error:", err));
283
- this.#guiManagerWorker.on("exit", (code) =>
284
- {
285
- if(!this.#exiting && code !== 0) console.error(`[SwingUI] GUI Worker stopped unexpectedly (exit code ${code})`);
286
- this.exit(code);
287
- });
288
-
289
- // wait for the worker to start
290
- const r = Atomics.wait(this.#sharedBuffSignal, SwingUI.WorkerSignalIndex.ExecutionControl, SwingUI.WorkerSignal.Block, 10000);
291
- if(r === "timed-out") throw new Error("Failed to start GUI Worker: timeout.");
292
- }
293
- else
294
- {
295
- const jvmOpts = {opts: [], env: env};
296
- if(process.argv.some(arg => arg === "--debug-java")) jvmOpts.opts.push("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005");
297
- if(this.os === "linux") jvmOpts.opts.push("--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED"); // to be able to set WM_CLASS in Java GUI
298
- if(this.os === "darwin")
299
- {
300
- jvmOpts.opts.push("-Dapple.awt.UIElement=true");
301
- jvmOpts.opts.push("-Dapple.awt.headless=false"); // was supposed to help JVM on macOS, but didn't. macOS doesn't allow GUI on non-main thread.
302
- }
303
-
304
- this.#jvm.JBridge.ensureJvm(jvmOpts);
305
- this.#jvm.JBridge.appendClasspath(path.join(this.#module_dir, "jar/gui-11.jar"));
306
- const JBridgeProcessHandle = this.#jvm.JBridge.importClass("java.lang.ProcessHandle");
307
- this.#jvm.process = await JBridgeProcessHandle.current();
308
- this.gui_process_id = Number(await this.#jvm.process.pid());
309
-
310
- // receive events from GUI
311
- this.#jvm.stdio.stdout = (_, line) =>
312
- {
313
- line = line.trim();
314
- if(!line) return;
315
-
316
- if(line.startsWith("GUI-EVENT->"))
237
+ case "exit":
317
238
  {
318
- try
319
- {
320
- const message = this.#textDecoder.decode(this.#decodeBase64(line.substring(11)));
321
- this.#inputLinesBuffer.push(message);
322
- }catch(ex)
323
- {
324
- console.error("Failed to parse IPC event:", ex);
325
- }
239
+ this.exit(0);
240
+ break;
326
241
  }
327
- else
242
+ case "worker_log":
328
243
  {
329
- console.log(line);
244
+ console.log(`WORKER THREAD: ${msg.data}`);
245
+ break;
330
246
  }
331
-
332
- this.#processInputData();
333
- };
334
-
335
- this.#jvm.stdio.stderr = (_, data) =>
336
- {
337
- console.error(data);
338
- };
339
-
340
- // enable STDIO redirect to our handlers
341
- this.#jvm.stdio.guard = this.#jvm.JBridge.stdout.enableRedirect(this.#jvm.stdio.stdout, this.#jvm.stdio.stderr);
342
-
343
- /*
344
- this.#jvm.eventListener = this.#jvm.JBridge.newProxy("SwingUI$Callback", {
345
- eventCall: data =>
247
+ case "worker_debug":
346
248
  {
347
- if(this.#inputLinesBuffer.length === 0) queueMicrotask(() => {this.#processInputData();});
348
-
349
- data = this.#textDecoder.decode(this.#decodeBase64(data));
350
-
351
- this.#inputLinesBuffer.push(data);
249
+ console.debug(`WORKER THREAD: ${msg.data}`);
250
+ break;
352
251
  }
353
- });
354
- */
355
-
356
- const ui_class = this.#jvm.JBridge.importClass("SwingUI");
357
- const ops = JSON.stringify({
358
- module_dir: this.#module_dir,
359
- root_dir: this.rootDirectory,
360
- verbose: process.argv.some(arg => arg === "--v")
361
- });
362
- this.#jvm.gui = new ui_class(ops);
363
- //await this.#jvm.gui.setEventCallback(this.#jvm.eventListener);
364
-
365
- // Watchdog
366
- this.#watchdog_timer = setInterval(() =>
367
- {
368
- try
252
+ case "worker_warn":
369
253
  {
370
- process.kill(this.gui_process_id, 0);
371
- }catch(ex)
254
+ console.warn(`WORKER THREAD: ${msg.data}`);
255
+ break;
256
+ }
257
+ case "worker_info":
372
258
  {
373
- console.log("Watchdog timer says the GUI process exited, so JS can exit too.");
374
- if(ex.code === "ESRCH") this.exit(1);
259
+ console.info(`WORKER THREAD: ${msg.data}`);
260
+ break;
375
261
  }
376
- }, 5000);
377
- }
262
+ case "worker_error":
263
+ {
264
+ console.error(`WORKER THREAD ERROR: ${msg.data}`);
265
+ break;
266
+ }
267
+ }
268
+ });
269
+ this.#guiManagerWorker.on("online", () => {});
270
+ this.#guiManagerWorker.on("error", (err) => console.error("[SwingUI] GUI Worker error:", err));
271
+ this.#guiManagerWorker.on("exit", (code) =>
272
+ {
273
+ if(!this.#exiting && code !== 0) console.error(`[SwingUI] GUI Worker stopped unexpectedly (exit code ${code})`);
274
+ this.exit(code);
275
+ });
276
+
277
+ // wait for the worker to start
278
+ const r = Atomics.wait(this.#sharedBuffSignal, SwingUI.WorkerSignalIndex.ExecutionControl, SwingUI.WorkerSignal.Block, 10000);
279
+ if(r === "timed-out") throw new Error("Failed to start GUI Worker: timeout.");
378
280
 
379
281
  // report current version of this module to UI
380
282
  this.sendToGUI({system: "version", value: this.#gui_version, pid: this.pid}, async r =>
@@ -417,16 +319,6 @@ export class SwingUI
417
319
  {
418
320
  if(typeof msg !== "string" || msg.length === 0) return null;
419
321
 
420
- /*try
421
- {
422
- msg = decodeURIComponent(msg).trim();
423
- }catch(ex)
424
- {
425
- console.error(this._msg[9] + msg + "\n\n" + ex.stack);
426
- console.error(ex);
427
- return null;
428
- }*/
429
-
430
322
  if(msg.startsWith("{") && msg.endsWith("}"))
431
323
  {
432
324
  try
@@ -707,13 +599,7 @@ export class SwingUI
707
599
  sendToGUI(msg, callback = null)
708
600
  {
709
601
  // create default callback for "get" messages
710
- if(callback === null && msg.get !== undefined)
711
- {
712
- callback = r =>
713
- {
714
- return r.value;
715
- };
716
- }
602
+ if(callback === null && msg.get !== undefined) callback = r => r.value;
717
603
 
718
604
  // If no callback is needed, then we can stack up messages and send them together
719
605
  if(callback != null)
@@ -721,20 +607,10 @@ export class SwingUI
721
607
  // Send accumulated messages first
722
608
  this.sendMessageQueue();
723
609
 
724
- let msgs = JSON.stringify([msg]);
610
+ let msgs = '[' + JSON.stringify(msg) + ']';
725
611
  this.stats.out += msgs.length;
726
612
 
727
- let response;
728
-
729
- if(this.#useWorkerThread)
730
- {
731
- response = this.#sendMessagesViaWorker("b64:" + Buffer.from(msgs, "utf-8").toString("base64"), true);
732
- }
733
- else
734
- {
735
- response = this.#jvm.gui.receiveDirectMessagesSync("b64:" + Buffer.from(msgs, "utf-8").toString("base64"));
736
- if(response != null) response = this.#textDecoder.decode(this.#decodeBase64(response));
737
- }
613
+ let response = this.#sendMessagesViaWorker("b64:" + Buffer.from(msgs, "utf-8").toString("base64"), true);
738
614
 
739
615
  if(response != null && typeof response === "string") response = JSON.parse(response);
740
616
 
@@ -748,7 +624,7 @@ export class SwingUI
748
624
  }
749
625
  else
750
626
  {
751
- this.#_msg_queue.push(structuredClone(msg)); // clone original object to preserve values in case they change before we send the message to GUI
627
+ this.#_msg_queue.push(JSON.stringify(msg)); // stringify already to preserve values in case they change before we send the message to GUI
752
628
 
753
629
  if(this.#_msg_queue.length >= this.#queue_limit)
754
630
  {
@@ -782,7 +658,8 @@ export class SwingUI
782
658
  {
783
659
  if(this.#_msg_queue.length < 1) return this;
784
660
 
785
- let msgs = JSON.stringify(this.#_msg_queue);
661
+ //let msgs = JSON.stringify(this.#_msg_queue);
662
+ let msgs = '[' + this.#_msg_queue.join(",") + ']';
786
663
 
787
664
  // compress messages if more than one message and long enough
788
665
  if(compress && this.#_msg_queue.length > 1 && msgs.length > this.#msgCompressThreshold)
@@ -800,18 +677,7 @@ export class SwingUI
800
677
  this.stats.out += msgs.length;
801
678
  this.#_msg_queue = []; // clear queue
802
679
 
803
- if(this.#guiManagerWorker != null)
804
- {
805
- this.#sendMessagesViaWorker(msgs, false);
806
- }
807
- else if(this.#exiting) // when exiting, don't wait for response
808
- {
809
- this.#jvm.gui.receiveDirectMessages(msgs);
810
- }
811
- else
812
- {
813
- this.#jvm.gui.receiveDirectMessagesSync(msgs);
814
- }
680
+ this.#sendMessagesViaWorker(msgs, false);
815
681
 
816
682
  return this;
817
683
  }
@@ -832,6 +698,48 @@ export class SwingUI
832
698
  }
833
699
  }
834
700
 
701
+ /**
702
+ * Detect java-bridge compatibility with the current environment.
703
+ */
704
+ #JavaBridgeSupported()
705
+ {
706
+ const support = {
707
+ windows: {
708
+ node: true,
709
+ deno: true
710
+ },
711
+ linux: {
712
+ node: true,
713
+ deno: false // on Linux java-bridge 2.8.1 has error: "TypeError: java.linux-x64-gnu.node: undefined symbol: uv_run"
714
+ }
715
+ };
716
+
717
+ const os = this.os;
718
+
719
+ if(support[os] === undefined) return false;
720
+ if(support[os][this.runtime] !== true) return false;
721
+
722
+ const arch = this.runtime === "deno" ? Deno.build.arch : globalThis.process?.arch;
723
+
724
+ // Normalize architecture
725
+ const archMap = {
726
+ x86_64: "x64",
727
+ aarch64: "arm64",
728
+ ia32: "x86"
729
+ };
730
+
731
+ const normalizedArch = archMap[arch] || arch;
732
+
733
+ // Platform and architecture support
734
+ const supported = {
735
+ windows: ["x86", "x64"],
736
+ linux: ["x64", "arm64"],
737
+ //darwin: ["x64", "arm64"] // macOS doesn't support UI on not main thread
738
+ };
739
+
740
+ return supported[os]?.includes(normalizedArch) || false;
741
+ }
742
+
835
743
  //endregion
836
744
 
837
745
  //region read-only Getters
@@ -1530,19 +1438,6 @@ export class SwingUI
1530
1438
  {
1531
1439
  this.sendToGUI({java: "exit", code: exitCode});
1532
1440
 
1533
- try
1534
- {
1535
- //this.#jvm.eventListener.reset();
1536
- }catch(_)
1537
- {
1538
- }
1539
- try
1540
- {
1541
- this.#jvm.stdio.guard.release();
1542
- }catch(_)
1543
- {
1544
- }
1545
-
1546
1441
  setTimeout(() =>
1547
1442
  {
1548
1443
  if(this.#guiManagerWorker != null)
@@ -608,6 +608,25 @@ export class ComponentContainer extends UIComponent
608
608
 
609
609
  delete desc.trayIcons;
610
610
  }
611
+
612
+ if("toolBars" in desc)
613
+ {
614
+ Object.keys(desc.toolBars).forEach(location =>{
615
+ try
616
+ {
617
+ common.validateComponent(desc.toolBars[location]);
618
+ }catch(ex)
619
+ {
620
+ error(`Failed to load a ToolBar at location "${location}". ${ex.name}: ${ex.message}`, false);
621
+ return;
622
+ }
623
+
624
+ const bar = new ToolBar();
625
+ this[desc.toolBars[location].ref] = bar;
626
+ this._applyComponentPropertiesV1_0(bar, desc.toolBars[location], common);
627
+ this.toolBar(location, bar);
628
+ });
629
+ }
611
630
  }
612
631
  }
613
632
 
@@ -37,7 +37,7 @@ export class PasswordField extends TextComponent
37
37
  * const myChar = '\u25CF';
38
38
  * const myChar = '\u2B24';
39
39
  *
40
- * @param {string} [character] - A one character string character. If the string has more than one character, only first one will be used.
40
+ * @param {string} [character] - A one character string. If the string has more than one character, only first one will be used.
41
41
  * @returns {PasswordField|string} Returns an instance of `this` object when setting a value, otherwise current value is returned.
42
42
  */
43
43
  echoChar(...args)
package/classes/Window.js CHANGED
@@ -453,7 +453,7 @@ class Window extends ShapeContainer
453
453
  if(size.width < 0 || size.height < 0) return this;
454
454
 
455
455
  const offset = this.innerOffset;
456
- this.#prop.size = {width: size.width + offset.left + offset.right, height: size.height + offset.top + offset.bottom};
456
+ this.prop.size = {width: size.width + offset.left + offset.right, height: size.height + offset.top + offset.bottom};
457
457
 
458
458
  return this.property("innerSize", [size]);
459
459
  }
@@ -606,11 +606,11 @@ class Window extends ShapeContainer
606
606
  }
607
607
 
608
608
  /**
609
- * Sets a ToolBar to one of locations: `top`, `right`, `bottom` and `left`, or gets a ToolBar at a specified location.
609
+ * Sets a ToolBar to one of locations: `top`, `right`, `bottom` and `left`.
610
610
  *
611
611
  * @param {string} dockLocation - One of: `top`, `right`, `bottom` and `left`.
612
612
  * @param {ToolBar} [toolbar] - ToolBar to set to specified location. Set `null` to remove the toolbar from that location. Omit to get the toolbar already in that location.
613
- * @returns {ToolBar|null|Window} If only location is specified, a {@link ToolBar} or `null` is returned. When `toolbar` argument is passed, an instance of `this` Window is returned.
613
+ * @returns {null|any|Window}
614
614
  * @since 1.0.8
615
615
  */
616
616
  toolBar(dockLocation, toolbar = undefined)
package/icon.png CHANGED
Binary file
package/index.js CHANGED
@@ -1,12 +1,10 @@
1
1
  /**
2
- * Swing-UI GUI for JavaScript Runtime, such as Node.js, Bun, Deno 2.
2
+ * swing-ui GUI for JavaScript, such as Node.js, Bun, Deno 2.
3
3
  */
4
4
 
5
5
  import fs from "fs";
6
6
  import path from "path";
7
7
 
8
- import JBridge from "java-bridge";
9
-
10
8
  // show if debugger options were set
11
9
  if(process.execArgv.some(arg => arg.startsWith("--inspect"))) console.log("JavaScript Debugger option is set.");
12
10
 
@@ -17,11 +15,6 @@ const __dirname = import.meta.dirname ?? import.meta.dir ?? path.dirname((await
17
15
 
18
16
  // Dynamically assign each function to globalThis
19
17
  import * as functions from "./functions.js"; // Import all functions from functions.js
20
- if(typeof structuredClone !== "function") // add structuredClone() function in case it doesn't exist (node <17)
21
- {
22
- const v8 = await import("v8");
23
- functions.structuredClone = ((obj) => {return v8.deserialize(v8.serialize(obj));});
24
- }
25
18
  Object.entries(functions).forEach(([name, func]) => {Object.defineProperty(globalThis, name, {writable: false, configurable: false, value: func});});
26
19
 
27
20
  // Dynamically assign each enum to globalThis
@@ -93,7 +86,7 @@ for(const file of fs.readdirSync(classesDir))
93
86
 
94
87
  try
95
88
  {
96
- let ui = new (await import("./SwingUI.js")).SwingUI(__dirname, JBridge);
89
+ let ui = new (await import("./SwingUI.js")).SwingUI(__dirname);
97
90
  await ui.InitGUIProcess();
98
91
  Object.defineProperty(globalThis, "ui", {writable: false, configurable: false, value: ui});
99
92
  }catch(ex)
package/jar/gui-11.jar CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swing-ui",
3
- "version": "1.1.7",
3
+ "version": "1.2.1",
4
4
  "description": "Cross-platform Graphic User Interface for Node.js, Bun and Deno 2+",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -54,7 +54,5 @@
54
54
  "bun": ">= 1.1.0",
55
55
  "deno": ">= 2.6.0"
56
56
  },
57
- "dependencies": {
58
- "java-bridge": "^2.8.1"
59
- }
57
+ "dependencies": {}
60
58
  }
@@ -23,6 +23,15 @@ export class Ellipse extends Shape {
23
23
  width: number;
24
24
  height: number;
25
25
  };
26
+ /**
27
+ * Sets or gets the size of the `Ellipse` (horizontal and vertical diameter).
28
+ *
29
+ * @param {number|Size} width - Width of the ellipse (horizontal diameter), or a `Size` object (e.g., {width:300,height:300}).
30
+ * @param {number} [height] - Height of the ellipse (vertical diameter).
31
+ * @returns {Size|Ellipse} If called without parameters, current size is returned; otherwise this Ellipse object is returned.
32
+ * @see Size
33
+ */
34
+ size(...args: any[]): Size | Ellipse;
26
35
  /**
27
36
  * Returns a JSON object that contains this shape properties. It may be converted back to this shape.
28
37
  *
@@ -14,7 +14,7 @@ export class PasswordField extends TextComponent {
14
14
  * const myChar = '\u25CF';
15
15
  * const myChar = '\u2B24';
16
16
  *
17
- * @param {string} [character] - A one character string character. If the string has more than one character, only first one will be used.
17
+ * @param {string} [character] - A one character string. If the string has more than one character, only first one will be used.
18
18
  * @returns {PasswordField|string} Returns an instance of `this` object when setting a value, otherwise current value is returned.
19
19
  */
20
20
  echoChar(...args: any[]): PasswordField | string;
@@ -27,6 +27,15 @@ export class Rectangle extends Shape {
27
27
  width: number;
28
28
  height: number;
29
29
  };
30
+ /**
31
+ * Sets or gets the size of the `Rectangle`.
32
+ *
33
+ * @param {number|Size} width - Width of the Rectangle, or a `Size` object (e.g., {width:300,height:300}).
34
+ * @param {number} [height] - Height of the Rectangle.
35
+ * @returns {Size|Rectangle} If called without parameters, current size is returned; otherwise this Rectangle object is returned.
36
+ * @see Size
37
+ */
38
+ size(...args: any[]): Size | Rectangle;
30
39
  /**
31
40
  * Sets corner radius if only one argument passed, or arc width and height if two arguments or size object supplied. The arc size is applied to all corners.
32
41
  *
@@ -330,14 +330,14 @@ export class Window extends ShapeContainer {
330
330
  */
331
331
  opacity(...args: any[]): number | this;
332
332
  /**
333
- * Sets a ToolBar to one of locations: `top`, `right`, `bottom` and `left`, or gets a ToolBar at a specified location.
333
+ * Sets a ToolBar to one of locations: `top`, `right`, `bottom` and `left`.
334
334
  *
335
335
  * @param {string} dockLocation - One of: `top`, `right`, `bottom` and `left`.
336
336
  * @param {ToolBar} [toolbar] - ToolBar to set to specified location. Set `null` to remove the toolbar from that location. Omit to get the toolbar already in that location.
337
- * @returns {ToolBar|null|Window} If only location is specified, a {@link ToolBar} or `null` is returned. When `toolbar` argument is passed, an instance of `this` Window is returned.
337
+ * @returns {null|any|Window}
338
338
  * @since 1.0.8
339
339
  */
340
- toolBar(dockLocation: string, toolbar?: ToolBar): ToolBar | null | Window;
340
+ toolBar(dockLocation: string, toolbar?: ToolBar): null | any | Window;
341
341
  #private;
342
342
  }
343
343
  import { ShapeContainer } from "./ShapeContainer.js";
@@ -79,7 +79,7 @@ type DragEvent = {
79
79
  */
80
80
  target: object;
81
81
  /**
82
- * - One of `dragstart`, `dragend`, `cancel`.
82
+ * - One of `dragstart`, `dragend`, `drag`, `cancel`.
83
83
  */
84
84
  type: string;
85
85
  /**
@@ -158,9 +158,21 @@ type ChangeEvent = {
158
158
  */
159
159
  position?: number | undefined;
160
160
  /**
161
- * - The number of characters inserted or removed. Present when `action` is present.
161
+ * - The number of characters inserted or removed. Present when `action` is present. Applies to text editing components only.
162
162
  */
163
163
  length?: number | undefined;
164
+ /**
165
+ * - Value of a currently selected {@link RadioButton}, {@link RadioButtonMenuItem} or {@link ToggleButton} within a group.
166
+ */
167
+ value?: string | number | undefined;
168
+ /**
169
+ * - Index of a currently selected {@link RadioButton}, {@link RadioButtonMenuItem} or {@link ToggleButton} within a group.
170
+ */
171
+ index?: number | undefined;
172
+ /**
173
+ * - Indicates if the target {@link RadioButton}, {@link RadioButtonMenuItem} or {@link ToggleButton} component's new state is selected.
174
+ */
175
+ selected?: boolean | undefined;
164
176
  };
165
177
  /**
166
178
  * Ancestor event received by the {@link UIComponent#onAncestorEvents |onAncestorEvents()} handler callback.
@@ -933,7 +945,7 @@ type ShapeEvent = {
933
945
  */
934
946
  target: object;
935
947
  /**
936
- * - One of `add`, `remove`, `click`, `mousedown`, `mouseup`, `mouseenter`, `mouseleave`.
948
+ * - One of: `add`, `remove`, `click`, `mousedown`, `mouseup`, `mouseenter`, `mouseleave`, `mousemove`.
937
949
  */
938
950
  type: string;
939
951
  /**
@@ -994,11 +1006,11 @@ type ListItem = {
994
1006
  */
995
1007
  icon?: string | null | undefined;
996
1008
  /**
997
- * - Item text color as a 6-character hex string (e.g. `#665500`).
1009
+ * - Item text color as a hex string (e.g. `#665500`).
998
1010
  */
999
1011
  color?: string | undefined;
1000
1012
  /**
1001
- * - Item background color as a 6-character hex string (e.g. `#665500`).
1013
+ * - Item background color as a hex string (e.g. `#665500`).
1002
1014
  */
1003
1015
  background?: string | undefined;
1004
1016
  /**
@@ -1009,6 +1021,10 @@ type ListItem = {
1009
1021
  * - {@link Font} formatted object.
1010
1022
  */
1011
1023
  font?: Font | undefined;
1024
+ /**
1025
+ * - Specifies if the Tree node Item text can be edited by the user. (only in Tree components)
1026
+ */
1027
+ editable?: boolean | undefined;
1012
1028
  /**
1013
1029
  * - In some cases items are returned with `index` property to indicate their position within component.
1014
1030
  */
@@ -1072,9 +1088,9 @@ type Border = {
1072
1088
  */
1073
1089
  style: BorderStyle;
1074
1090
  /**
1075
- * - Border size in pixels. Must be >= 1.
1091
+ * - Border width in pixels. Must be >= 1.
1076
1092
  */
1077
- size?: number | undefined;
1093
+ width?: number | undefined;
1078
1094
  /**
1079
1095
  * - Inner padding as a space-separated string of four integer values: `"top right bottom left"`. Example: `"5 10 5 10"`. Can be set even when `style` is `"none"`.
1080
1096
  */
@@ -1179,7 +1195,7 @@ type TableColumn = {
1179
1195
  /**
1180
1196
  * - The character used to mask input for the `password` type.
1181
1197
  */
1182
- character?: string | undefined;
1198
+ echoChar?: string | undefined;
1183
1199
  /**
1184
1200
  * - Icon shown in the column header. Value can be a local file path, URI, or base64 encoded image string.
1185
1201
  */
@@ -1244,7 +1260,7 @@ type TableColumn = {
1244
1260
  /**
1245
1261
  * Table cell coordinates containing column and row property.
1246
1262
  */
1247
- type Cell = {
1263
+ type TableCell = {
1248
1264
  /**
1249
1265
  * - a column index of the cell
1250
1266
  */
@@ -54,7 +54,7 @@ else
54
54
  async function startJar()
55
55
  {
56
56
  let JAR_PATH = path.join(workerData.moduleDir, "jar/gui-11.jar");
57
- let JAVA_BIN = env.JAVA_HOME ? path.join(env.JAVA_HOME, workerData.os === "windows" ? "java.exe" : "java") : "java"; // build custom path from specified dir for each OS, or just use default command.
57
+ let JAVA_BIN = env.JAVA_HOME ? path.join(env.JAVA_HOME, "bin", workerData.os === "windows" ? "java.exe" : "java") : "java"; // build custom path from specified dir for each OS, or just use default command.
58
58
  let JAVA_OPTS = (env.JAVA_OPTS ?? "").split(" ").filter(Boolean);
59
59
  if(JAVA_OPTS.indexOf("-Dfile.encoding=UTF-8") === -1) JAVA_OPTS.push("-Dfile.encoding=UTF-8"); // important
60
60
  if(workerData.debugJava) JAVA_OPTS.push("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005"); // for debugging JAR