JavaFX Image エラー 〜java.lang.reflect.InvocationTargetException〜

JavaFXでのコーディング中、PNGファイルを読み込もうとした時に、下のようなエラーが出ました。

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$155(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: Children: duplicate children added: parent = Grid hgap=0.0, vgap=0.0, alignment=TOP_LEFT
    at javafx.scene.Parent$2.onProposedChange(Parent.java:454)
    at com.sun.javafx.collections.VetoableListDecorator.add(VetoableListDecorator.java:206)
    at javafx.scene.layout.GridPane.add(GridPane.java:965)
    at zenryokuservice.main.game.GameMain.start(GameMain.java:256)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Exception running application zenryokuservice.main.game.GameMain

エラーが出た実装

ImageView image = new ImageView(new Image("/map/Grass.png", true));

修正後

ImageView image = new ImageView(new Image(url.toExternalForm()));

パスの内容が悪かったのかね?



関連ページ一覧

Eclipse セットアップ

  1. Java Install Eclipse〜開発ツールのインストール〜
  2. TensorFlow C++環境〜EclipseCDTをインストール〜
  3. Setup OpenGL with JavaJOGLを使う準備 for Eclipse
  4. Eclipse Meven 開発手順〜プロジェクトの作成〜
  5. Java OpenCV 環境セットアップ(on Mac)
  6. Eclipse SceneBuilderを追加する
  7. JavaFX SceneBuilder EclipseSceneBuilder連携~

Java Basic一覧

  1. Java Basic Level 1 〜Hello Java〜
  2. Java Basic Level2 〜Arithmetic Calculate〜
  3. Java Basic Level3 〜About String class〜
  4. Java Basic Level 4〜Boolean〜
  5. Java Basic Level 5〜If Statement〜
  6. Java Basic Summary from Level1 to 5
  7. Java Basic Level 6 〜Traning of If statement〜
  8. Java Basic Level8 〜How to use for statement〜
  9. Java Basic Level 8.5 〜Array〜
  10. Java Basic Level 9〜Training of for statement〜
  11. Java Basic Level 10 〜While statement 〜
  12. Java Basic Swing〜オブジェクト指向〜
  13. Java Basic Swing Level 2〜オブジェクト指向2〜
  14. サンプル実装〜コンソールゲーム〜
  15. Java Basic インターフェース・抽象クラスの作り方
  16. Java Basic クラスとは〜Step2_1〜
  17. Java Basic JUnit 〜テストスイートの作り方〜

Git関連

  1. Java Git clone in Eclipse 〜サンプルの取得〜
  2. Eclipse Gitリポジトリの取得 GitからソースをPullしよう〜
  3. IntelliJ IDEA GitGitリポジトリからクローン〜

JavaFX関連ページ

  1. Eclipse SceneBuilderを追加する
  2. JavaFX SceneBuilder 〜EclipseとSceneBuilder連携~
  3. JavaFX SceneBuilder〜ボタンにメソッドを割り当てるワンポイント〜
  4. Java プロコンゲーム 〜見た目の作成(SceneBuilderの使用)〜

ステップアップ関連ページ一覧

  1. Java 初めてでも大丈夫〜ステップアッププログラミングのススメ〜
  2. ステップアッププログラミング〜Java FxでHelloWorld解説〜
  3. Java StepUpPrograming〜JavaFX で四則計算〜
  4. Java StepUpPrograming〜JavaFXで画面切り替えを作る1〜
  5. Java StepUpPrograming〜JavaFXで画面切り替え2ボタン作成〜
  6. Java StepUpPrograming〜JavaFXで画面切り替え3アクション〜
  7. Java StepUpPrograming〜JavaFXで画面切り替え4Pane切り替え〜
  8. Java StepUpPrograming〜JavaFXで画面切り替え5WebEngine

JavaFX + ND4Jで機械学習準備

  1. JavaFX + ND4J〜数学への挑戦1:ND4Jのインストール〜
  2. JavaFX + ND4J〜数学への挑戦2: 行列の計算〜
  3. Java + ND4J 〜数学への挑戦3: ベクトル(配列)の作成方法〜

オブジェクト指向関連ページ

  1. [オブジェクト指向の概念1〜OracleDocのチュートリアル1〜](https://zenryokuservice.com/wp/2019/10/301. /%e3%82%aa%e3%83%96%e3%82%b8%e3%82%a7%e3%82%af%e3%83%88%e6%8c%87%e5%90%91%e3%81%ae%e6%a6%82%e5%bf%b5-%e3%80%9coracledoc%e3%81%ae%e3%83%81%e3%83%a5%e3%83%bc%e3%83%88%e3%83%aa%e3%82%a2%e3%83%ab%ef%bc%91/)
  2. オブジェクト指向の概念2〜クラスとは〜

Java Discord

  1. IntelliJ IDEA Discord Botを作る〜Gradle環境のセットアップ〜
  2. Java Discord セットアップ〜Hello Discord〜
  3.  Java Discord ピンポン〜Discordプログラム〜
  4. Java Discord Listener実装〜コマンドを好きなだけ追加しよう〜

JavaFX ワンポイント 〜新しいWindowを立ち上げる〜

JavaFXを起動するときにすでにウィンドウを1つ起動していますが、さらにウィンドウを使いたいとき。。。

今回はそんなところを「ワンポイントレッスン」的に記載したいと思います。

ちなみに、JavaFXはこんな感じのものです。余計な音が入っています。そして、文言を表示する部分でnewWindowを使用しています。

ウィンドウを新しく作る

WindowはStageです。なので、下のように実装したらできました。
参考にしたサイトはこちらです。

private Stage createNewWindow(Stage primary) {
    newWindow = new Stage();
    StackPane stack = new StackPane();
    textArea = new TextArea();
    textArea.setOnKeyPressed(keyEvent -> {
        KeyCode code = keyEvent.getCode();
        if (keyEvent.isShiftDown() && KeyCode.SPACE.equals(code)) {
            newWindow.close();
            isTextIn = false;
        }
    });
    textArea.setOnKeyReleased(keyEvent -> {
        KeyCode code = keyEvent.getCode();
        if (keyEvent.isShiftDown() && KeyCode.ENTER.equals(code)) {
            textArea.setText("");
            textArea.positionCaret(0);
        }
    });
    stack.getChildren().add(textArea);
    Scene scene = new Scene(stack, 250, 50);
    newWindow.setScene(scene);
    newWindow.initModality(Modality.WINDOW_MODAL);
    newWindow.initOwner(primary);
    newWindow.setX(primary.getWidth() * 0.4);
    newWindow.setY(primary.getHeight() * 0.8);
    newWindow.show();

    return newWindow;
}

作成したウィンドウにキーイベントを追加して見ました。

ちなみに、
簡単ですが、こんな感じで。。。

でわでわ。。。



関連ページ

関連ページ一覧

Eclipse セットアップ

  1. Java Install Eclipse〜開発ツールのインストール〜
  2. TensorFlow C++環境〜EclipseCDTをインストール〜
  3. Setup OpenGL with JavaJOGLを使う準備 for Eclipse
  4. Eclipse Meven 開発手順〜プロジェクトの作成〜
  5. Java OpenCV 環境セットアップ(on Mac)
  6. Eclipse SceneBuilderを追加する
  7. JavaFX SceneBuilder EclipseSceneBuilder連携~

Java Basic一覧

  1. Java Basic Level 1 〜Hello Java〜
  2. Java Basic Level2 〜Arithmetic Calculate〜
  3. Java Basic Level3 〜About String class〜
  4. Java Basic Level 4〜Boolean〜
  5. Java Basic Level 5〜If Statement〜
  6. Java Basic Summary from Level1 to 5
  7. Java Basic Level 6 〜Traning of If statement〜
  8. Java Basic Level8 〜How to use for statement〜
  9. Java Basic Level 8.5 〜Array〜
  10. Java Basic Level 9〜Training of for statement〜
  11. Java Basic Level 10 〜While statement 〜
  12. Java Basic Swing〜オブジェクト指向〜
  13. Java Basic Swing Level 2〜オブジェクト指向2〜
  14. サンプル実装〜コンソールゲーム〜
  15. Java Basic インターフェース・抽象クラスの作り方
  16. Java Basic クラスとは〜Step2_1〜
  17. Java Basic JUnit 〜テストスイートの作り方〜

Git関連

  1. Java Git clone in Eclipse 〜サンプルの取得〜
  2. Eclipse Gitリポジトリの取得 GitからソースをPullしよう〜
  3. IntelliJ IDEA GitGitリポジトリからクローン〜

JavaFX FileChooser 〜ファイルの選択をする部品〜

FileChooserクラス

ブラウザ(Google Chrome, Safari, Edge etc..)で、ファイルを選択してアップロードするときのような、画面操作を実現するクラスFileChooserクラスを紹介します。

JavaFXはApplicationクラスを継承してlaunchを実行すれば起動できるシンプルな扱いで動かせます。

具体的には下のように書きます。参照先はこちらOracleDocsです。

コードの書き方

1. Applicationクラスを継承

作成したクラスにApplicationクラスを継承します。下のクラスは「HelloWorld」を作成して「extends Application」と追加しました。

import文は「import javafx.application.Application;」と書きます。

public class HelloWorld extends Application {

2. メインメソッドの実装

単純に下のように書けば動きます。メインメソッドで呼び出しているのはApplication#launch()メソッドです。継承しているので、そのまま呼び出せます。
※launchメソッドはstaticメソッドなので、メインメソッド内でも直接呼び出すことができます。

 public static void main(String[] args) {
        launch(args);
 }

3. start()メソッドの実装

このメソッドをオーバーライドして描画する画面のプログラムを行います。
Application#start()メソッドをHelloWorldクラスでstart()メソッドを定義(実装)することで、オーバーライドすることができます。日本語にすると「上書き」です。
そんなわけで、HelloWorldクラスのlaunch()メソッドを起動することで、このクラスのstart()メソッドが動きます。

ファイルチューザーの扱い方

いよいよ、描画処理の内容に入ります。
下のように、インスタンス化して動かします。細かいところは、実装してみて確認してください(笑)

 // ファイルクラスをインスタンス化
 FileChooser fileChooser = new FileChooser();
 // ダイヤログを表示した時の文字(下のキャプチャ参照)
 fileChooser.setTitle("ファイルを選択してください。");
 // Mac(自分の端末)でやった場合はファイルタイプを指定するものがないので無効?
 fileChooser.getExtensionFilters().addAll(
         new ExtensionFilter("Text Files", "*.txt"),
         new ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif"),
         new ExtensionFilter("Audio Files", "*.wav", "*.mp3", "*.aac"),
         new ExtensionFilter("All Files", "*.*"));
 File selectedFile = fileChooser.showOpenDialog(mainStage)

そして最後の行にあるファイルを書き出ししないとファイルが作成されません。

そして、キャンセルををした場合はFileがNullになるようです。

[rakuten ids="auc-dejima:10002899"]

関連ページ一覧

  1. Java Doc 読解 System
  2. Java Doc 読解〜System.out
  3. Java Doc読解 System.In
  4. JavaDoc 読解  Filesクラス 
  5. Java Doc読解 BufferedReader
  6. Java Doc 読解〜BufferedWriter

JavaFXでハローワールド〜OpenCVまで

  1. Java 初めてでも大丈夫〜ステップアッププログラミングのススメ〜
  2. ステップアッププログラミング〜Java FxでHelloWorld解説〜
  3. Java StepUpPrograming〜JavaFX で四則計算〜
  4. Java StepUpPrograming〜JavaFXで画面切り替えを作る1〜
  5. Java StepUpPrograming〜JavaFXで画面切り替え2ボタン作成〜
  6. Java StepUpPrograming〜JavaFXで画面切り替え3アクション〜
  7. Java StepUpPrograming〜JavaFXで画面切り替え4Pane切り替え〜
  8. Java StepUpPrograming〜JavaFXで画面切り替え5WebEngine〜




JavaFX ワンポイント 〜升目状にNodeを配置する〜

以下のような感じでNodeを配置できます。緑色の部分には50x50のラベル(Image付き)を4x4マスで並べました。

<ソース>

String lightGrass = "grass_light.png";
String deepGrass = "grass_deep.png";
String soilBasic = "soil_basic.png";
GridPane grid = new GridPane();
grid.add(createImageLbl(lightGrass), 0, 1);
grid.add(createImageLbl(lightGrass), 0, 2);
grid.add(createImageLbl(lightGrass), 0, 3);
grid.add(createImageLbl(lightGrass), 0, 4);
grid.add(createImageLbl(lightGrass), 1, 1);
grid.add(createImageLbl(lightGrass), 1, 2);
grid.add(createImageLbl(lightGrass), 1, 3);
grid.add(createImageLbl(lightGrass), 1, 4);
grid.add(createImageLbl(lightGrass), 2, 1);
grid.add(createImageLbl(lightGrass), 2, 2);
grid.add(createImageLbl(lightGrass), 2, 3);
grid.add(createImageLbl(lightGrass), 2, 4);
grid.add(createImageLbl(lightGrass), 3, 1);
grid.add(createImageLbl(lightGrass), 3, 2);
grid.add(createImageLbl(lightGrass), 3, 3);
grid.add(createImageLbl(lightGrass), 3, 4);
vBox.getChildren().add(grid);

lightGrass(ラベル, 位置(X), 位置(Y));のように設定します。

なので、上のソースを以下のように修正すると。。。

GridPane grid = new GridPane();
grid.add(createImageLbl(lightGrass), 0, 1);
grid.add(createImageLbl(lightGrass), 0, 2);
grid.add(createImageLbl(lightGrass), 0, 3);
grid.add(createImageLbl(lightGrass), 0, 4);
grid.add(createImageLbl(deepGrass), 1, 1);
grid.add(createImageLbl(deepGrass), 1, 2);
grid.add(createImageLbl(deepGrass), 1, 3);
grid.add(createImageLbl(deepGrass), 1, 4);
grid.add(createImageLbl(soilBasic), 2, 1);
grid.add(createImageLbl(lightGrass), 2, 2);
grid.add(createImageLbl(lightGrass), 2, 3);
grid.add(createImageLbl(lightGrass), 2, 4);
grid.add(createImageLbl(lightGrass), 3, 1);
grid.add(createImageLbl(soilBasic), 3, 2);
grid.add(createImageLbl(lightGrass), 3, 3);
grid.add(createImageLbl(lightGrass), 3, 4);
vBox.getChildren().add(grid);

座標で位置を示します。座標 = (X, Y) = (0, 1) => 0,1の位置テキストフィールドの下あたりにあります。

[rakuten ids="toripurussss:10000004"]

Eclipse セットアップ

  1. Java Install Eclipse〜開発ツールのインストール〜
  2. TensorFlow C++環境〜EclipseCDTをインストール〜
  3. Setup OpenGL with JavaJOGLを使う準備 for Eclipse
  4. Eclipse Meven 開発手順〜プロジェクトの作成〜
  5. Java OpenCV 環境セットアップ(on Mac)
  6. Eclipse SceneBuilderを追加する
  7. JavaFX SceneBuilder EclipseSceneBuilder連携~

JavaFXでハローワールド〜OpenCVまで

  1. Java 初めてでも大丈夫〜ステップアッププログラミングのススメ〜
  2. ステップアッププログラミング〜Java FxでHelloWorld解説〜
  3. Java StepUpPrograming〜JavaFX で四則計算〜
  4. Java StepUpPrograming〜JavaFXで画面切り替えを作る1〜
  5. Java StepUpPrograming〜JavaFXで画面切り替え2ボタン作成〜
  6. Java StepUpPrograming〜JavaFXで画面切り替え3アクション〜
  7. Java StepUpPrograming〜JavaFXで画面切り替え4Pane切り替え〜
  8. Java StepUpPrograming〜JavaFXで画面切り替え5WebEngine〜

Git

  1. Java Git clone in Eclipse 〜サンプルの取得〜
  2. Eclipse Gitリポジトリの取得 GitからソースをPullしよう〜
  3. IntelliJ IDEA GitGitリポジトリからクローン〜


JavaFX SceneBuilder〜ボタンにメソッドを割り当てるワンポイント〜

FXMLで追加したボタンに。。。

onAction属性でメソッドを割り当てる。

<FXML>コピーして作成したファイルを開くと上のような画面が見れます。

<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.*?>
<BorderPane prefHeight="186.0" prefWidth="562.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="zenryokuservice.opencv.fx.tutorial2.FourierController">
<left>
<VBox alignment="CENTER">
<padding>
<Insets left="10" right="10" />
</padding>
   <children>
   <ImageView fx:id="originalImage" />
   </children>
</VBox>
</left>
<right>
<VBox alignment="CENTER" spacing="10">
<padding>
<Insets left="10" right="10" />
</padding>
   <children>
   <ImageView fx:id="transformedImage" />
   <ImageView fx:id="antitransformedImage" />
   </children>
</VBox>
</right>
<bottom>
<HBox alignment="CENTER" prefHeight="77.0" prefWidth="582.0" spacing="10">
<padding>
<Insets bottom="25" left="25" right="25" top="25" />
</padding>
   <children>
   <Button alignment="center" onAction="#loadImage" text="Load Image" />
   <Button fx:id="transformButton" alignment="center" disable="true" onAction="#transformImage" prefHeight="27.0" prefWidth="110.0" text="Apply transformation" />
   <Button fx:id="antitransformButton" alignment="center" disable="true" onAction="#antitransformImage" prefHeight="27.0" prefWidth="94.0" text="Apply anti transformation" />
            <Button fx:id="exeButton" mnemonicParsing="false" text="Execute" onAction="#execute" />
            <SplitMenuButton fx:id="selectorBox" mnemonicParsing="false" prefHeight="27.0" prefWidth="93.0" text="Method">
              <items>
                <MenuItem mnemonicParsing="false" text="Action 1" />
                <MenuItem mnemonicParsing="false" text="Action 2" />
              </items>
            </SplitMenuButton>
   </children>
</HBox>
</bottom>
   <top>
      <Label fx:id="messageLbl" alignment="TOP_CENTER" prefHeight="19.0" prefWidth="361.0" textAlignment="CENTER" BorderPane.alignment="CENTER" />
   </top>
</BorderPane>

上の赤い字の部分が追加したコンポーネントです。対象はボタンのみです。

<対象のボタン>

@FXML
private Button exeButton;

<そして対応するメソッド>

/**
* FXMLファイルにこのメソッドをonAction属性に指定している。
*/
@FXML
public void execute() {
System.out.println("Hello JavaFX");
}

<実行結果>

[rakuten ids="dtc:11465875"]

関連ページ一覧

  1. EclipseにSceneBuilderを追加する
  2. JavaFX SceneBuilder 〜EclipseとSceneBuilder連携~
  3. Java 初めてでも大丈夫〜ステップアッププログラミングのススメ〜
  4. ステップアッププログラミング〜Java FxでHelloWorld解説〜

開発環境構築

  1. Java Install Eclipse〜開発ツールのインストール〜
  2. Java OpenCV 環境セットアップ(on Mac)
  3. Eclipse SceneBuilderを追加する
  4. JavaFX SceneBuilder EclipseSceneBuilder連携~