我可以在外部为swtich声明并初始化ImageView并随其设置其属性吗?

时间:2018-12-31 20:56:52

标签: 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)

请详细解释。

1 个答案:

答案 0 :(得分:2)

在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...

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

如果您的目标是避免同时创建多个Image,那么您应该做的就是在多个Image之间共享相同的ImageView实例。