FXML:ImageViews 出现在 SceneBuilder 中但不出现在实际应用程序中
FXML: ImageViews showing up in SceneBuilder but not in the actual app
我正在尝试编写一个简单的 Java 应用程序,用于通过拖动门和连接来修改和可视化逻辑电路。我正在使用 SceneBuilder 将界面放在一起。现在,我坚持让可用的基本逻辑门显示在它们适当的栏中并响应与之交互。更准确地说,我试图让一个门只显示一些控制台输出,以确认 GUI 逻辑连接正在工作。
我遇到的最大问题是门的 ImageView,可能连同其他一些 FXML 元素,出于某种原因拒绝在实际编译的应用程序中显示,即使它们在 SceneBuilder 中工作和反应正确,在其 "Preview" 功能中。
我不得不做一些实验,将它们包装在我不太了解的各种其他 FXML 元素中,因为显然 ImageWiew 没有 onDragDetected() 方法,即使它的文本输入字段在场景生成器。可以直接从第一张图片上的 SceneBuilder 清楚地看到预期的正在进行的应用程序布局。与实际 运行 应用程序的第二个比较。
可能相关的代码:
Main.java
package main;
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("RootLayout.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 640, 450));
primaryStage.show();
}
public static void main(String[] args) throws Exception {
launch(args);
}
}
TheCircuitController.java
package Gates;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;
/**
* The class for holding all the information about gates, connections, and in and out pins in the current circuit
*/
public class TheCircuitController implements Initializable{
@FXML
private AnchorPane anchorPaneNAND;
//TODO temporarily public, make private later
public ArrayList<CircuitElement> allCircuitElements= new ArrayList<CircuitElement>();
public ArrayList<Pin> theCircuitInputPins = new ArrayList<Pin>();
public ArrayList<Pin> theCircuitOutputPins = new ArrayList<Pin>();
ArrayList<Connection> allCircuitConnections = new ArrayList<Connection>();
public ArrayList<Pin> allCircuitGateInputPins = new ArrayList<Pin>();
public ArrayList<Pin> allCircuitGateOutputPins = new ArrayList<Pin>();
public ArrayList<Gate> allCircuitGates = new ArrayList<Gate>();
private InbuiltGateType currentDragGateType;
@Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
// initialize your logic here: all @FXML variables will have been injected
anchorPaneNAND.setOnDragDetected(this::handleDragDetectedNAND);
}
@FXML
private void handleDragDetectedNAND(MouseEvent mouseEvent) {
System.out.println("drag detected nand!");
}
//other stuff of the class, unrelated to FXML
}
RootLayout.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="450.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Gates.TheCircuitController">
<children>
<MenuBar prefHeight="27.0" prefWidth="562.0">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Delete" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
<SplitPane dividerPositions="0.2413793103448276" prefHeight="402.0" prefWidth="640.0">
<items>
<ScrollPane fitToHeight="true" fitToWidth="true" prefHeight="400.0" prefWidth="122.0">
<content>
<VBox prefHeight="400.0" prefWidth="208.0" spacing="10.0">
<children>
<AnchorPane fx:id="anchorPaneNAND" onDragDetected="#handleDragDetectedNAND">
<children>
<ImageView>
<image>
<Image url="@../../resources/100px-NAND_ANSI.svg.png" />
</image>
</ImageView>
</children>
</AnchorPane>
<ImageView>
<image>
<Image url="@../../resources/100px-NOT_ANSI.svg.png" />
</image>
</ImageView>
<ImageView>
<image>
<Image url="@../../resources/100px-AND_ANSI.svg.png" />
</image>
</ImageView>
<ImageView>
<image>
<Image url="@../../resources/OR_ANSI.svg.png" />
</image>
</ImageView>
<ImageView>
<image>
<Image url="@../../resources/100px-NOR_ANSI.svg.png" />
</image>
</ImageView>
<ImageView>
<image>
<Image url="@../../resources/100px-XOR_ANSI.svg.png" />
</image>
</ImageView>
<ImageView>
<image>
<Image url="@../../resources/100px-XNOR_ANSI.svg.png" />
</image>
</ImageView>
</children>
<padding>
<Insets left="20.0" right="20.0" />
</padding></VBox>
</content></ScrollPane>
<ScrollPane prefHeight="400.0" prefWidth="406.0" />
</items>
</SplitPane>
</children>
</VBox>
因此我需要知道:
为什么那些门(或至少一个)没有按预期显示? ScrollPane 有什么问题,为什么它不像在 SceneBuilder 中那样显示其滑块?我需要进行哪些不同的设置或摆动才能让这些门显示并正确交互?
经过一些随机的胡扯,我找到了解决办法。
首先,我调查了 View->Show Sample Controller Skeleton
。在那里,我注意到 handleDragDetectedNAND()
方法没有任何修饰符,而我的方法有 private
,早期是从某个教程或其他教程中复制的。我删除了修改器,应用程序现在可以运行了。如果路过的人愿意解释一下为什么会这样(我不知道也没有时间研究,截止日期快到了),这个答案的价值将大大提高。
确保所有图像都在src
文件夹 中。 (测试)
The image which outsite of src
folder dont appear.
+ MyProject
+ not_working_dir
+ src
+ com.Whosebug
+ working_dir
我正在尝试编写一个简单的 Java 应用程序,用于通过拖动门和连接来修改和可视化逻辑电路。我正在使用 SceneBuilder 将界面放在一起。现在,我坚持让可用的基本逻辑门显示在它们适当的栏中并响应与之交互。更准确地说,我试图让一个门只显示一些控制台输出,以确认 GUI 逻辑连接正在工作。
我遇到的最大问题是门的 ImageView,可能连同其他一些 FXML 元素,出于某种原因拒绝在实际编译的应用程序中显示,即使它们在 SceneBuilder 中工作和反应正确,在其 "Preview" 功能中。
我不得不做一些实验,将它们包装在我不太了解的各种其他 FXML 元素中,因为显然 ImageWiew 没有 onDragDetected() 方法,即使它的文本输入字段在场景生成器。可以直接从第一张图片上的 SceneBuilder 清楚地看到预期的正在进行的应用程序布局。与实际 运行 应用程序的第二个比较。
可能相关的代码:
Main.java
package main;
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("RootLayout.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 640, 450));
primaryStage.show();
}
public static void main(String[] args) throws Exception {
launch(args);
}
}
TheCircuitController.java
package Gates;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;
/**
* The class for holding all the information about gates, connections, and in and out pins in the current circuit
*/
public class TheCircuitController implements Initializable{
@FXML
private AnchorPane anchorPaneNAND;
//TODO temporarily public, make private later
public ArrayList<CircuitElement> allCircuitElements= new ArrayList<CircuitElement>();
public ArrayList<Pin> theCircuitInputPins = new ArrayList<Pin>();
public ArrayList<Pin> theCircuitOutputPins = new ArrayList<Pin>();
ArrayList<Connection> allCircuitConnections = new ArrayList<Connection>();
public ArrayList<Pin> allCircuitGateInputPins = new ArrayList<Pin>();
public ArrayList<Pin> allCircuitGateOutputPins = new ArrayList<Pin>();
public ArrayList<Gate> allCircuitGates = new ArrayList<Gate>();
private InbuiltGateType currentDragGateType;
@Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
// initialize your logic here: all @FXML variables will have been injected
anchorPaneNAND.setOnDragDetected(this::handleDragDetectedNAND);
}
@FXML
private void handleDragDetectedNAND(MouseEvent mouseEvent) {
System.out.println("drag detected nand!");
}
//other stuff of the class, unrelated to FXML
}
RootLayout.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="450.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Gates.TheCircuitController">
<children>
<MenuBar prefHeight="27.0" prefWidth="562.0">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Delete" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
<SplitPane dividerPositions="0.2413793103448276" prefHeight="402.0" prefWidth="640.0">
<items>
<ScrollPane fitToHeight="true" fitToWidth="true" prefHeight="400.0" prefWidth="122.0">
<content>
<VBox prefHeight="400.0" prefWidth="208.0" spacing="10.0">
<children>
<AnchorPane fx:id="anchorPaneNAND" onDragDetected="#handleDragDetectedNAND">
<children>
<ImageView>
<image>
<Image url="@../../resources/100px-NAND_ANSI.svg.png" />
</image>
</ImageView>
</children>
</AnchorPane>
<ImageView>
<image>
<Image url="@../../resources/100px-NOT_ANSI.svg.png" />
</image>
</ImageView>
<ImageView>
<image>
<Image url="@../../resources/100px-AND_ANSI.svg.png" />
</image>
</ImageView>
<ImageView>
<image>
<Image url="@../../resources/OR_ANSI.svg.png" />
</image>
</ImageView>
<ImageView>
<image>
<Image url="@../../resources/100px-NOR_ANSI.svg.png" />
</image>
</ImageView>
<ImageView>
<image>
<Image url="@../../resources/100px-XOR_ANSI.svg.png" />
</image>
</ImageView>
<ImageView>
<image>
<Image url="@../../resources/100px-XNOR_ANSI.svg.png" />
</image>
</ImageView>
</children>
<padding>
<Insets left="20.0" right="20.0" />
</padding></VBox>
</content></ScrollPane>
<ScrollPane prefHeight="400.0" prefWidth="406.0" />
</items>
</SplitPane>
</children>
</VBox>
因此我需要知道:
为什么那些门(或至少一个)没有按预期显示? ScrollPane 有什么问题,为什么它不像在 SceneBuilder 中那样显示其滑块?我需要进行哪些不同的设置或摆动才能让这些门显示并正确交互?
经过一些随机的胡扯,我找到了解决办法。
首先,我调查了 View->Show Sample Controller Skeleton
。在那里,我注意到 handleDragDetectedNAND()
方法没有任何修饰符,而我的方法有 private
,早期是从某个教程或其他教程中复制的。我删除了修改器,应用程序现在可以运行了。如果路过的人愿意解释一下为什么会这样(我不知道也没有时间研究,截止日期快到了),这个答案的价值将大大提高。
确保所有图像都在src
文件夹 中。 (测试)
The image which outsite of
src
folder dont appear.
+ MyProject
+ not_working_dir
+ src
+ com.Whosebug
+ working_dir