我正在学习JavaFX,为此我的IDE是NetBeans IDE 8.2。 我想运行项目时遇到问题。 我的示例项目是通过场景构建器在ImageView上拖放图片。 错误是:
Executing C:\Users\Mohammad Sadeghi\Documents\NetBeansProjects\DragDrop\dist\run1057050476\DragDrop.jar using platform C:\Program Files\Java\jdk1.8.0_212\jre/bin/java
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$159(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassCastException: javafx.scene.image.ImageView cannot be cast to javafx.scene.Parent
at dragdrop.DragDrop.start(DragDrop.java:22)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$166(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$179(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$177(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$178(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$152(WinApplication.java:177)
... 1 more
Exception running application dragdrop.DragDrop
Java Result: 1
我的FXMLDocument.fxml是:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.ImageView?>
<ImageView fx:id="ImgID" fitHeight="228.0" fitWidth="248.0" onDragDone="#ondragdone" pickOnBounds="true" preserveRatio="true" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="dragdrop.FXMLDocumentController"/>
FXMLDocumentController.java:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package drag-drop;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.DragEvent;
/**
*
* @author Mohammad Sadeghi
*/
public class FXMLDocumentController implements Initializable {
private Label label;
@FXML
private ImageView ImgID;
public FXMLDocumentController() {
}
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hello World!");
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
@FXML
private void ondragdone(DragEvent event) {
List<File> fi=event.getDragboard().getFiles();
try {
Image img=new Image(new FileInputStream(fi.get(0)));
ImgID.setImage(img);
} catch (Exception e) {
System.out.println("ERROR");
}
}
}
而我的Main app()是:
public class DragDrop extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
我不知道这是什么错误! 当我使用Scenebuilder时,在另一个JavaFX项目上几乎有相同的错误。 有人可以帮我吗?
答案 0 :(得分:1)
如果您查看FXMLLoader#load(URL)
的签名,则会看到:
public static <T> T load(URL location) throws IOException
注意到<T>
吗?这使得方法通用,并且将类型参数用作方法的返回类型。这样便可以将调用#load(URL)
的结果分配给任何类型的变量,例如您正在做的事情。
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
您可以从字面上将root
的类型更改为任何其他类型,并且代码仍然可以编译。但是,目前,以上代码已将T
推断为Parent
。在幕后,它使用强制类型转换,与#load(URL)
方法返回Object
而不是T
时要执行的操作相同。
Parent root = (Parent) FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
问题是您的FXML声明根元素为ImageView
。这意味着#load(URL)
方法返回的对象的实际类型是ImageView
,而不是Parent
,并且ImageView
类不是Parent
的子类型。 ClassCastException
。
一种选择是使用ImageView root = ...;
。但是,这还不够,因为您尝试将root
用作必须为Scene
的{{1}}的根。更好的解决方案是将Parent
包装在FXML文件的ImageView
中。这是一个使用Parent
的示例:
StackPane