Edited at

JavaFXでMerry Christmas!!

航空券予約サイト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:

以上でございます!