[英]“NullPointerException: Location is required.” when running the JavaFX project JAR, but not when running from the IDE
[英]JavaFX "Location is required." even though it is in the same package
我正在嘗試運行我的 JavaFX 程序,但遇到了一些困難。 我不斷收到“java.lang.NullPointerException:需要位置”的錯誤。 fxml 文件與應用程序 class 在同一個 package 中。這是我非常簡單的代碼:
package com.kromalights.designer.entry;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
primaryStage.setTitle("Kromalights Designer");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
這是我的 main.fxml 文件的副本:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>
<?scenebuilder-stylesheet mailStyles.css?>
<?import java.net.*?>
<BorderPane prefHeight="300.0" prefWidth="300.0" xmlns:fx="http://javafx.com/fxml/1"
xmlns="http://javafx.com/javafx/2.2"
fx:controller="com.kromalights.designer.entry.Controller">
<bottom>
<Pane prefHeight="200.0" prefWidth="200.0"/>
</bottom>
<center>
<Pane prefHeight="200.0" prefWidth="200.0"/>
</center>
<left>
<VBox prefHeight="200.0" prefWidth="100.0"/>
</left>
<top>
<HBox prefHeight="100.0" prefWidth="200.0"/>
</top>
<stylesheets>
<URL value="@mainStyles.css" />
</stylesheets>
</BorderPane>
controller class確實存在,在fxml文件指定的package中。 我所有的名字都是正確的,並且是我認為它們應該出現的地方。 我錯過了什么? 我確實嘗試重命名我的 fxml 文件,以防出現名稱問題。 請幫忙。 僅供參考,我在 OSX 上使用 Intellij IDEA。
更新:這是一個 Maven 問題。 我為此項目設置了 Maven,這導致了問題。 我暫時刪除了 Maven,這樣我就可以在沒有它的情況下繼續工作。 有沒有人知道我在使用 Maven 時如何最好地處理這個問題?
就我而言,上述所有問題都不是問題。
當我更換時,我的問題解決了:
getClass().getResource("ui_layout.fxml")
和 :
getClass().getClassLoader().getResource("ui_layout.fxml")
將文件移動到 main/resources 目錄有效。
URL url = new File("src/main/java/ua/adeptius/goit/sample.fxml").toURI().toURL();
Parent root = FXMLLoader.load(url);
這對我有幫助,因為
getClass.getResource("path")
總是給我返回空;
我現在已經看到這個錯誤幾次了。 我經常使用 Netbeans Maven FXML 應用程序模板編寫一個名為“Simple”的小項目,只是為了在出現問題時作為一種“參考模型”返回。 為了測試,我使用這樣的東西:
String sceneFile = "/fxml/main.fxml";
Parent root = null;
URL url = null;
try
{
url = getClass().getResource( sceneFile );
root = FXMLLoader.load( url );
System.out.println( " fxmlResource = " + sceneFile );
}
catch ( Exception ex )
{
System.out.println( "Exception on FXMLLoader.load()" );
System.out.println( " * url: " + url );
System.out.println( " * " + ex );
System.out.println( " ----------------------------------------\n" );
throw ex;
}
當您運行該代碼段並且加載失敗時,您應該會看到一個原因,或者至少是來自 FXMLLoader 的一條消息。 因為是測試,所以拋出異常。 你不想繼續。
注意事項。 這是一個 Maven 項目,因此資源將相對於資源文件夾,因此:
傳遞給 FXMLLoader 的資源區分大小寫:
// If you load "main.fxml" and your file is called: "Main.fxml" // You will will see the message ... java.lang.NullPointerException: Location is required.
如果您解決了“需要位置”的問題,那么您可能在 FXML 中遇到了問題
// 像這樣: // javafx.fxml.LoadException: file:/D:/sandbox/javafx/app_examples/person/target/person-00.00.01-SNAPSHOT.jar!/fxml/tableWithDetails.fxml:13
將意味着第 13 行存在問題,在文件中,每個:
在消息中。 此時,您需要閱讀 FXML 並查看是否可以發現問題。 您可以嘗試相關問題中的一些提示。
對於這個問題,我認為文件名是正確的大小寫:“Main.fxml”。 移動文件時,名稱可能已更改或字符串已重新鍵入。 祝你好運。
有關的:
代替
Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
放
Parent root = FXMLLoader.load(getClass().getResource("/main.fxml"));
區別在於“/”。
原因 :
第一個:getResource 將嘗試查找與包相關的資源
第二個:getResource 會將其視為絕對路徑並簡單地調用類加載器。
我無法使用
getClass().getResource("views/view.fxml")
因為我把我的控制器類放到了“控制器”包中,所以這是我的解決方案:
getClass().getResource("../views/view.fxml")
如果您查看文檔 [1],您會看到load()
方法可以接受一個 URL:
load(URL location)
因此,如果您運行的是 Java 7 或更新版本,您可以像這樣加載 FXML 文件:
URL url = Paths.get("./src/main/resources/fxml/Fxml.fxml").toUri().toURL();
Parent root = FXMLLoder.load(url);
此示例來自 Maven 項目,這就是 FXML 文件位於資源文件夾中的原因。
[1] https://docs.oracle.com/javase/8/javafx/api/javafx/fxml/FXMLLoader.html
此問題可能是由 FXML 文件的錯誤路徑引起的。
如果您使用的是絕對路徑( my/package/views/view.fxml
),則必須在前面加上斜杠:
getClass().getResource("/my/package/views/view.fxml")
您也可以使用相對路徑:
getClass().getResource("views/view.fxml")
我遇到了同樣的錯誤。 在我的情況下,fxml 文件名中有一個前導空格符號:
" fxml_example.fxml" 而不是 "fxml_example.fxml"
我不知道它是從哪里來的。 很難注意到它。 當我刪除前導空格時,一切正常。 我什至不知道文件名可以以空格符號開頭。
如果您的問題與 Maven 無關,並且您在瀏覽器中運行它時遇到相同的 NullPointerException(從 IDE 運行它很好),請嘗試以下操作:
-> Netbeans -> 右鍵單擊項目 -> 屬性 -> 構建 -> 部署 -> 勾選“請求無限制訪問(啟用簽名,自簽名)”
這是因為@FXML 注釋需要從 FXML 標記注入值的權限(請參閱http://docs.oracle.com/javafx/2/fxml_get_started/fxml_deployment.htm )
我在 JDK8u31 上運行我的應用程序,如果沒有 Chrome/Firefox/IE 中的證書,它永遠不會運行。
加載器的根目錄位於 maven 項目的“資源”文件夾中。 所以如果你有src/main/java
那么 fxml 文件路徑應該從: src/main/resources
https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html
我嘗試了上述答案,但在我的項目中不起作用。 我的項目是在 Windows 中使用maven
和openjfx
。
這解決了這個問題:
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("/main.fxml"));
root = fxmlLoader.load()
我發現上述所有解決方案都可以正常工作,因為它們會觸發您的 IDE 重建項目。 不涉及魔法。
這個問題的“真正”解決方案是你應該放棄你以前的構建目錄。
2021 年 6 月:
將項目轉換為 Maven 后,您應該將 fxml 和 css 文件移動到資源文件夾。 只需拖放(在 IntelliJ 社區中)。 然后 :
Parent root = FXMLLoader.load(Objects.requireNonNull(getClass().getClassLoader().getResource("FXMLDocument.fxml")));
和 :
root.getStylesheets().add(getClass().getResource("/newCascadeStyleSheet.css").toString());
styleSheet 需要斜線。
就這樣。
如果您的項目是基於 Maven 的,Idea 將忽略 src/main/java 文件夾中除 java 文件之外的所有文件。 就像你說將文件移動到 src/main/resources 是可行的,但現在 SceneBuilder 不再知道你的控制器類了,因為它在一個完全不同的目錄中,你失去了所有的洞察力,你盲目地構建。
我相信這是 intellij 中的一個問題,因為 SceneBuilder希望在(我引用)“相同目錄、直接子目錄或 .fxml”文檔的父目錄中找到您的控制器類 java 文件。
我有時也有同樣的例外。
當我在 Eclipse 中使用向導創建 FXML 文件時,我在名稱字段中寫入example.fxml 。 Eclipse 會創建一個文件,例如example.fxml.fxml 。 由於這個錯誤,FXMLLoader 無法找到正確的 FXML 文件。 所以,我的建議是,檢查你的 start-Method 中 FXML-Filename 的名稱和文件的真實名稱。
希望我能幫上忙。 祝你好運。
您應該在根目錄中使用getClassLoader()
方法
Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("main.fxml"));
我有這樣的結構:
src
main
java
dogapp
DogApp.java (the class that contains the main method and overloaded start method)
resources
DogApp.fxml
但它需要像這樣(需要在resources
文件夾中有dogapp
文件夾):
src
main
java
dogapp
DogApp.java (the class that contains the main method and overloaded start method)
resources
dogapp
DogApp.fxml
DogApp.java :
public class DogApp extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws IOException {
primaryStage.setTitle("Dog App");
primaryStage.setScene(new Scene(FXMLLoader
.load(getClass().getResource("DogApp.fxml"))));
primaryStage.show();
}
}
我只是簡單地向加載程序傳遞了一個正確的URL,如下所示:
URL url = getClass().getResource("myForm.fxml");
Parent root = FXMLLoader.load(url);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.