VSCode+GradleでJavaFXのHelloWorldを動かすまで

# はじめに
VSCode+GradleでJavaFXを「とりあえず」動かすにはどうしたらいいのかメモ的に書きます。
随所に先人の知恵をコピペしてできましたものです。先人の皆さま、いつもありがとうございます。

# 0. 環境

利用したツールと実行環境は以下のとおりです。

- Linux Mint 19.3
- OpenJDK 11
- OpenJFX 11 (11.0.6)
- VSCode(code) 1.42.1
- Gradle 6.1.1

また、タイトルの部分にフォーカスするため、個々のツールのインストールについては割愛します。

# 1. Gradleでプロジェクトを作成する

プロジェクトディレクトリを作成し、gradle initを実行します(gradleコマンドにパスを通している前提です)。以下のように選択肢に答えていくと出来あがります。

    ximia@thinkpad:~/dev/sandbox02$ gradle init

    Select type of project to generate:
      1: basic
      2: application
      3: library
      4: Gradle plugin
    Enter selection (default: basic) [1..4] 2

    Select implementation language:
      1: C++
      2: Groovy
      3: Java
      4: Kotlin
      5: Swift
    Enter selection (default: Java) [1..5] 3

    Select build script DSL:
      1: Groovy
      2: Kotlin
    Enter selection (default: Groovy) [1..2] 1

    Select test framework:
      1: JUnit 4 VSCode
      2: TestNG
      3: Spock
      4: JUnit Jupiter
    Enter selection (default: JUnit 4) [1..4] 1

    Project name (default: sandbox02): 
    Source package (default: sandbox02): me.osa2.java.sandbox02

    > Task :init
    Get more help with your project: https://docs.gradle.org/6.1.1/userguide/tutorial_java_projects.html

    BUILD SUCCESSFUL in 42s
    2 actionable tasks: 2 executed
    ximia@thinkpad:~/dev/sandbox02$ 

# 2.VSCodeでtasks.jsonを追加する

上で作ったsandbox02ディレクトリをVSCodeのワークスペースにフォルダ追加してから、デフォルトのビルドを実行とします。
が、何を実行したらいいのか分からないVSCodeがConfigを作れと行ってきます(下の図)。画面中央上に表示されている「Configure Build Task...」をクリックします（VSCodeを日本語化とかしている人は、適宜脳内通訳してください）。

![Screenshot at 2020-02-16 18-51-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318338/1d284f4f-2089-8c9c-e107-1cf6c5508e6e.png)

選択肢ではその他を選びます。するとHelloと表示するだけのtasks.jsonがプロジェクトの.vscodeフォルダ下に出来あがります。そこに以下をまるっと全体上書きでコピペします。

```json
{
    "version": "1.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "./gradlew build"
        },
        {
            "label": "run",
            "type": "shell",
            "command": "./gradlew run",
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "clean",
            "type": "shell",
            "command": "./gradlew clean"
        },
        {
            "label": "check",
            "type": "shell",
            "command": "./gradlew check"
        },
        {
            "label": "create-jar",
            "type": "shell",
            "command": "./gradlew jar"
        }
    ]
}
```
保存後に、VSCodeのメニューから Terminal > Run Buld Task... を選択すると下のシェルの画面でごそごそとビルドが走り、Gradleがinit時に用意したコンソールアプリでの"Hello World"が表示されます。
tasks.jsonをみると、gradle runがbuildタスクのデフォルトとなっていることがわかります。

# 3. JavaFXのコードに差し替える

非常に雑ですが、VSCode内でsrc/main/java/(パッケージパス)/App.javaを以下のコードでまるっと上書きし、ファイル名をHelloWorld.javaに変更します。また、src/test以下にあるテスト用のスケルトンもエラーとなるので(ここではテストコードは書かないということで)、削除します。

```java
package your.package.path;
 
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
 
public class HelloWorld extends Application {
    public static void main(String[] args) {
        launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Hello World!");
        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        btn.setOnAction(new EventHandler<ActionEvent>() {
 
            @Override
            public void handle(ActionEvent event) {
                System.out.println("Hello World!");
            }
        });
        
        StackPane root = new StackPane();
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }
}
```
なお、このコードは天下のOracleさまの以下のページからまるっと拝借してまいりました。
https://docs.oracle.com/javafx/2/get_started/hello_world.htm

# 4. VSCode, Gradleそれぞれにクラスパスを通す

まず、build.gradleを以下のようにまるっと置き換え、保存します。mainClassNameは皆さまそれぞれのご都合に合わせて書き換えください。ここまででビルド(gradle run)をすると、JavaFXのアプリが起動されます。アプリのイメージは末尾にあります。

```gradle
/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Java project to get you started.
 * For more details take a look at the Java Quickstart chapter in the Gradle
 * User Manual available at https://docs.gradle.org/6.1.1/userguide/tutorial_java_projects.html
 */

plugins {
    id 'java'
    id 'application'
    id 'eclipse' // for auto-completion enabled .classpath.
    id 'org.openjfx.javafxplugin' version '0.0.8'
}

repositories {
    jcenter()
}

javafx {
    version = "11"
    modules = [ 'javafx.controls']
}

dependencies {
    // This dependency is used by the application.
    implementation 'com.google.guava:guava:28.1-jre'

    // Use JUnit test framework
    testImplementation 'junit:junit:4.12'

    // Making Runnable Jar
    implementation "com.github.jengelman.gradle.plugins:shadow:5.1.0"
}

mainClassName = 'me.osa2.java.sandbox02.HelloWorld'

tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}

jar {
        manifest {
        attributes ('Main-Class': mainClassName, "Implementation-Title": "Gradle",
                "Implementation-Version": 1)
    }
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    from configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
```

次に.vscodeフォルダ(先ほどtasks.jsonを作ったフォルダ)にlaunch.jsonをファイル作成し、以下を中身として、まるっと貼り付けます。メインクラス名、パッケージ名、openjfxのlibのパスは皆さまそれぞれのご都合に合わせて書き換えください。これでVSCodeを起動し直すとソース上で認識不能だった識別子の赤波アンダーラインが消えるはずです。

```json
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "java",
            "name": "Debug (Launch) - Current File",
            "request": "launch",
            "mainClass": "${file}"
        },
        {
            "type": "java",
            "name": "Debug (Launch)-HelloWorld<sandbox02>",
            "request": "launch",
            "mainClass": "me.osa2.java.sandbox02.HelloWOrld",
            "projectName": "hello",
            "vmArgs": "--module-path /home/ximia/libs/javafx-sdk-11.0.2/lib --add-modules javafx.controls,javafx.fxml"
        }
    ]
}
```

# 5. おわりに
Qiitaの他の記事の寄せ集め的で、しかも「まるっとコピペ」ばかりでスミマセン。
![app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318338/b61a59fe-68ea-8750-5bdb-77d65a301b6a.png)
動いてから諸々考えたい人にはよろしいかと。ご参考に慣れば幸いです！:grinning:

== END ==