簡體   English   中英

JavaFX “需要位置。” 即使它在同一個 package

[英]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 項目,因此資源將相對於資源文件夾,因此:

  • “/fxml/main.fxml”。
  • 前導斜杠是必需的。
  • 傳遞給 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 行存在問題,在文件中,每個:

  • tableWithDetails.fxml :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 中使用mavenopenjfx

這解決了這個問題:

FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("/main.fxml"));
root = fxmlLoader.load()

我發現上述所有解決方案都可以正常工作,因為它們會觸發您的 IDE 重建項目。 不涉及魔法。

這個問題的“真正”解決方案是你應該放棄你以前的構建目錄。

  • 如果您使用的是 Maven,只需刪除目標文件夾(或執行 mvn clean)!
  • 如果您使用的是 ANT,請刪除相應的文件夾(我認為它已被調用)!
  • 如果您使用的是 Gradle,請刪除 build 文件夾!

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM