swing-ui 1.0.3 → 1.0.5

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
@@ -668,7 +668,7 @@ export class SwingUI
668
668
  callback.call(e.target, e);
669
669
  }catch(ex)
670
670
  {
671
- let comp_name = e.target.constructor.name;
671
+ let comp_name = e.target?.constructor?.name;
672
672
  e.target = `${comp_name}{...}`; // make it shorter by hiding internals of component
673
673
  if(e.source != null) e.source = `${e.source.constructor.name}{...}`; // make it shorter by hiding internals of component
674
674
  error(`${this._msg[6]}${comp_name}: ${e.event} \n\n${ex.stack}\n\nEvent ${stringify(e)}`, false);
@@ -1245,6 +1245,28 @@ export class SwingUI
1245
1245
  }
1246
1246
  }
1247
1247
 
1248
+ /**
1249
+ * Sets/get whether double-buffering should be used in rendering GUI in Java. Disabling may help to fix some graphical issues in Linux if flickering happens on component repaint.
1250
+ *
1251
+ * @param {boolean} enabled - `true` to enable double-buffering (default), `false` to disable.
1252
+ * @return {SwingUI|boolean} When setting a value, an instance of this `ui` object is returned, otherwise a current value is returned.
1253
+ */
1254
+ doubleBuffer(...args)
1255
+ {
1256
+ if(args.length > 0)
1257
+ {
1258
+ this.sendToGUI({java: "doubleBuffer", value: args[0] === true});
1259
+ return this;
1260
+ }
1261
+ else
1262
+ {
1263
+ return /** @type {boolean} */ this.sendToGUI({java: "doubleBuffer"}, r =>
1264
+ {
1265
+ return r.value;
1266
+ });
1267
+ }
1268
+ }
1269
+
1248
1270
  /**
1249
1271
  * Shows a message dialog window like alert() in web browser.
1250
1272
  *
package/classes/Arc.js CHANGED
@@ -96,7 +96,7 @@ export class Arc extends Shape
96
96
  }
97
97
  else
98
98
  {
99
- return {width: this._size.width, height: this._size.height};
99
+ return {width: this._hole_size.width, height: this._hole_size.height};
100
100
  }
101
101
  }
102
102
 
@@ -182,4 +182,4 @@ export class Arc extends Shape
182
182
 
183
183
  return obj;
184
184
  }
185
- }
185
+ }
@@ -111,8 +111,13 @@ export class ComponentContainer extends UIComponent
111
111
 
112
112
  if(this.#descriptorObject == null)
113
113
  {
114
- this.applyComponentProperties = null;
115
- this.applyUIDefinition = null;
114
+ this._applyUIDefinition = undefined;
115
+ this._applyComponentPropertiesV1_0 = undefined;
116
+ this._buildComponentResources = undefined;
117
+
118
+ delete this._applyUIDefinition;
119
+ delete this._applyComponentPropertiesV1_0;
120
+ delete this._buildComponentResources;
116
121
  }
117
122
  }
118
123
 
@@ -446,7 +451,7 @@ export class ComponentContainer extends UIComponent
446
451
  * @private
447
452
  * @ignore
448
453
  */
449
- applyUIDefinition(class_name)
454
+ _applyUIDefinition(class_name)
450
455
  {
451
456
  // Apply UI to this component
452
457
  if(this.#descriptorObject != null)
@@ -473,12 +478,12 @@ export class ComponentContainer extends UIComponent
473
478
  try
474
479
  {
475
480
  common.validateComponent(this.#descriptorObject.component);
481
+ this._buildComponentResources(this, this.#descriptorObject, common); // contextMenus, menuBar, trayIcons
482
+ this._applyComponentPropertiesV1_0(this, this.#descriptorObject.component, common);
476
483
  }catch(ex)
477
484
  {
478
485
  error(`${ex.name}: ${ex.message}`, false);
479
486
  }
480
-
481
- this.applyComponentPropertiesV1_0(this, this.#descriptorObject.component, common);
482
487
  }
483
488
  else
484
489
  {
@@ -502,15 +507,108 @@ export class ComponentContainer extends UIComponent
502
507
  }
503
508
 
504
509
  // delete these functions to make sure they can't be called again
505
- this.applyComponentProperties = null;
506
- this.applyComponentPropertiesV1_0 = null;
507
- this.applyUIDefinition = null;
510
+ this._buildComponentResources = undefined;
511
+ this._applyComponentPropertiesV1_0 = undefined;
512
+ this._applyUIDefinition = undefined;
513
+
514
+ delete this._buildComponentResources;
515
+ delete this._applyComponentPropertiesV1_0;
516
+ delete this._applyUIDefinition;
517
+ }
518
+
519
+ /**
520
+ * @private
521
+ */
522
+ _buildComponentResources(component, desc, common)
523
+ {
524
+ //region For backward compatibility
525
+ if("contextMenus" in desc.component)
526
+ {
527
+ desc.contextMenus = desc.component.contextMenus;
528
+ delete desc.component.contextMenus;
529
+ }
530
+
531
+ if("trayIcons" in desc.component)
532
+ {
533
+ desc.trayIcons = desc.component.trayIcons;
534
+ delete desc.component.trayIcons;
535
+ }
536
+ //endregion
537
+
538
+ // load context menus
539
+ if("contextMenus" in desc)
540
+ {
541
+ if(Array.isArray(desc.contextMenus))
542
+ {
543
+ desc.contextMenus.forEach(json_child =>
544
+ {
545
+ try
546
+ {
547
+ common.validateComponent(json_child);
548
+
549
+ this[json_child.ref] = new globalThis[json_child.type]();
550
+ this._applyComponentPropertiesV1_0(this[json_child.ref], json_child, common);
551
+ }catch(ex)
552
+ {
553
+ error(`Failed to load a context menu. ${ex.name}: ${ex.message}`, false);
554
+ }
555
+ });
556
+ }
557
+
558
+ delete desc.contextMenus;
559
+ }
560
+
561
+ if(desc.component.type === "Window")
562
+ {
563
+ // load main menu bar
564
+ if("menuBar" in desc.component)
565
+ {
566
+ try
567
+ {
568
+ common.validateComponent(desc.component.menuBar);
569
+
570
+ const bar = new globalThis[desc.component.menuBar.type]();
571
+ this._applyComponentPropertiesV1_0(bar, desc.component.menuBar, common);
572
+ component.menuBar(bar);
573
+ delete desc.component.menuBar;
574
+ }catch(ex)
575
+ {
576
+ error(`Failed to load a menu bar. ${ex.name}: ${ex.message}`, false);
577
+ }
578
+ }
579
+
580
+ // load tray icons
581
+ if("trayIcons" in desc)
582
+ {
583
+ if(Array.isArray(desc.trayIcons))
584
+ {
585
+ desc.trayIcons.forEach(json_child =>
586
+ {
587
+ try
588
+ {
589
+ common.validateComponent(json_child);
590
+ }catch(ex)
591
+ {
592
+ error(`Failed to load a tray icon. ${ex.name}: ${ex.message}`, false);
593
+ return;
594
+ }
595
+
596
+ const trayIcon = new globalThis[json_child.type]();
597
+ this.onDispose(e => {if(!trayIcon.destroyed) trayIcon.destroy();}); // destroy the tray icon when window gets disposed
598
+ this[json_child.ref] = trayIcon;
599
+ this._applyComponentPropertiesV1_0(trayIcon, json_child, common);
600
+ });
601
+ }
602
+
603
+ delete desc.trayIcons;
604
+ }
605
+ }
508
606
  }
509
607
 
510
608
  /**
511
609
  * @private
512
610
  */
513
- applyComponentPropertiesV1_0(component, properties, common)
611
+ _applyComponentPropertiesV1_0(component, properties, common)
514
612
  {
515
613
  const ref = properties.ref;
516
614
  delete properties.ref;
@@ -605,76 +703,6 @@ export class ComponentContainer extends UIComponent
605
703
  }
606
704
  }
607
705
 
608
- // load context menus
609
- if("contextMenus" in properties)
610
- {
611
- if(Array.isArray(properties.contextMenus))
612
- {
613
- properties.contextMenus.forEach(json_child =>
614
- {
615
- try
616
- {
617
- common.validateComponent(json_child);
618
- }catch(ex)
619
- {
620
- error(`Failed to load a context menu. ${ex.name}: ${ex.message}`, false);
621
- return;
622
- }
623
-
624
- this[json_child.ref] = new globalThis[json_child.type]();
625
- this.applyComponentPropertiesV1_0(this[json_child.ref], json_child, common);
626
- });
627
- }
628
-
629
- delete properties.contextMenus;
630
- }
631
-
632
- if(component instanceof Window)
633
- {
634
- // load main menu bar
635
- if("menuBar" in properties)
636
- {
637
- try
638
- {
639
- common.validateComponent(properties.menuBar);
640
- }catch(ex)
641
- {
642
- error(`Failed to load a menu bar. ${ex.name}: ${ex.message}`, false);
643
- }
644
-
645
- const bar = new globalThis[properties.menuBar.type]();
646
- this.applyComponentPropertiesV1_0(bar, properties.menuBar, common);
647
- component.menuBar(bar);
648
- delete properties.menuBar;
649
- }
650
-
651
- // load tray icons
652
- if("trayIcons" in properties)
653
- {
654
- if(Array.isArray(properties.trayIcons))
655
- {
656
- properties.trayIcons.forEach(json_child =>
657
- {
658
- try
659
- {
660
- common.validateComponent(json_child);
661
- }catch(ex)
662
- {
663
- error(`Failed to load a tray icon. ${ex.name}: ${ex.message}`, false);
664
- return;
665
- }
666
-
667
- const trayIcon = new globalThis[json_child.type]();
668
- component.onDispose(e => {if(!trayIcon.destroyed) trayIcon.destroy();}); // destroy the tray icon when window gets disposed
669
- this[json_child.ref] = trayIcon;
670
- this.applyComponentPropertiesV1_0(trayIcon, json_child, common);
671
- });
672
- }
673
-
674
- delete properties.trayIcons;
675
- }
676
- }
677
-
678
706
  // apply properties
679
707
  for(const prop of Object.keys(properties))
680
708
  {
@@ -748,7 +776,7 @@ export class ComponentContainer extends UIComponent
748
776
 
749
777
  const child_ref = json_child.ref;
750
778
  this[child_ref] = new globalThis[json_child.type]();
751
- this.applyComponentPropertiesV1_0(this[child_ref], json_child, common);
779
+ this._applyComponentPropertiesV1_0(this[child_ref], json_child, common);
752
780
  component.addChild(this[child_ref]);
753
781
  });
754
782
  }
package/classes/Panel.js CHANGED
@@ -32,7 +32,7 @@ class Panel extends ShapeContainer
32
32
  //this.finalize(Panel, ShapeContainer);
33
33
 
34
34
  // load UI definition file
35
- if(new.target !== Panel && this.applyUIDefinition != null) this.applyUIDefinition(new.target.name); // must be called AFTER super()
35
+ if(new.target !== Panel && this._applyUIDefinition != null) this._applyUIDefinition(new.target.name); // must be called AFTER super()
36
36
  }
37
37
 
38
38
  /**
@@ -267,7 +267,7 @@ class UIComponent
267
267
  * Gets a previous sibling component. If this component wasn't added to any container component, then `null` is returned.
268
268
  * @readonly
269
269
  * @type {UIComponent|null}
270
- * @since 1.0.2
270
+ * @since 1.0.3
271
271
  */
272
272
  get previousSibling()
273
273
  {
@@ -281,7 +281,7 @@ class UIComponent
281
281
  * Gets a next sibling component. If this component wasn't added to any container component, then `null` is returned.
282
282
  * @readonly
283
283
  * @type {UIComponent|null}
284
- * @since 1.0.2
284
+ * @since 1.0.3
285
285
  */
286
286
  get nextSibling()
287
287
  {
@@ -294,7 +294,7 @@ class UIComponent
294
294
  * Gets an array of sibling components.
295
295
  * @readonly
296
296
  * @type {UIComponent[]}
297
- * @since 1.0.2
297
+ * @since 1.0.3
298
298
  */
299
299
  get siblings()
300
300
  {
@@ -445,7 +445,7 @@ class UIComponent
445
445
 
446
446
  /**
447
447
  * Checks if this component is inside specified ancestor component (at any level, not just direct child).
448
- * @param {Object} ancestor - Ancestor component to test against
448
+ * @param {UIComponent} ancestor - Ancestor component to test against
449
449
  * @return {boolean}
450
450
  * @see ComponentContainer#contains
451
451
  */
package/classes/Window.js CHANGED
@@ -129,7 +129,7 @@ class Window extends ShapeContainer
129
129
  //this.finalize(ShapeContainer, Window);
130
130
 
131
131
  // load UI definition file
132
- if(new.target !== Window && this.applyUIDefinition != null) this.applyUIDefinition(new.target.name); // must be called AFTER super()
132
+ if(new.target !== Window && this._applyUIDefinition != null) this._applyUIDefinition(new.target.name); // must be called AFTER super()
133
133
  }
134
134
 
135
135
  /**
package/icon.png CHANGED
Binary file
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.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Cross-platform Graphic User Interface for Node.js, Bun and Deno 2+",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -14,7 +14,6 @@ export class ComponentContainer extends UIComponent {
14
14
  * @ignore
15
15
  */
16
16
  constructor(...args: any[]);
17
- applyComponentProperties: any;
18
17
  /**
19
18
  * Loads UI Components and properties from UI designer file FILE_NAME.ui.json where FILE_NAME is the name of JavaScript file of the component.
20
19
  *
@@ -22,7 +21,15 @@ export class ComponentContainer extends UIComponent {
22
21
  * @private
23
22
  * @ignore
24
23
  */
25
- private applyUIDefinition;
24
+ private _applyUIDefinition;
25
+ /**
26
+ * @private
27
+ */
28
+ private _applyComponentPropertiesV1_0;
29
+ /**
30
+ * @private
31
+ */
32
+ private _buildComponentResources;
26
33
  /**
27
34
  * Gets an array of child components.
28
35
  *
@@ -122,10 +129,6 @@ export class ComponentContainer extends UIComponent {
122
129
  * };
123
130
  */
124
131
  onContainerEvents(...args: any[]): this | Function[];
125
- /**
126
- * @private
127
- */
128
- private applyComponentPropertiesV1_0;
129
132
  #private;
130
133
  }
131
134
  import { UIComponent } from "./UIComponent.js";
@@ -98,21 +98,21 @@ export class UIComponent {
98
98
  * Gets a previous sibling component. If this component wasn't added to any container component, then `null` is returned.
99
99
  * @readonly
100
100
  * @type {UIComponent|null}
101
- * @since 1.0.2
101
+ * @since 1.0.3
102
102
  */
103
103
  readonly get previousSibling(): UIComponent | null;
104
104
  /**
105
105
  * Gets a next sibling component. If this component wasn't added to any container component, then `null` is returned.
106
106
  * @readonly
107
107
  * @type {UIComponent|null}
108
- * @since 1.0.2
108
+ * @since 1.0.3
109
109
  */
110
110
  readonly get nextSibling(): UIComponent | null;
111
111
  /**
112
112
  * Gets an array of sibling components.
113
113
  * @readonly
114
114
  * @type {UIComponent[]}
115
- * @since 1.0.2
115
+ * @since 1.0.3
116
116
  */
117
117
  readonly get siblings(): UIComponent[];
118
118
  /**
@@ -176,11 +176,11 @@ export class UIComponent {
176
176
  verifyComponent(): this;
177
177
  /**
178
178
  * Checks if this component is inside specified ancestor component (at any level, not just direct child).
179
- * @param {Object} ancestor - Ancestor component to test against
179
+ * @param {UIComponent} ancestor - Ancestor component to test against
180
180
  * @return {boolean}
181
181
  * @see ComponentContainer#contains
182
182
  */
183
- insideOf(ancestor: Object): boolean;
183
+ insideOf(ancestor: UIComponent): boolean;
184
184
  /**
185
185
  * Sets or gets component's visibility.
186
186
  * NOTE: Window and InternalWindow components visibility is set to `false` by default. Use .visible(true) or .show() to make it visible.
@@ -58,7 +58,7 @@ async function startJar()
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
61
- if(workerData.os === "linux") JAVA_OPTS.push("--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED"); // to be able to set WM_CLASS to project name in Java GUI
61
+ if(workerData.os === "linux") JAVA_OPTS.push("--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED"); // to be able to set WM_CLASS to project name in Java GUI
62
62
 
63
63
  const _opts = [...JAVA_OPTS, "-jar", JAR_PATH, "--root-dir", workerData.rootDir, "--module-dir", workerData.moduleDir];
64
64