Могу ли я объявить и инициализировать ImageView снаружи для оператора swtich и установить его свойство вместе с ними? - PullRequest
0 голосов
/ 31 декабря 2018

Этот код работает (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 объявлен глобально и инициализирован снаружи для оператора switch и 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 голосов
/ 01 января 2019

В 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 s.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...