java - 运行 java 文件时打开 FXML 窗口

标签 java fxml

我目前正在尝试使用java和FXML窗口构建一个图片查看程序。我一直在纠结 - 了解 FXML 并从程序访问它们,并且能够让按钮消失和重新出现 - 但是在针对此图片查看器调整所述代码后,我发现 FXML 面板在运行时无法打开文件。除了有关(到目前为止)声明未使用的库的警告之外,没有任何错误/警告。启动后,没有错误消息,没有文本框,也没有到终端的输出,因此我无法从那里提供任何内容。代码如下:

package practice1;

import javafx.application.Application;
import javafx.stage.Stage;
import java.io.IOException;
import javax.imageio.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.*;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.*;
import javafx.scene.image.ImageView;
import javafx.scene.image.*;
import java.awt.image.BufferedImage;

public class MainProgram extends Application{


    public void start(Stage stage) {



        try {

            FXMLLoader fxmlLoader = new FXMLLoader();
            String viewerFxml = "WindowPanel.fxml";
            AnchorPane page = (AnchorPane)fxmlLoader.load(
                    this.getClass().getResource(viewerFxml).openStream());
            Scene scene = new Scene(page);
            stage.setScene(scene);
            stage.show();

        } catch (IOException ex) {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
            System.exit(1);
        }
    }

    public static void main(String args[]) {
        launch(args);
            System.exit(0);
        }
    }

FXML如下:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.text.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="practice1.MyController">
   <children>
      <Button fx:id="TurnLeft" layoutX="113.0" layoutY="353.0" mnemonicParsing="false" onAction="#hide1" text="Turn Left" />
      <Button fx:id="TurnRight" layoutX="237.0" layoutY="353.0" mnemonicParsing="false" onAction="#hide2" text="Turn Right" />
      <ToolBar prefHeight="40.0" prefWidth="600.0">
        <items>
            <MenuButton mnemonicParsing="false" text="Pick Up">
              <items>
                <MenuItem mnemonicParsing="false" text="Action 1" />
                <MenuItem mnemonicParsing="false" text="Action 2" />
              </items>
            </MenuButton>
            <MenuButton mnemonicParsing="false" text="Drop">
              <items>
                <MenuItem mnemonicParsing="false" text="Action 1" />
                <MenuItem mnemonicParsing="false" text="Action 2" />
              </items>
            </MenuButton>
        </items>
      </ToolBar>
      <Button fx:id="proceed" layoutX="178.0" layoutY="315.0" mnemonicParsing="false" onAction="#changeImage" text="Proceed" />
      <ImageView fx:id="mainImage" fitHeight="259.0" fitWidth="426.0" layoutY="40.0" pickOnBounds="true" preserveRatio="true">
         <image>
            <Image url="@Picture1.png" />
         </image></ImageView>
      <Text layoutX="436.0" layoutY="60.0" strokeType="OUTSIDE" strokeWidth="0.0" text="You have" />
      <Text layoutX="436.0" layoutY="86.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Object1" />
      <Text layoutX="436.0" layoutY="111.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Object2" />
      <Text layoutX="436.0" layoutY="139.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Object 3" />
      <ImageView fx:id="SmallImage2" fitHeight="89.0" fitWidth="117.0" layoutX="266.0" layoutY="45.0" pickOnBounds="true" preserveRatio="true" />
      <ImageView fx:id="SmallImage3" fitHeight="89.0" fitWidth="117.0" layoutX="266.0" layoutY="142.0" pickOnBounds="true" preserveRatio="true" />
      <ImageView fx:id="SmallImage1" fitHeight="89.0" fitWidth="117.0" layoutX="152.0" layoutY="45.0" pickOnBounds="true" preserveRatio="true" />
   </children>
</AnchorPane>

文件“Picture1.png”位于工作区中,位置为:

WorkspaceA/Practice1/scr/practice1/Picture1.png

最佳答案

背景

JavaFX 中使用 @ 表示法来指定 relative location它“假定位于相对于当前 FXML 文件的路径”。

出了什么问题

您可以使用以下代码将 FXML 作为流加载:

 AnchorPane page = (AnchorPane)fxmlLoader.load(
     this.getClass().getResource(viewerFxml).openStream());

Steam 不是位置,因此不存在相对于流的位置概念。

如果我在本地运行您的应用程序,我将得到一个堆栈跟踪,其中找不到图片文件(这里只是它的最后一部分):

Caused by: java.lang.IllegalArgumentException: Invalid URL or resource not found
at javafx.scene.image.Image.validateUrl(Image.java:1081)
... 18 more

如何解决

在加载 FXML 之前设置加载器中的位置:

fxmlLoader.setLocation(getClass().getResource(viewerFxml));
AnchorPane page = fxmlLoader.load();

然后加载程序将能够解析对图片文件的相对引用。

检查您的目录结构和构建输出

这对您来说可能是也可能不是问题。

您可以使用位置说明符指定图像:

<Image url="@Picture1.png" />

这告诉 FXMLLoader 在获取 FXML 的同一位置查找 Picture1.png;例如如果您从文件系统加载 FXML,则图像将与 FXML 位于文件系统上的同一文件夹中 - 类似地,如果您从 jar 加载 FXML,则图像应位于 jar 中检索 FXML 的同一路径上从。

您声明您将图片放置在:WorkspaceA/Practice1/scr/practice1/Picture1.png。我不确定该位置是什么,但如果它与您的 MainProgram.java 源、MyController.java 源、WindowPanel.fxml 位于同一位置,并且您的构建系统是否设置为将图像和 fxml 复制到编译并打包目标目录,那么它将正常工作 - 如果不是,您将需要将图像移动到适当的源位置。

关于java - 运行 java 文件时打开 FXML 窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28203560/

相关文章:

java - Quarkus ClassNotFoundException 本地依赖

Java:将两个json对象与主键合并在一起

javafx - 如何在JavaFX/FXML中对齐中心标签?

java - 为什么在初始化后添加 View 会引发 NLP,但在初始化期间不会引发 NLP,使用 afterburner.fx

java - 日期选择器仅用红色标记某些日期

java - 收到一次经纬度后如何停止这个GPS?

java - 不使用反射实例化类对象

java - 如何将外部 JS 脚本导入到 FXML 布局?

java - 如何在 android 中将蓝牙设备发现超时设置为 1 小时(3600)秒并且从不超时

java - 类 'javafx.scene.layout.BorderPane' 不支持属性 'controller'