how to set up the NetBeans environment for running Java EE 7 compilant JavaServer Faces with @ManagedBean annotation

若拿到使用 JavaServer Faces (JSF) 開發的套件,內含 @ManagedBean 註記,可依據附註的部落格,查出其合適的開發工具版本為 JSF 2.0 + GlassFish 3.x + JDK 6 + NetBeans 6.x 或 JSF 2.2 + GlassFish 4.x + JDK 7 + NetBeans 7.x。

若找不到JDK 6、JDK 7,支援 LTS (長期服務) 版本的 JDK 8 較好找,應該也可以。至於 NetBeans 版本似乎較不嚴苛,使用較新的 NetBeans 22 也是可以的,只是伺服器要安裝支援 Java EE 6 或 7 的 GlassFish 及 JDK 版本。其安裝步驟如下

1. 假設 NetBeans 要安裝 GlassFish 4.1.2 (內含符合Java EE 7 Web標準的JSF2.2) + JDK 8
      所須 JDK 8 如下:
        OpenJDK Zulu 8.0.442+6
        zulu8.84.0.15-ca-jdk8.0.442-win_x64.zip
        C:\Users\xx\Documents\NetBeansJDKs\zulu8.84.0.15-ca-jdk8.0.442-win_x64\

2. 開舊專案後,改伺服器選用 Java EE 7 Web 相容的 GlassFish 4.1.12
      Resolve Missing Server Problem
        Available Java EE 7 Web compatible servers:
          GlassFish Server 4
     【OK】

3. 啟動 GlassFish Server 4
      Window/Services/Servers: GlassFish Server 4
        GlassFish server couldn ot be started with JDK XX (Default).
        Please select another Java SE Platform.
        Java Platform: Zulu 8.0.442+6
     【OK】

     Windoww安全性警訊
       Windows Defender 允許 OpenJDK xxx 在這些網路上通訊:
       V 網域網路,例如工作場所網路
    【允許存取】

4. 安裝 GlassFish 4.1.2 步驟
    Tools/Servers:
       Add Server...
         Choose Server
           Server: GlassFish Server
           Name: GlassFish Server 4
       Next>
         Server Location
           Installation Location: C:\Users\xx\GlassFish_server4
           X Local Domain
           Choose server to download:
             GlassFish Server 4.1.2
             V I have read and accept the licence agreement...(click)
             Download Now... (104.2m)
       Next>
         Domain Location
           Domain: domain1
           Host: localhost, Vloopback
           DAS Port: 4848, HTTP Port: 8080, VDefault
           Target:
           User Name:
           Password:
      【Finish】
    

        Server Name: GlassFish Server 4
        Server Type: GlassFish Server 4.1.2
        Common:
          Installation Location: C:\Users\xx\GlassFish_server4\glassfish
          Domains Folder: C:\Users\xx\GlassFish_server4\glassfish\domains
          Host: localhost
          DAS Port: 484, HTTP Port:8080
          Domain: domain1
            Enable HTTP Monitor (維持不打勾)
          V Enable JDBC Driver Deployment
          V Preserve Sessions Across Redeployment
          V Start Registered Derby Server
      【Close】

5. 安裝  JDK 8 方法
    Tools/Java Platforms
      Add Platform...
        Select platform type
          Download OpenJDK (via Foojay.io Disco API)
        Connect to OpenJDK Discovery Service
          Quick:
            Version: 23,21,17,11,8
            Distribution: Microsoft or Zulu

附註: 有關於 Java 平台企業版各種開發工具的歷史相容關係,可參考如下說明:
    Blog: Version history of Java EE,  JSF, GlassFish, JDK, and NetBeans

Version history of Java EE, JSF, GlassFish, JDK, and NetBeans

下表為 Java 平台企業版 (EE, Enterprise Edition) 各種開發工具的版本歷史。資料來自網路,可看出從昇陽公司的 J2EE、甲骨文公司的 Java EE,到 Eclipse基金會的 Jakarta EE,EE 標準的主導權不斷異動。 如果有機會拿到依據各代 Java 平台 EE 標準開發的舊程式碼,建議查找下表找出最合適的相關開發工具,以免無法進行測試。

例如,若拿到使用 JavaServer Faces (JSF) 開發的套件,內含 @ManagedBean 註記,可先查出其適用版本為 Java EE 6 或 Java EE 7。接著,參考下表得知,其合適的開發工具版本為 JSF 2.0 + GlassFish 3.x + JDK 6 + NetBeans 6.x 或 JSF 2.2 + GlassFish 4.x + JDK 7 + NetBeans 7.x。

其中,Java 開發套件 (Java Development Kit),簡稱 JDK,也歷經多代更迭。若找不到 JDK 6、JDK 7,支援 LTS (長期服務) 版本的 JDK 8 較好找,應該也可以。至於 NetBeans 版本的要求較不嚴苛,使用較新的 NetBeans 22 也是可以的,只是伺服器要安裝支援 Java EE 6 或 7 的 GlassFish 及 JDK 版本。

Year EE Standard JSF/Jakarta GlassFish JDK NetBeans
1999J2EE 1.2
2000J2SE 1.3
2001J2EE 1.3
2002J2SE 1.4
2003J2EE 1.4
2004JSF 1.0,1.1J2SE 5 (1.5)NetBeans 4.0
2005
2006Java EE 5JSF 1.2J2SE 6 (1.6)NetBeans 5.0
2007NetBeans 6.0
2008
2009Java EE 6JSF 2.0GlassFish 3.0
2010
2011J2SE 7 (1.7)NetBeans 7.0
2012
2013Java EE 7JSF 2.2GlassFish 4.0
2014J2SE 8 (1.8), LTSNetBeans 8.0
2015
2016
2017Java EE 8JSF 2.3J2SE 9 (1.9)
2018J2SE 10 (1.10), J2SE 11 (LTS)NetBeans 9.0, 10.0
2019Jakarta 2.3GlassFish 5.0J2SE 12, 13NetBeans 11.0
2020Jakarta EE 9Jakarta 3.0GlassFish 6.0J2SE 14, 15NetBeans 12.0
2021Jakarta EE 9.1J2SE 16, J2SE 17 (LTS)
2022Jakarta EE 10Jakarta 4.0GlassFish 7.0J2SE 18, 19NetBeans 13, 14, 15, 16
2023J2SE 20, J2SE 21 (LTS)NetBeans 17, 18, 19, 20
2024Jakarta EE 11J2SE 22, 23NetBeans 21, 22, 23, 24
2025J2SE 24, J2SE 25 (LTS)NetBeans 25, 26, 27, 28

以下表格摘要,由 NetBeans 測試,列出可和各版本 GlassFish 相容的長期支援 JDK (LTS) 版本,供安裝參考。

Year EE Standard JSF/Jakarta GlassFish Compatible JDK (LTS) Note
2009Java EE 6JSF 2.0GlassFish 3.0JDK 8
2013Java EE 7JSF 2.2GlassFish 4.0JDK 8支援 @ManagedBean 標註的最高版本組合
2019Java EE 8Jakarta 2.3GlassFish 5.0JDK 8@ManagedBean 廢止,改用環境及相依注入(CDI) 的 @Named 標註
2020Jakarta EE 9Jakarta 3.0GlassFish 6.0JDK 11, 17
2022Jakarta EE 10Jakarta 4.0GlassFish 7.0JDK 11, 17, 21

註1: Java EE 6,7 支援的 @ManagedBean 寫法,可參考如下要點,改成 Jakarta EE 支援的 @Named 註記。


  // 原來 Java EE 6,7 寫法
  import javax.faces.bean.ManagedBean;

  @ManagedBean(name="webBean")
  public class MyWebBean
  
  // 改成 Jakarta EE 寫法

  import jakarta.inject.Named;
  import jakarta.enterprise.context.SessionScoped;
  import java.io.Serializable;

  @Named("webBean")
  @SessionScoped
  public class MyWebBean implements Serializable

註2: 網路參考來源: 以 Wikipedia 維基百科網站為主

  1. Jakarta EE
  2. JavaServer Faces
  3. GlassFish
  4. Java版本歷史
  5. NetBeans
  6. NetBeans Release Schedule

Diagnosing the Error: Module javafx.fxml not found

在 NetBeans 使用 JavaFX 時,常遇到如下錯誤

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

表示啟動層初始化時 Java 執行環境無法找到 javafx.fxml 模組。
這可能是由於 NetBeans 模組路徑的設定錯誤 或 根本未安裝模組所致。
以下為診斷和解決這個問題的步驟。

1.檢查 JavaFX SDK 安裝 及 NetBeans 設定正確否
   依據如下提示逐項檢查:
     how to set up NetBeans environment for JavaFX applications

2.打開 NetBeans 列印 Ant 腳本功能
   依據如下設定選項 
     Tools/Options/Java/Ant 或者 NetBeans/Settings...
        Ant Home: ...
        [v] Always Show Output

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

    即可在執行 Run File 時,於 Output 視窗
    觀看Ant Target (build.xml) Output

3.檢查 NetBeans 執行 Ant run 腳本的參數填對否
   核對如下重要 java 執行參數
   run:
    Executing '/path/to/bin/java' with arguments:
    '-Dfile.encoding=UTF-8'
    
    '--add-modules'
    'javafx.controls,javafx.fxml,javafx.media'
    
    '-classpath'
    '/path/to/javafx-sdk-xx/lib/javafx-swt.jar:
     /path/to/javafx-sdk-xx/lib/javafx.base.jar:
     /path/to/javafx-sdk-xx/lib/javafx.controls.jar:
     /path/to/javafx-sdk-xx/lib/javafx.fxml.jar:
     /path/to/javafx-sdk-xx/lib/javafx.graphics.jar:
     /path/to/javafx-sdk-xx/lib/javafx.media.jar:
     /path/to/javafx-sdk-xx/lib/javafx.swing.jar:
     /path/to/javafx-sdk-xx/lib/javafx.web.jar:
     /path/to/MyProject/build/classes'
     
    '--module-path'
    '/path/to/MyProject/build/classes:
     /path/to/javafx-sdk-xx/lib/javafx-swt.jar:
     /path/to/javafx-sdk-xx/lib/javafx.base.jar:
     /path/to/javafx-sdk-xx/lib/javafx.controls.jar:
     /path/to/javafx-sdk-xx/lib/javafx.fxml.jar:
     /path/to/javafx-sdk-xx/lib/javafx.graphics.jar:
     /path/to/javafx-sdk-xx/lib/javafx.media.jar:
     /path/to/javafx-sdk-xx/lib/javafx.swing.jar:
     /path/to/javafx-sdk-xx/lib/javafx.web.jar'
     
    'MyJavaFXApp'

4.任何一處 Ant run 腳本的參數有缺,可對應到如下 NetBeans 設定有誤:
     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
               
註1: 其實 Ant build 及 run 腳本的工作原理就是由 NetBeans 設定抽取相關參數,
    組合成如下命令列編譯及執行指令。故執行有問題可找回相關設定哪裏出問題。

    命令列編譯指令
    > javac -classpath "...\javafx-sdk-xx\lib\javafx.fxml.jar;...;." \
      MyJavaFXApp.java

    命令列執行指令
    > java --add-modules javafx.controls,javafx.fxml,javafx.media \
      -classpath . \
      --module-path "...\javafx-sdk-xx\lib\javafx.fxml.jar;..." \
      MyJavaFXApp

註2: NetBeans 執行 Ant run 腳本時,依序參考如下檔案
       MyProject/
         build.xml
         nbproject/
           build-impl.xml
           project.properties
     其中,project.properties有專案屬性如下,存放設定執行參數,亦可對照檢視設定錯誤原因。
       run.classpath=\
         ${javac.classpath}:\
         ${build.classes.dir}
       run.jvmargs=--add-modules javafx.controls,javafx.fxml,javafx.media
       run.modulepath=\
         ${javac.modulepath}:\
         ${libs.JavaFX_xx.classpath}

Two ways to draw shapes in JavaFX

 JavaFX 有 2 種畫形狀的寫法如下:

A. Pane容器放 Shape 形狀

import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;

....

        Pane pane = new Pane();

        Circle circle = new Circle(50, 50, 30);
        circle.setFill(Color.BLUE);

        Rectangle rectangle = new Rectangle(100, 100, 80, 40);
        rectangle.setFill(Color.RED);

        pane.getChildren().addAll(circle, rectangle);

註1: Pane小孩清單會記住所有加入形狀元件,Pane大小調整後也會重新顯示所有形狀
註2: javafx.scene.shape支援形狀有
         Circle, Rectangle, Ellipse, Line, Polygon, Polyline, 
         Arc, CubicCurve, QuadCurve, Path 等

B. Canvas元件上畫出形狀

import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;

.....

        Canvas canvas = new Canvas(300, 200);
        GraphicsContext gc = canvas.getGraphicsContext2D();

        gc.setFill(Color.BLUE);
        gc.fillOval(50, 50, 60, 60); // Draw a circle

        gc.setFill(Color.RED);
        gc.fillRect(150, 100, 80, 40); // Draw a rectangle

        
註1: javafx.scene.canvas.GraphicsContext會暫時記住所有畫圖區內容,直到大小異動才清空
註2: javafx.scene.canvas.GraphicsContext支援形狀有

// 矩形
 fillRect(double x, double y, double w, double h) // 前景色填滿
 strokeRect(double x, double y, double w, double h) // 前景色畫框
 clearRect(double x, double y, double w, double h)  // 背景色填滿

// 圓形
 fillOval(double x, double y, double w, double h)
 strokeOval(double x, double y, double w, double h)

// 弧形
 fillArc(double x, double y, double w, double h, 
         double startAngle, double arcExtent, ArcType closure)
 strokeArc(double x, double y, double w, double h, 
           double startAngle, double arcExtent, ArcType closure)

// 多邊形,多邊線
 fillPolygon(double[] xPoints, double[] yPoints, int nPoints)
 strokePolygon(double[] xPoints, double[] yPoints, int nPoints)
 fillPolyline(double[] xPoints, double[] yPoints, int nPoints)
 strokePolyline(double[] xPoints, double[] yPoints, int nPoints)
 strokeLine(double x1, double y1, double x2, double y2)

// 路徑模式, 一次只能維護一條路徑
 beginPath()
 moveTo(double x, double y)
 lineTo(double x, double y)
 closePath()
 stroke()  // 畫路徑框
 fill() // 畫路徑內部

how to write change event handlers for JavaFX components

在 javafx.scene.control 套件路徑下,如下元件有更動屬性都會產生異動事件(Change Event),

    TextField/CheckBox/ComboBox/RadioButton/ChoiceBox/Slider/ListView

可對元件屬性註冊異動事件處理器(Change Event Handler),接收異動事件,進行處理。

註冊異動事件處理器寫法,和註冊動作事件處理器寫法不同,
須利用.xxxProperty()方法先取得元件屬性,
再利用.addListener 方法為屬性添加異動監聽器,寫法如下:

textField.textProperty().addListener((observable, oldValue, newValue) -> {
  System.out.println("value changed from " + oldValue + " to " + newValue);
});

textField.textProperty().addListener(new ChangeListener<String>() {
  @Override
  public void changed(ObservableValue observable, 
                      String oldValue, String newValue) {
    System.out.println("value changed from " + oldValue + " to " + newValue);
  }
});


註1: 至於其他元件的異動事件處理器註冊,須搭配各元件的屬性取法不同,寫法如下:
    checkBox.selectedProperty().addListener(...)
    comboBox.valueProperty().addListener(...)
    radioButton.selectedProperty().addListener(...)
    choiceBox.getSelectionModel().selectedItemProperty().addListener(...)
    slider.valueProperty().addListener(...)
    listView.getSelectionModel().selectedItemProperty().addListener(...)

註2: JavaFX 有 javafx.event.ActionEvent 動作事件類別及物件,但沒有異動事件類別。
     元件一旦有動作事件,通常屬於高階離散事件,立即一次性處理完即可,
     故設計上註冊處理器寫法較簡單,只允許對元件呼叫如下方法,掛上單一動作監聽器。
         setOnAction(event -> {...}); 

註3: 元件屬性一旦有異動事件,通常屬於低階連續事件,須要密集多次處理狀態變化,
     故設計上註冊處理器寫法較細緻彈性,可對屬性呼叫如下方法,掛上多個異動監聽器。
        addListener(
           new javafx.beans.value.ChangeListener(
              (ob, oldV, newV) -> {...}
           )
        );

Two ways to write action event handlers in JavaFX

在 javafx.scene.control 套件路徑下,如下元件受點選都會產生動作事件(ActionEvent),

    Button/TextField/CheckBox/ComboBox/RadioButton/MenuItem/Hyperlink

可對元件註冊動作事件處理器(ActionEvent Handler),接收動作事件,進行處理。

註冊動作事件處理器有兩種寫法:

1.利用元件的.setOnAction方法註冊,寫法如下

button.setOnAction(event -> System.out.println("Button clicked!"));button.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
        System.out.println("Button clicked!");
    }
});


2. 利用.fxml檔的元件屬性註冊,寫法如下

<Button text="Click Me" onAction="#handleButtonAction"/>

public class Controller {

    @FXML
    private void handleButtonAction(ActionEvent event) {
        System.out.println("Button clicked!");
    }
}

註: 方法前的 @ 標註旨在通知編譯器作防呆檢查,減少可能錯誤
1. @Override 標註將提醒編譯器檢查該方法簽名是否有覆蓋上一代方法
2. @FXML 標註將提醒編譯器檢查該方法或屬性是否出現於 .fxml 介面配置檔中

How to interpret the caused by sections of a Java stack trace?

Java執行出錯丟出例外時,常會列印一串 Caused by 訊息,其格式為
   java.lang.Exception: Exception in xxx
       at ......... (....java: ..)
       .......
       at ......... (....java: ..)
   Caused by: java.lang.Exception: Exception in yyy
       at ......... (....java: ..)
       .......
       at ......... (....java: ..)
   Caused by: java.lang.Exception: Exception in zzz
       at ......... (....java: ..)
       .......
       at ......... (....java: ..)

這表示先有 zzz 錯誤,然後造成 yyy 錯誤,然後造成 xxx 錯誤。因此,最初錯誤原因為最後Caused by 指出的 zzz 錯誤。至於每個錯誤後面都會跟著很多 at,印出丟出例外當時的方法堆疊內容,越後面的 at 程式碼越早執行。


 public class CausedByExample {
    public static void main(String[] args) {
        try {
            method1();  // line 4
        } catch (Exception e) {
            // 此行指令表明 執行方法main出現例外 將列印丟出例外時的堆疊記錄內容
            e.printStackTrace();
        }
    }

    public static void method1() throws Exception {
        try {
            method2();  // line 13
        } catch (Exception e) {
            // 此行指令表明 執行方法1出現例外 是由 執行方法2的例外e造成,將列印
            // java.lang.Exception: Exception in method1
            //  逐層列印丟出方法1例外時的堆疊記錄內容
            throw new Exception("Exception in method1", e);  // line 18
            //  public Exception(String message, Throwable cause) 
            //  產生新例外,包含例外說明字串 message,及造成本例外的原因 cause
        }
    }

    public static void method2() throws Exception {
        // 此行指令表明 執行方法2出現例外,將列印
        // java.lang.Exception: Exception in method2
        //  逐層列印丟出方法2例外時的堆疊記錄內容
        throw new Exception("Exception in method2");  // line 26
    }
}

Output:

上面程式在method2產生例外,由method1接收,再包裝成原因產生新例外,由main接收,列印e.printStackTrace。其列印內容說明,Exception in method2 造成 Exception in method1

java.lang.Exception: Exception in method1
	at CausedByExample.method1(CausedByExample.java:18)
	at CausedByExample.main(CausedByExample.java:4)
Caused by: java.lang.Exception: Exception in method2
	at CausedByExample.method2(CausedByExample.java:26)
	at CausedByExample.method1(CausedByExample.java:13)
	... 1 more

how to set up NetBeans environment for JavaFX applications

JavaFX 為 Java 繼 Awt, Swing 之後推出的第 3 代圖形介面 (GUI) 套件,多了場景建立器 (Scene Builder),排版配置檔 CSS 等支援能力。 利用 NetBeans 整合開發環境 (IDE) 撰寫 JavaFX 應用時,常遇到開發環境如何建立的問題。很容易會遇到如下錯誤:

   Error occurred during initialization of boot layer
   java.lang.module.FindException: Module javafx.controls not found
或
   java.lang.module.FindException: Module javafx.fxml 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

註1: 建立 JavaFX 開發環境所須安裝套件如下
1.OpenJDK
  https://learn.microsoft.com/zh-tw/java/openjdk/download
    microsoft-jdk-21.0.5-windows-x64.msi (不含JavaFX)
    microsoft-jdk-21.0.5-macos-aarch64.pkg
  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
    Apache-NetBeans-22.pkg

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

4.JavaFX SDK
  https://gluonhq.com/products/javafx/
    openjfx-17.0.13_windows-x64_bin-sdk.zip
    openjfx-17.0.13_osx-aarch64_bin-sdk.zip
    
註2: JavaFX 和 JDK 的版本相容性,可參考如下說明:
      Version history of Java EE, JPA, Java DB, JavaFX, and JDK

	
YearJavaFX (LTS)Compatible JDK (LTS)Note
2018JavaFX 11 (LTS)J2SE 11, 17, 21JDK 8 不支援 JavaFX 11 模組功能
2021JavaFX 17 (LTS)J2SE 11, 17, 21
2023JavaFX 21 (LTS)J2SE 17, 21JDK 11 不支援 JavaFX 21 模組版本
註3: NetBeans 要看到 Scene Builder Home,須要安裝且啟動(Activate)如下任一插件 Tools/Plugins: JavaFX 2 或 JavaFX Implementation for Windows 安裝之後,針對專案 .fxml 按右鍵,才會看到如下選項 Open 連動開啟場景建立器畫面 Edit 開啟.fxml文字畫面 Make Controller 產生 .fxml 中 fx:controller 屬性指定的控制器.java類別檔 註4: NetBeans 要能看到 JavaFX yy 類別庫,須設定 Tools/Libraries/Libraries: Library Name: JavaFX yy Classpath/Add JAR/Folder...: ...\javafx-sdk-yy\lib\javafx-swt.jar ...\javafx-sdk-yy\lib\javafx.base.jar ...\javafx-sdk-yy\lib\javafx.controls.jar ...\javafx-sdk-yy\lib\javafx.fxml.jar ...\javafx-sdk-yy\lib\javafx.graphics.jar ...\javafx-sdk-yy\lib\javafx.media.jar ...\javafx-sdk-yy\lib\javafx.swing.jar ...\javafx-sdk-yy\lib\javafx.web.jar 註5: NetBeans 要能點選原始碼類別,按右鍵點選 Show Javadoc (Alt-F1) 看到類別 註解說明,須設定 Tools/Libraries/Libraries: Library Name: JavaFX yy Javadoc/Add URL...: https://docs.oracle.com/javafx/2/api/ 註6: NetBeans 要能點選原始碼類別,按右鍵點選 Navigate> Go to Source (Ctrl-Shift-B) 看到類別 原始碼,須設定 Tools/Libraries/Libraries: Library Name: JavaFX yy Sources/Add JAR/Folder...: ...\javafx-sdk-yy\src.zip

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)

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

how to connect codex app to remote ollama backend through caddy relay

如何讓 Codex App 連接公司架設的 LLM 從 Caddy 閘道安裝、遠端 Ollama API 金鑰,到 Codex 的 config.toml 組態設定,一次整理成可直接照做的流程。 前言 OpenAI 提供免費下載...

總網頁瀏覽量