java - 我可以在 for 和 switch 语句之外声明和初始化 ImageView 并在其中设置其属性吗?

标签 java javafx

此代码正在运行(ImageView 已全局声明,但在 for 和 switch 语句中初始化并设置其属性)

private static ImageView imgP;
public static Pane board = new Pane();

public void start(Stage primaryStage)throws Exception {
    Rectangle r1,r;
    for(int i = 0;i<64;i+=2) {
        r = new Rectangle((i%8 + (i/8)%2)*tileSize,(i/8)*tileSize, tileSize,tileSize);
        r.setFill(Color.rgb(255,200,100));
        r1 = new Rectangle(((i+1)%8-(((i+1)/8)%2))*tileSize,(((i+1))/8)*tileSize,tileSize,tileSize);
        r1.setFill(Color.rgb(150,50,30));

        board.getChildren().addAll(r,r1);
    }


    for(int i = 0;i<64;i++) {
        switch(Test.board[i/8][i%8]) {
        case "P":
                imgP = new ImageView(new Image("images/11.png"));
                imgP.setFitWidth(tileSize);
                imgP.setFitHeight(tileSize);
                imgP.setX((i%8 )*tileSize);
                imgP.setY((i/8)*tileSize);
                board.getChildren().add(imgP);
            break;
         }
     }
     Scene scene = new Scene(board);
     primaryStage.setScene(scene);
     primaryStage.show();
}
}

此代码不会(ImageView 被全局声明,并在 for 和 switch 语句之外初始化,同时设置其属性)

private static ImageView imgP;
public static Pane board = new Pane();

public void start(Stage primaryStage)throws Exception {
    Rectangle r1,r;
    ImageView imgP = new ImageView(new Image("images/11.png"));
    for(int i = 0;i<64;i+=2) {
        r = new Rectangle((i%8 + (i/8)%2)*tileSize,(i/8)*tileSize, tileSize,tileSize);
        r.setFill(Color.rgb(255,200,100));
        r1 = new Rectangle(((i+1)%8-(((i+1)/8)%2))*tileSize,(((i+1))/8)*tileSize,tileSize,tileSize);
        r1.setFill(Color.rgb(150,50,30));

        board.getChildren().addAll(r,r1);
    }


    for(int i = 0;i<64;i++) {
        switch(Test.board[i/8][i%8]) {
        case "P":
                imgP.setFitWidth(tileSize);
                imgP.setFitHeight(tileSize);
                imgP.setX((i%8 )*tileSize);
                imgP.setY((i/8)*tileSize);
                board.getChildren().add(imgP);
            break;
        }
       }
       Scene scene = new Scene(board);
       primaryStage.setScene(scene);
       primaryStage.show();
}
}

产生的错误如下:

Exception in Application start method
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
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$154(LauncherImpl.java:182)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: Children: duplicate children added: parent = Pane@5a3b6136
    at javafx.scene.Parent$2.onProposedChange(Parent.java:454)
    at com.sun.javafx.collections.VetoableListDecorator.add(VetoableListDecorator.java:206)
    at FrontEnd.start(FrontEnd.java:47)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(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$147(WinApplication.java:177)

请有理有据地解释。

最佳答案

在 JavaFX 中,Node 不能同时多次添加到同一个父节点。这就是您收到此异常的原因:

Caused by: java.lang.IllegalArgumentException: Children: duplicate children added: parent = Pane@5a3b6136
    at javafx.scene.Parent$2.onProposedChange(Parent.java:454)
    at com.sun.javafx.collections.VetoableListDecorator.add(VetoableListDecorator.java:206)
    at FrontEnd.start(FrontEnd.java:47)
    // Omitted rest of stack trace for brevity...

在您的代码中,您调用for循环的board.getChildren().add(imgP)每个迭代。第二个示例中的问题是 imgP 每次都是相同的实例。在第一个示例中,每次迭代都会创建一个新实例。

如果您的目标是避免创建同一事物的多个 Image,那么您应该做的是在多个 ImageView< 之间共享相同的 Image 实例s.

关于java - 我可以在 for 和 switch 语句之外声明和初始化 ImageView 并在其中设置其属性吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53991362/

相关文章:

java - Gson 枚举序列化

java - 是否可以在不使用 JavaMail api 对端口进行硬编码的情况下连接到邮件服务器,基本上代码应该独立于端口。 ?

JavaFX如何将对话框/警报带到屏幕前面

java - 单击 Javafx 2.2 选项卡中的保存/取消按钮时如何关闭该选项卡?

java - 用于 java 的领英

Java 类型转换 - float(和 long)到 int

java - 套接字仅接受一个客户端

java - Scala (JavaFX) sbt-assemble 不打包图像/照片

java - AlertType.CONFIRMATION 在 JavaFX 中抛出 IllegalArgumentException

java - 当 SwingNode 的父级调整大小时,SwingNode 内容不调整大小