当前位置: 首页 > 知识库问答 >
问题:

图像不是从gradle在JavaFX项目中构建的jar加载的

宰父淳
2023-03-14
$java -jar sample-menu-all.jar

java.io.FileNotFoundException: file:/Users/myuser/MyProjectRoot/build/libs/sample-menu-all.jar!/images/main_menu/icon.svg (No such file or directory)
    at java.base/java.io.FileInputStream.open0(Native Method)
    at java.base/java.io.FileInputStream.open(FileInputStream.java:220)
    at java.base/java.io.FileInputStream.<init>(FileInputStream.java:158)
    at java.base/java.io.FileInputStream.<init>(FileInputStream.java:113)
    at java.base/java.io.FileReader.<init>(FileReader.java:58)
    at presentation.utils.ImageUtil.loadSvgImage(ImageUtil.java:23)
    at presentation.controller.MenuController.loadRegistrationButtonImage(MenuController.java:25)
    at presentation.controller.MenuController.initialize(MenuController.java:20)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2573)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3253)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3210)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3179)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3152)
    at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3144)
    at presentation.navigator.VitalBitMenuNavigator.launchNewScene(VitalBitMenuNavigator.java:22)
    at presentation.navigator.VitalBitMenuNavigator.launchMenuStage(VitalBitMenuNavigator.java:33)
    at presentation.MainApp.start(MainApp.java:20)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:919)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
javafx.fxml.LoadException:
file:/Users/myuser/MyProjectRoot/build/libs/sample-menu-all.jar!/fxml/menu.fxml

    at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3253)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3210)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3179)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3152)
    at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3144)
    at presentation.navigator.VitalBitMenuNavigator.launchNewScene(VitalBitMenuNavigator.java:22)
    at presentation.navigator.VitalBitMenuNavigator.launchMenuStage(VitalBitMenuNavigator.java:33)
    at presentation.MainApp.start(MainApp.java:20)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:919)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
Caused by: java.lang.NullPointerException
    at javafx.swing/javafx.embed.swing.SwingFXUtils.toFXImage(SwingFXUtils.java:77)
    at presentation.utils.ImageUtil.loadSvgImage(ImageUtil.java:30)
    at presentation.controller.MenuController.loadRegistrationButtonImage(MenuController.java:25)
    at presentation.controller.MenuController.initialize(MenuController.java:30)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2573)
    ... 15 more

我的目录结构如下

ProjectRootDir
|-- build
  |-- libs
    sample-menu-all.jar
|-- build.gradle
|-- src
  |-- main
    |-- java
      |-- presentation
        MainApp.java
        |-- controller
          |-- MenuController.java
        |-- navigator 
          |-- MenuNavigator.java
        |-- utils
          |-- ImageUtile.java
    |-- resources
      |-- fxml
        |-- menu.fxml
      |-- properties
        |-- string.properties
    buildscript {
    dependencies {
        classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: '8.8.2'
        classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4'
    }
    repositories {
        jcenter()
        mavenLocal()
        mavenCentral()
    }
}

plugins {
    id 'java'
}

version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'javafx-gradle-plugin'

mainClassName = 'presentation.MainApp'
sourceCompatibility = 1.8

repositories {
    mavenLocal()
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    // Camera lib
    compile 'com.github.sarxos:webcam-capture:0.3.12'
    compile 'org.slf4j:slf4j-log4j12:1.7.21'
    // RxJavaFX
    implementation "io.reactivex.rxjava2:rxjava:2.2.2"
    // Retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
    // Batik (for loading AVG)
    compile group: 'org.apache.xmlgraphics', name: 'batik-transcoder', version: '1.10'
}


jfx {
    mainClass = 'MainApp'
    vendor = 'myVendor'
}

jar {
    manifest {
        attributes 'Main-Class': 'presentation.MainApp'
    }
    from {
        configurations.compile.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
}

sourceSets {
    main {
        java {
            srcDirs 'src/main/java'
        }
        resources {
            srcDirs 'src/main/resources'
        }
    }
}
package presentation;

import javafx.application.Application;
import javafx.stage.Stage;
import presentation.navigator.MenuNavigator;

public class MainApp extends Application {

    public static Stage primaryStage;

    private MenuNavigator navigator;

    public MainApp() {
        navigator = new MenuNavigator();
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        MainApp.primaryStage = primaryStage;
        navigator.launchMenuStage(primaryStage);
    }

    public static void main(String[] args) {
        launch(args);
    }
}
    import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import presentation.utils.ResourceBundleUtf8Control;
import presentation.utils.config.Config;
import java.io.File;
import java.net.URL;
import java.io.IOException;
import java.util.Locale;
import java.util.ResourceBundle;

public class MenuNavigator {

    private void launchNewScene(Stage stage, String $fxmlName) {
        try {
            URL location = getClass().getResource("/fxml/" + $fxmlName);
            ResourceBundle resources = ResourceBundle.getBundle("properties.string", Locale.getDefault(), new ResourceBundleUtf8Control());
            Parent root = FXMLLoader.load(location, resources);
            Scene scene = new Scene(root, Config.loadDimen("dimension.app_screen_size.width"), Config.loadDimen("dimension.app_screen_size.height"));
            stage.setScene(scene);
            stage.setTitle(Config.loadString("string.title"));
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void launchMenuStage(Stage stage) {
        launchNewScene(stage, "menu.fxml");
    }
}
package presentation.controller;

import javafx.event.ActionEvent;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.ImageView;
import presentation.MainApp;
import presentation.utils.FileUtil;
import presentation.utils.ImageUtil;
import java.net.URL;
import java.util.ResourceBundle;

public class MenuController extends BaseController implements Initializable {

    public Button userRegistrationButton;

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        this.loadRegistrationButtonImage();
    }

    private void loadRegistrationButtonImage() {
        ImageView buttonImage = new ImageView();
        ImageUtil.loadSvgImage(buttonImage, "/images/main_menu/icon.svg", 71, 94);
        userRegistrationButton.setGraphic(buttonImage);
        userRegistrationButton.setGraphicTextGap(37.5);
    }

}
package presentation.utils;

import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.image.PNGTranscoder;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.net.URL;

public class ImageUtil {
    public static void loadSvgImage(ImageView target, String resourcePath, int withd, int height) {
        SvgTranscoder imageTranscoder = new SvgTranscoder();

        imageTranscoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, (float) withd);
        imageTranscoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, (float) height);

        try {
            URL imagePath = ImageUtil.class.getResource(resourcePath);
            TranscoderInput input = new TranscoderInput(new FileReader(imagePath.getFile()));
            imageTranscoder.transcode(input, null);
        } catch (FileNotFoundException | TranscoderException e) {
            e.printStackTrace();
        }

        BufferedImage bimage =  imageTranscoder.getImage();
        WritableImage wimage = SwingFXUtils.toFXImage(bimage, null);
        target.setImage(wimage);
    }
}
package presentation.utils;

import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.ImageTranscoder;

import java.awt.image.BufferedImage;

public class SvgTranscoder extends ImageTranscoder {

    private BufferedImage image = null;

    @Override
    public BufferedImage createImage(int w, int h) {
        image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        return image;
    }

    @Override
    public void writeImage(BufferedImage img, TranscoderOutput out) {
    }

    public BufferedImage getImage() {
        return image;
    }
}

共有1个答案

有凯泽
2023-03-14

问题是这样的:

new FileReader(imagePath.getFile())

URL类的getFile()方法尽管有其名称,但并不返回有效的文件名,也不会将URL转换为文件。(该方法是20多年前在Java1.0中引入的,当时大多数URL实际上都表示同一台计算机或不同计算机上的物理文件。)

即使是这样,一个.jar文件也是一个单独的归档文件--其中的条目本身并不是文件,只是表示压缩数据的字节的子序列。

URL imagePath = ImageUtil.class.getResource(resourcePath);
TranscoderInput input = new TranscoderInput(imagePath.toString());
 类似资料:
  • 我正在使用Scene Builder2.0和eclipse Luna。在fxml文件中,我有我的场景的代码和图像。如果我在eclipse上测试这一点,一切都是正常的,但是如果我将它导出到可运行的jar中,然后运行它,我就会得到没有图像的窗口...以下是部分代码: 文件结构: 我觉得问题出在路径上,但我不知道这条路是怎么走的。加载程序代码: 初始化函数:

  • 我的JavaFX项目可以在一台机器中加载图像,但是相同的代码不能在另一台机器中加载图像。 我有包结构(在src中)-/com/mypackagestructure/view/images/,它保存图像文件。 我的CSS文件位于-/com/mypackagestructure/view/Login。css 我在另一台机器上有完全相同的代码(安装了相同的操作系统、相同的Eclipse IDE和JDK/

  • 下面是我的代码: 只是一个加载图像的文件。 我得到以下错误: 以下是完整的代码:

  • 我见过很多人对在Eclipse中运行时加载的图像有相同的问题,但在从导出的JAR中运行时没有。我一直有这个问题,直到我找到了正确的解决方案。现在我遇到了一个问题,当从一个新导出的、可运行的JAR运行时,图像被加载,程序工作得非常完美,但在Eclipse中却不行!值得注意的是,我在我的机器上更新了Java! 它在Eclipse中运行得非常好,直到我解决了如何正确导出可运行的JAR,现在却没有!资产文

  • 我的文件路径如下所示: 我的代码在应用程序文件夹中,我要加载的图片在资源中。 Im使用以下代码将图像从资源中获取到应用程序中的类中(图像是一个BuffereImage)。 这似乎在我的IDE(intellij)工作,因为我可以看到加载的图像,如图所示 但是,当我构建时,图像不会显示。我正在建造: 档案- 然后我构建工件- 所以当我去构建的罐子的目的地并运行它时,没有任何图片被显示 我通过提取包含图

  • 我有一个gradle groovy项目,其中我只有groovy脚本,它们不在源目录中,而是在一个单独的目录中。此外,我还有groovy junit测试,这些测试使用groovy shell测试调用它们的脚本。 我有一个gradle构建来运行测试,然后将脚本压缩到单独的zip文件中,并将它们上传到maven repo中。问题是,gradle还创建并上传了一个jar文件。由于源目录中没有文件,jar只