[英]Accessing a Canvas in JavaFX scene using FXML Loader
所以我試圖制作一個包含 canvas 的窗格的場景。 這個 canvas 需要在這個窗格內,因為我將在它旁邊顯示信息。 我使用scenebuilder創建了一個窗格,然后在其中放置了一個名為“繪圖”的畫布。 然后我加載場景並嘗試在 canvas 中繪制,但是我得到並錯誤地說 canvas 是 null。 我知道有類似問題的答案,但是在我不覺得的情況下,他們沒有回答我的問題。 如果他們這樣做,您能否解釋一下,因為我不明白。
package uk.ac.rhul.cs3821;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.stage.Stage;
public class TurtleView extends Application {
private static volatile TurtleView instance = null;
Turtle turtle = new Turtle(0,0,0);
@FXML
private Canvas drawing;
private GraphicsContext gc;
@FXML
void initialize() {
instance = this;
}
/**
* Creates a JavaFX instance and Launches the JavaFX application.
*
* @return the JavaFX instance running
*/
public static synchronized TurtleView getInstance() {
if (instance == null) {
new Thread(() -> Application.launch(TurtleView.class)).start();
// Wait until the instance is ready since initialise has executed.
while (instance == null) {// empty body
}
}
return instance;
}
@Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(RuleView.class.getResource("TurtleView.fxml"));
Scene scene = new Scene(root, 800, 500);
primaryStage.setScene(scene);
primaryStage.show();
gc = drawing.getGraphicsContext2D();
}
}
你應該解決的問題
JavaFX 應用程序 class 負責實現應用程序生命周期。
對於一個 class 來說,這是很多責任。
你不應該要求它做更多的事情。
在小型演示應用程序中,應用程序 class 通常會做所有事情,但這只是因為它們是小型演示程序,除此之外,不同類的功能分開。
從來沒有應用程序 class 也充當 controller。
當您查看前面的應用程序生命周期定義時,您可以看到 VM 中應該只有一個應用程序實例,該實例是在調用 launch() 時創建的,並且只能調用一次。
默認情況下,FXML 加載器將在 FXML 中定義的fx:controller
class 上創建一個實例。 如果 class 是一個應用程序,那么 controller 將創建另一個應用程序實例,但它不會知道啟動的實例,這將非常令人困惑,因為某些字段將在一個實例中初始化,而某些字段將在另一個實例中初始化。
getInstance() 方法很奇怪。
我不確定它的用途以及您為什么擁有它。
不管是什么原因,可能有更好的方法來處理它。
我不會在這里討論更多,但您可能想針對實例管理提出一個具有特定mcve的新問題,該問題解釋了您在做什么以及為什么,並詢問一種更好的方法來實現您的明確目標.
因為應用程序不是 controller 它不應該包含:
那你該怎么辦?
請參閱此答案中的示例 hello 應用程序:
只需忽略答案中所有無關緊要的 exe 打包內容,然后查看代碼結構、文件布局、構建工具使用等方面的所有其他內容,然后按照這些內容進行操作(這將是“文件樹”和“文件”部分的答案)。 它演示了如何使用 FXML 構建一個簡單的 hello world 應用程序。
鏈接示例 hello world JavaFX 應用程序最初由Idea New JavaFX 項目向導創建。 如果你有想法,你可以運行它來創建一個新項目,然后為你的實現修改它,否則你可以將鏈接答案中的代碼復制到 IDE 中的一個新項目中並修改它。
主觀設計意見
幾個額外的設計點,它們不是那么重要,如果你願意,你可以忽略。 設計是主觀的,有不同的實施策略都可以。 您更了解您的應用程序,因此請選擇最適合您的應用程序。
您的應用程序可以有多個 FXML 文件,並非所有節點都需要在 FXML 中定義,您可以混合使用兩種不同的節點創建系統。
Perhaps have a class (non-FXML) which creates a canvas and responds to events and drawing commands on the canvas, and a separate class (an FXML controller) for managing the UI controls that interfaces with the drawing class.
class 中唯一的 @FXML 注釋字段是 canvas。
如果 class 僅包含單個節點實例,則在不使用 FXML 的代碼中創建節點會更容易。
只有當您有一個包含大量節點的更復雜的布局時,FXML 才真正有用。
這是主觀的,您仍然可以擁有一個只有一個 @FXML 字段的 controller,並且以這種方式實現就可以了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.