简体   繁体   English

我无法加载图像来更改 window JavaFX 的图标

[英]I can't load an image to change the icon of a window JavaFX

I tried to make a window with an icon with JavaFx but it doesn't work.我试图制作一个带有 JavaFx 图标的 window 但它不起作用。 I don't know why?我不知道为什么? I've been testing with InputStream and I had an error also.我一直在使用 InputStream 进行测试,但我也遇到了错误。 I use URL and it doesn't work also.我使用 URL ,它也不起作用。 HELP:( please请帮忙

The Main Class:主要Class:

package fr.fireblaim.firelauncherlib_test;

import fr.fireblaim.firelauncherlib.WindowOptions;
import fr.fireblaim.firelauncherlib.graphics.Base;
import fr.fireblaim.firelauncherlib.utils.ResourceLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class Main extends Base {

    private WindowOptions windowOptions = new WindowOptions(1280, 720,  "Launcher Test", true, StageStyle.UNDECORATED);

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        Scene scene = new Scene(new LauncherPanel(windowOptions));

        setupWindow(stage, scene, windowOptions, ResourceLoader.loadImage("icon.png"));
    }

}

The ResourceLoader Class:资源加载器 Class:

package fr.fireblaim.firelauncherlib.utils;

import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

public class ResourceLoader {

    private static String resourceLocation = "resources/";

    public static Image loadImage(String file) {
        try {
            BufferedImage image = ImageIO.read(new URL( "file:" + getResourceLocation() + file));
            return SwingFXUtils.toFXImage(image, null);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void setResourceLocation(String resourceLocation) {
        ResourceLoader.resourceLocation = resourceLocation;
    }

    public static String getResourceLocation() {
        return resourceLocation;
    }
}

The Base Class:基础 Class:

package fr.fireblaim.firelauncherlib.graphics;

import fr.fireblaim.firelauncherlib.WindowOptions;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

import javax.swing.*;
import java.awt.*;

public abstract class Base extends Application {

    private Point point = new Point();

    public abstract void start(Stage stage) throws Exception;

    protected void setupWindow(Stage stage, Scene scene, WindowOptions windowOptions) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            System.err.println("[FireLauncherLib] Can't setup the window:\n" + e);
        }

        stage.initStyle(windowOptions.getStageStyle());
        stage.setResizable(false);
        stage.setTitle(windowOptions.getTitle());
        stage.setWidth(windowOptions.getWidth());
        stage.setHeight(windowOptions.getHeight());
        stage.setAlwaysOnTop(true);

        stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent event) {
                Platform.exit();
                System.exit(0);
            }
        });

        if(windowOptions.isMovable()) {
            scene.setOnMousePressed(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    point.x = (int)(stage.getX() - event.getScreenX());
                    point.y = (int)(stage.getY() - event.getScreenY());
                }
            });

            scene.setOnMouseDragged(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    stage.setX(event.getScreenX() + point.x);
                    stage.setY(event.getScreenY() + point.y);
                }
            });
        }

        stage.setScene(scene);

        stage.show();
    }

    protected void setupWindow(Stage stage, Scene scene, WindowOptions windowOptions, Image icon) {
        setupWindow(stage, scene, windowOptions);
        stage.getIcons().clear();
        stage.getIcons().add(icon);
    }

}

I have this error:我有这个错误:

javax.imageio.IIOException: Can't get input stream from URL!
    at javax.imageio.ImageIO.read(ImageIO.java:1401)
    at fr.fireblaim.firelauncherlib.utils.ResourceLoader.loadImage(ResourceLoader.java:17)
    at fr.fireblaim.firelauncherlib_test.Main.start(Main.java:24)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$7(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication.lambda$null$10(GtkApplication.java:245)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.FileNotFoundException: resources/icon.png (Aucun fichier ou dossier de ce type)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:90)
    at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:188)
    at java.net.URL.openStream(URL.java:1068)
    at javax.imageio.ImageIO.read(ImageIO.java:1399)
    ... 11 more
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at javafx.stage.Stage$4.onChanged(Stage.java:696)
    at com.sun.javafx.collections.TrackableObservableList.lambda$new$0(TrackableObservableList.java:45)
    at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
    at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
    at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
    at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
    at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
    at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
    at javafx.collections.ModifiableObservableListBase.add(ModifiableObservableListBase.java:155)
    at java.util.AbstractList.add(AbstractList.java:108)
    at fr.fireblaim.firelauncherlib.graphics.LauncherBase.setupWindow(LauncherBase.java:70)
    at fr.fireblaim.firelauncherlib_test.Main.start(Main.java:24)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$7(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication.lambda$null$10(GtkApplication.java:245)
    at java.lang.Thread.run(Thread.java:748)

I use Intellij IDEA 2019.3.4 Ultimate我使用 Intellij IDEA 2019.3.4 Ultimate

The Resource Structure:资源结构:

src resources icon.png src资源图标.png

It seems from your code - as you use the "file:" protocol - that you expect the images to be in a directory on the filesystem.从您的代码看来 - 当您使用“文件:”协议时 - 您希望图像位于文件系统上的目录中。 So why not change the call load from File not URL:那么为什么不从文件而不是 URL 更改呼叫负载:

File f = new File(getResourceLocation(), file);
ImageIO.read(f)

You can then fix the directory location issue by checking where Java thinks those files are from by calling / printing:然后,您可以通过调用/打印检查 Java 认为这些文件来自何处来解决目录位置问题:

f.getAbsolutePath();
f.exists();

Alternatively if these images are in the same jar as your code you should be using getClass().getResourceAsStream() to locate InputStream to pass to ImageIO.read(is).或者,如果这些图像与您的代码在同一个 jar 中,您应该使用 getClass().getResourceAsStream() 来定位 InputStream 以传递给 ImageIO.read(is)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM