2024年11月12日 星期二

how to set up NetBeans environment for JavaFX applications

JavaFX 為 Java 繼 Awt, Swing 之後推出的第3代圖形介面(GUI)套件。 利用 NetBeans 整合開發環境(IDE)撰寫 JavaFX應用時,常遇到開發環境如何建立的問題。很容易會遇到如下錯誤:

   Error occurred during initialization of boot layer
   java.lang.module.FindException: Module javafx.controls not found

以下整理幾點 NetBeans 整合 JavaFX SDK,SceneBuilder 場景建立器,詳查 Build 腳本的方法,供除錯參考。

✅ NetBeans 整合 JavaFX SDK 方法
     Project Properties
       Libraries/
           Java Platform: JDK xx (Default)
           Compile/Compile-time Libraries:
               Classpath: JavaFX yy
           Run/Run-time Libraries:
               Modulepath: JavaFX yy

       Run/
           Configuration: <default config>
           VM Options:
               --add-modules javafx.controls,javafx.fxml,javafx.media
         
✅ NetBeans 整合 SceneBuilder 方法
     Tools/Options/Java/JavaFX
        JavaFX Scene Builder Integration
          Scene Builder Home: C:\Users\zz\AppData\Local\SceneBuilder
    
✅ NetBeans除錯想看Build執行腳本內容
     Tools/Options/Java/Ant:
        Ant Home: ...
        [v] Always Show Output

     Verbosity Level: Quiet/Normal/[Verbose]/Debug

    即可觀看Ant Target (build.xml) Output

註: 建立 JavaFX 開發環境所須安裝套件如下
1.OpenJDK
  https://learn.microsoft.com/zh-tw/java/openjdk/download
    microsoft-jdk-21.0.5-windows-x64.msi (不含JavaFX)
  https://www.azul.com/downloads/?package=jdk-fx#zulu
    zulu21.38.21-ca-fx-jdk21.0.5-win_x64.msi (含JavaFX)

2.NetBeans
  https://netbeans.apache.org/download/index.html
    Apache-NetBeans-22-bin-windows-x64.exe

3.SceneBuilder
  https://gluonhq.com/products/scene-builder/
    SceneBuilder-23.0.1.msi

4.JavaFX SDK
  https://gluonhq.com/products/javafx/
    openjfx-17.0.13_windows-x64_bin-sdk.zip

2024年11月11日 星期一

controller class not found or fxml load error when running JavaFX applications

執行 JavaFX 圖形介面程式,使用視窗配置檔 .fxml 時,若出現 fxml載入錯誤控制器類別找不到 錯誤,很可能是因為 .fxml 配置檔的控制器指定值沒有寫對。可打開 .fxml 檔,檢查容器 (XXPane) 標籤的 fx:controller 控制器欄位值是否正確。若有使用套件包裝,其套件路徑是否正確。

如下 fxml 配置檔範例中,假設 DrawShapesController.java 控制器宣告歸屬套件 package com.abc;,則其值前面要加上 com.abc 套件路徑,在依據 fxml 配置檔載入控制器時,才找得到控制器類別。

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity" 
xmlns="http://javafx.com/javafx/8.0.60" 
xmlns:fx="http://javafx.com/fxml/1" 
fx:controller="com.abc.DrawShapesController">
...
</BorderPane>

註1: 常見 fxml載入錯誤 及 控制器類別找不到錯誤  例子。

Exception in Application start method
java.lang.reflect.InvocationTargetException
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  .....
  at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)

Caused by: java.lang.RuntimeException: Exception in Application start method
  at javafx.graphics@19/.....LauncherImpl.launchApplication1(LauncherImpl.java:901)
  at javafx.graphics@19/.....LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
  at java.base/java.lang.Thread.run(Thread.java:834)

Caused by: javafx.fxml.LoadException: ..../DrawShapes.fxml:8
  at javafx.fxml@19/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2707)
  ......
  at ......DrawShapes.start(DrawShapes.java:16)
  ......

Caused by: java.lang.ClassNotFoundException: DrawShapesController
  at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
  ......

Exception running application .....DrawShapes

註2: 有時也會看到如下 找不到類別定義錯誤 例子。

Caused by: java.lang.NoClassDefFoundError: DrawRandomLinesController (wrong name: DrawRandomLinesController)

2024年11月9日 星期六

how to write a JavaFX application without use of SceneBuilder?

一般 JavaFX 的視窗要利用 Gluon公司釋放的 SceneBuilder 工具,建立視窗配置檔 .fxml,再由程式載入套用。其實不利用視窗配置檔,也可建立視窗,只是配置元件位置較麻煩。以下參考Copilot輸出範例,展示簡單版,不載入配置檔,視窗建立法。


// JavaFX_noscenebuilder.java // 展示如何不用場景建立器,配置元件位置, // 直接用程式部署元件的 JavaFX 視窗程式寫法 // // 命令列編譯指令 // > javac -classpath "...\javafx-sdk-xx\lib\javafx-swt.jar;...;." \ // JavaFX_noscenebuilder.java // // 命令列執行指令 // > java --add-modules javafx.controls,javafx.fxml \ // -classpath . \ // --module-path "...\javafx-sdk-xx\lib\javafx-swt.jar;..." \ // JavaFX_noscenebuilder // // 引用 JavaFX 套件 import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.StackPane; import javafx.stage.Stage; // JavaFX 視窗類別須繼承自 javafx.application.Application public class JavaFX_noscenebuilder extends Application { @Override // 舞台啟動方法,接收舞台參數 primaryStage,建立場景 public void start(Stage primaryStage) { primaryStage.setTitle("Hello World!"); // 設定舞台標題 Button btn = new Button(); // 建立按鈕 btn.setText("Say 'Hello World'"); // 設立按鈕顯示字串 // 設定按鈕事件處理器,列印歡迎字串 btn.setOnAction(event -> System.out.println("Hello World!")); StackPane root = new StackPane(); // 建立堆疊面板,當場景根節點 root.getChildren().add(btn); // 將按鈕加入堆疊面板的小孩容器 // 在場景根節點root下,建立300x100場景 Scene scene = new Scene(root, 300, 100); primaryStage.setScene(scene); // 設定舞台場景 primaryStage.show(); // 顯示舞台 } // 測試主程式 public static void main(String[] args) { // 載入JavaFX執行期環境,建立應用程式物件,呼叫 start()啟動舞台及場景 Application.launch(args); } }
    註: 程式編譯及執行所須參考的套件如下
  1. JavaFX xx -javafx-swt.jar
  2. JavaFX xx -javafx.base.jar
  3. JavaFX xx -javafx.controls.jar
  4. JavaFX xx -javafx.fxml.jar
  5. JavaFX xx -javafx.graphics.jar
  6. JavaFX xx -javafx.media.jar
  7. JavaFX xx -javafx.swing.jar
  8. JavaFX xx -javafx.web.jar
  9. JDK yy

2024年10月6日 星期日

how to recover the windows desktop in an RDP session

使用遠端桌面 (RDP) 工具連線到遠方 Windows 電腦時,有時候不小心關閉或弄壞了檔案總管 ( explorer.exe) 行程,導致工作列消失,或桌面變成一片黑,無法操作。這種情況下,毋須驚慌,以下是一步步如何啟動 工作管理員 (Task Manager),恢復桌面的方法。

  1. 步驟一:打開命令列視窗 (CMD)
    1. 打開工作管理員:按下 Windows Key + X  或 Ctrl + Shift + Esc 或 Ctrl + Alt + End,然後選擇「工作管理員」。
    2. 啟動新工作:在工作管理員中,點擊「檔案」選單,然後選擇「執行新工作」。
    3. 輸入命令:在彈出的對話框中,輸入 cmd,然後按下「確定」或 Enter 鍵。

  2. 步驟二:登出並重新登入
    1. 輸入登出命令:在命令提示字元後,輸入以下指令並按下 Enter:
      shutdown /l
      這個關機指令加上 (l)ogout 登出參數,會立即登出當前使用者。
    2. 重新登入:登出後,重新登入你的帳號。此時,桌面應該會恢復正常。

這個方法利用了 Windows 的內建功能來解決因誤操作導致的桌面消失問題。通過工作管理員啟動命令提示字元,然後使用登出命令,再重新登入,可以快速恢復桌面環境。這是一個簡單而有效的解決方案,適用於遠端桌面連線遇到類似無法操作的情況。

2024年10月5日 星期六

is an object with a string field mutable or immutable

In Java, strings are immutable objects. You might wonder if an object contains a String field which can be changed to other strings, is it an immutable or mutable object?

In fact, an object is considered immutable if its state cannot be changed after it is created. This means that all fields of the object must be final and cannot be modified after the object is constructed. Even though String objects themselves are immutable, if an object contains a field of type String that can be changed to reference a different String object, then the containing object is considered mutable. This is because the state of the object (i.e., the value of the String field) can change.

Here’s an example to illustrate this:

public class MutableObject {
    private String mutableField;  // fields without final can be changed

    public MutableObject(String initialField) {
        this.mutableField = initialField;
    }

    public void setMutableField(String newField) {
        this.mutableField = newField;
    }

    public String getMutableField() {
        return mutableField;
    }
}

In this example, MutableObject is mutable because the mutableField can be changed using the setMutableField method.

On the other hand, an immutable object would look like this:

public final class ImmutableObject {
    private final String immutableField; // final fields cannot be changed

    public ImmutableObject(String initialField) {
        this.immutableField = initialField;
    }

    public String getImmutableField() {
        return immutableField;
    }
}

In this case, ImmutableObject is immutable because the immutableField is final and cannot be changed after the object is created.

So, if your object allows its String field to be changed, it is considered mutable.

2024年8月12日 星期一

how many instances and containers will be launched in AWS ECS service

AWS 彈性容器服務 (ECS) 分成 ECS on Fargate 及 ECS on EC2 兩種。其中,ECS on Fargate 由 Fargate 服務全權負責容器如何配置到個體,屬無伺服器 (serverless)或 託管 (managed)的運算類服務。ECS on EC2 則由用戶自行負責容器如何配置到個體,其服務參數的任務配置(task placement)選項包含: az balanced spread,az balanced binpack,binpack,one task per host,random,custom等。預設 az balanced spread 為先平衡分散到不同的可用區,再平衡分散到可用區內個體。binpack乃依記憶體儘量配置容器到最少數量的個體上,即挑選足夠放置之下,剩餘記憶體最小之個體先放容器。

至於 ECS 到底會啟動幾個虛擬機個體 (instance)及容器 (container)來提供服務,可由如下因素決定: 
  1. 個體數: 由 ECS 叢集參數的個體希望容量(desired capacity) 上下限決定。其實際數量可由叢集的自動伸縮群組(ASG, Auto Scaling Group)參數,依個體負載指標值(metric)變化,在希望容量的上下限之間,採用目標追蹤(target tracking)類型原則,作伸縮調整。
     
  2. 容器數: 由 ECS 部署建立服務的所須任務數 (desired tasks)參數,及建立任務定義時使用的容器數量有多少兩者決定。ECS服務的實際任務數可由服務自動伸縮 (Service Auto Scaling) 參數,依服務負載指標值變化,看是採用目標追蹤(target tracking)類型或步進伸縮(step scaling)類型的原則,作伸縮調整。
Reference:
1. ECS叢集個體自動擴展: Automatically manage Amazon ECS capacity with cluster auto scaling - Amazon Elastic Container Service

2024年4月21日 星期日

what's the mechanism behind hash tables

雜湊表格 (HashTable),雜湊集合 (HashSet),或 雜湊映射 (HashMap),以下統稱雜湊表格,是效能最佳的一種資料結構,其增刪查找的時間複雜度皆為 O(1),和容器存放的元素個數 n 無關。Python語言的集合 (Set) 及字典 (Dictionary) 就是分別基於 雜湊集合 及 雜湊映射 而實現的,所以存取效能很好。

話雖如此,雜湊表格苦於兩個缺點,一是不能發生踫撞,只要踫撞嚴重,存取效能就會降低,退化成 O(n)。二是不能排序,不能查詢比某元素大/小的元素集合(tailSet/headSet)。若容器須要排序,只能退而求其次,改用樹狀結構 (TreeSet/TreeMap),例如搜索樹等,其增刪查找效能降到 O(log(n));或堆積 (Heap),其增刪效能 O(log(n)),但查找最小或最大值效能 O(1)。

以下參考文獻,列出雜湊表格常採用的技術分類,供了解其極佳效能的作法及補救法。

A. Hash code and compression: (雜湊碼及壓縮技術)

  A1. Hash code function 雜湊碼函數
         如何依據元素內容計算雜湊值

  1.  Bit representation (位元表現法)
  2.  Polynomial hash codes (多項式雜湊碼)
  3.  Cyclic-shift hash codes (循環平移雜湊碼)

  A2. Compression function 壓縮函數
        如何將雜湊碼 (hash_code) 依表格大小 (hash_table_size) 轉為找尋起點格下標

  1.  Division method (求餘數法)
         hash_code mod hash_table_size
  2.  MAD (multiply-add-and-divide) method (乘加求餘數法)
         [(a * hash_code + b) mod p] mod hash_table_size

B. Hash collision handling 雜湊踫撞處理法

  B1. Closed addressing / Open hashing or Separate chaining
         封閉式定址         /  開放式雜湊法,個別串接

         放元素的格子全由元素的雜湊碼決定 / 放元素的格子在雜湊表之外

  B2. Open addressing / Closed hashing
         開放式定址       / 封閉式雜湊法

        放元素的格子不全由元素的雜湊碼決定,視當時踫撞情形而定 / 放元素的格子在雜湊表

  1. Linear probing 線性探索
  2. Quadratic probing 平方探索
  3. Double hashing 雙雜湊

Reference:

  1. Open Addressing Collision Handling technique in Hashing - GeeksforGeeks
  2. 2015-goodrich-wiley-data structures & algorithms in java, 6th ed.