在 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}
2024年12月11日 星期三
Diagnosing the Error: Module javafx.fxml not found
2024年12月10日 星期二
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() // 畫路徑內部
2024年12月1日 星期日
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 介面配置檔中
訂閱:
文章 (Atom)