Java
Eclipse
AdventCalendar
JavaFX

航空券予約サイトskyticket(スカイチケット)を運営している株式会社アドベンチャーでございます:bow:

skyticketでは、各種デバイス(パソコン・スマートフォン・タブレット)から、旅行を中心とした予約に関わる様々なサービスを提供しています。

スマートフォン向けアプリも展開しています:iphone:
- App Store
- Google Play

[skyticket:Android版アプリ]
qiita-square

ブルーを基調としたとても爽やかなサイトですね:airplane:
玉城ティナちゃんもとっても素敵:relaxed::relaxed::relaxed:

1. さてなにつくろ

さてこのブルー基調のskyticket:airplane:
アドベントカレンダーネタということで、クリスマスっぽい見た目にしよう思います:christmas_tree:

JavaFXを使って、skyticketのデスクトップアプリ:computer:を作ります。
とは言っても画面表示はwebviewです・・。
キラキラの見た目にするお:star::star::star:

2. 環境

1. OpenJDK 11

2018年9月にリリースされたJava11使います。
https://jdk.java.net/11/

openjdk version "11.0.1" 2018-10-16
OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)

2. OpenJFX 11

Java11からOpenJDKに(OracleJDKにも)同梱されなくなったので別途用意します:computer:

https://openjfx.io/openjfx-docs/
↑環境設定、実行手順が易しく書かれています。Maven Gradleを利用した手順もあります:relaxed:

javafx.version=11.0.1
javafx.runtime.version=11.0.1+1
javafx.runtime.build=1

3. Scene Builder 11

gluonの使います。XML手書きはきついの:older_man_tone1:
Java11向けのRC版出ていたのでコレを使います。
https://gluonhq.com/products/scene-builder/

Version 11.0.0

4. IDE

Eclipse使います。
https://www.eclipse.org/downloads/

Eclipse IDE for Java Developers
Version: 2018-09 (4.9.0)
Build id: 20180917-1800

※あとEclipseプラグインも入れておきます。JavaFXプロジェクトのひな型作ってくれるので楽チン:ok_woman_tone1:

e(fx)clipse 3.4.1

3. つくってみた

1. JavaFXのプロジェクト作成

EclipseでJavaFXプロジェクト作ります。

手順はコチラ (:beach_umbrella:押下で手順が開閉します:beach_umbrella:)

 
・手順1. プロジェクト選択
 
FileNew Project...
image.png
Java FX ProjectNext >
image.png


・手順2. プロジェクト名入力
jjj.png
Project name:applicationNext >


・手順3. Java設定
image.png
ソノママ Next >


・手順4. JavaFX設定
image.png

以下の通り入力して Finish

Project設定 設定値
Application type Desktop
Package Name jp.skytikcet
Declarative UI -
├Language FXML
├Root-Type javafx.scene.layout.AnchorPane
├File Name Skyticket
└Controller Name SkyticketController



・JavaFXプロジェクト作成後のディレクトリ・ファイルの構成

application
│  .classpath
│  .project
│  build.fxbuild
│
├─.settings
│      org.eclipse.jdt.core.prefs
│
├─bin
│  └─jp
│      └─skyticket
│              Main.class
│              SkyticketController.class
│              Skyticket.fxml
│              application.css
│
└─src
    └─jp
        └─skyticket
                Main.java                  
                SkyticketController.java   
                Skyticket.fxml             
                application.css            

2. FXML修正

 
Scene Builder(GUI)使ってSkyticket.fxmlのレイアウト修正をしていきます。
コントローラで操作するためにfx:id(フィールドと対応)とOn Action(メソッドと対応)も併せて設定します。
↓目指すレイアウト構造はこんなん。
image.png

手順はコチラ (:beach_umbrella:押下で手順が開閉します:beach_umbrella:)

 
・手順1. ScreenBuilder起動

Skyticket.fxmlを選択して右クリックからのOpen with ScreenBuilderでScreenBuilderを起動します。
(ScreenBuilderが起動しない場合は、WindowPreferencesJavaFXから「SceneBuilder.exe」までのパス設定をすることで機能するようになります。)
image.png

デフォルトはこのような状態です。
image.png


・ 手順2. AnchorPaneレイアウト
まずはAnchorPaneから。幅と高さを設定します。
デフォルトではリージョンの最小(USE_COMPUTED_SIZE)が設定されているので、これを書き換えます。
スマホっぽいサイズ設定にしました。
image.png

そしてfx:id。コントローラ側でコンポーネントにアクセスするためのidを設定します。
(コントローラからコンポーネントを操作しない場合は設定の必要ありません。)
image.png

※FXMLとコントローラとの紐付けfx:controllerはデフォルトで設定済みです。


・ 手順3.webViewレイアウト
続いてwebView
左のControlsからドラッグ&ドロップで配置します。
image.png

WebViewについても幅と高さを与え、fx:idを設定します。
image.png



・ 手順4.buttonレイアウト
同様に左のControlsからドラッグ&ドロップで配置します。
image.png

同様に幅と高さを与え、fx:idを設定します。
image.png

加えてOn Actionにボタン押下時のイベントハンドラ(メソッド名)を設定します。

残りのボタンも同様に設定します。(雑:older_man_tone1:


・ 最終的なレイアウト
image.png

・最終的なFXML

Skyticket.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.web.WebView?>

<AnchorPane fx:id="ap" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="812.0" prefWidth="375.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="jp.skyticket.SkyticketController">
   <children>
      <WebView fx:id="webView" layoutX="0" layoutY="34.0" prefHeight="802.0" prefWidth="365.0" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
      <Button text="よやく" fx:id="btnToppage" onAction="#toppage" layoutX="0" layoutY="712.0" prefHeight="100.0" prefWidth="125.0" mnemonicParsing="false" />
      <Button text="マイページ" fx:id="btnMypage" onAction="#mypage" layoutX="125.0" layoutY="712.0" prefHeight="100.0" prefWidth="125.0" mnemonicParsing="false"  />
      <Button text="押しちゃダメ" fx:id="btnSetting" onAction="#setting" layoutX="250.0" layoutY="712.0" prefHeight="100.0" prefWidth="125.0" mnemonicParsing="false"  />
   </children>
</AnchorPane>

ここまでレイアウト作成です。

3. CSS修正

続いてCSSを修正します。

application.css
/* 通常スタイル */
.button {
  -fx-border-color: white;
  -fx-background-color: #0896ff;
}
/* クリスマス用スタイル */
.button.christmas {
  -fx-background-color: #b79e00;
  -fx-font-family: 'ふい字'
}

あとwebviewの方の装飾用にskyticket.cssを新規作成します。

4. メイン、コントローラクラスの修正

続いてJavaファイル(主にコントローラ)を修正します。

まずはメインクラス。JavaFXのエントリポイントですね。
ほぼデフォルトままで、シーンのサイズ修正とタイトル設定しただけです。

Main.java
package jp.skyticket;

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.fxml.FXMLLoader;


public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            AnchorPane root = FXMLLoader.load(getClass().getResource("Skyticket.fxml"));
            Scene scene = new Scene(root, 375, 812); // サイズを修正
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setTitle("Merry Christmas!!"); // タイトル設定を追加
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

続いてコントローラクラス。
フィールド(画面コンポーネント)とメソッド(イベント)を記述します。
@FXMLアノテーションを付けることでFXMLと関連付き、コントローラ側で操作可能になります。
(しかしFXMLからコントローラのソース自動生成出来ないのかなぁ:santa_tone2:

SkyticketController.java
package jp.skyticket;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;

public class SkyticketController  {
        // 画面コンポーネント
        @FXML private AnchorPane ap;
        @FXML private WebView webView;
        @FXML private Button btnMypage;
        @FXML private Button btnToppage;
        @FXML private Button btnSetting;

        private WebEngine webEngine;

        /**
         * 初期化
         * ・UAを設定してトップ画面を描画します。
         * 
         * @param event
         */
        @FXML
        private void initialize() {   
            this.webEngine = this.webView.getEngine();
            // スマートフォン用ページ表示したいのでUA設定
            this.webEngine.setUserAgent("Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) CriOS/61.0.3163.73 Mobile/15A372 Safari/602.1");
            this.webEngine.load("https://skyticket.jp");
        }
        /**
         * btnMypage押下時のイベントハンドラ
         * ・マイページを描画します。
         * 
         * @param event
         */
        @FXML
        private void mypage(ActionEvent event) {
            this.webEngine.load("https://skyticket.jp/user/");
        }
        /**
         * btnToppage押下時のイベントハンドラ
         * ・トップ画面を描画します。
         * 
         * @param event
         */
        @FXML
        private void toppage(ActionEvent event) {
            this.webEngine.load("https://skyticket.jp");
        }
        /**
         * btnSetting押下時のイベントハンドラ
         * ・ボタンに装飾用クラスを追加します。
         * ・クリスマス用CSSを適用します。
         * ・トップ画面を描画します。
         * 
         * @param event
         */
        @FXML
        private void setting(ActionEvent event) {
            // 各種ボタンにクリスマス装飾スタイル用のクラスを設定      
            this.btnMypage.getStyleClass().add("christmas");
            this.btnToppage.getStyleClass().add("christmas");
            this.btnSetting.getStyleClass().add("christmas");

            // webviewのクリスマス用CSS適用
            this.webEngine.setUserStyleSheetLocation(getClass().getResource("skyticket.css").toString());

            this.webEngine.load("https://skyticket.jp");
        }
}

以上で作成完了でございます。

4.うごかしてみた

まずは初期表示。
普通にwebview機能しています。
qiita-square

下部のボタン「よやく」 ボタン、「マイページ」ボタンもいい感じ。
普通にチケット申し込みも可能です:airplane:
qiita-square

最後に「押しちゃダメ」ボタン
qiita-square

 
ぜったいに・・・

押しちゃダメ・・・
 
 
 
サンタさんとの

おやくそく
 
 
 
ぜったいに・・・
 


:no_good:ココぜったいに押しちゃにダメだお:no_good_tone3:

 
:christmas_tree::christmas_tree::christmas_tree:Merry Christmas:christmas_tree::christmas_tree::christmas_tree:
qiita-square

出演男優はアドベンのはるたんこと、春木部長です。
おっさんずラブ:heart_eyes::heart_eyes::heart_eyes:

それでは皆さん、良いクリスマスを~:christmas_tree::santa_tone2::christmas_tree:

以上でございます!