この記事は Mikatus Advent Calendar 2019 5日目の記事です。
#はじめに
皆さんはお酒が好きですか?
私はお酒が大好きですし、多分お酒も私のことが好き1です。
しかし、昨今の缶チューハイは__某ストロング__を始めとした9%以上のものが増えてきました。
私もついついアルコール度数が高いものを買ってしまいがちですが、健康被害を考えると震え上がってしまい__お酒を飲まなければ眠れない毎日です__。
そんななか、職場の仲間から__「ほろよいで割ればOK」2__と言われその発想に感動すると共に、お酒をお酒で割った時のアルコール度数とは・・・?となったので計算するデスクトップアプリをJavaFXで作ってみました。
#JavaFXとは
以下Wikipediaから引用
JavaFX(ジャバエフエックス)とはJava仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリである。Java SE 7 Update 2以降に標準搭載されている。Swingとは異なり、FXMLと呼ばれるXMLとCSSを併用してデザインを記述する。
ざっくり言うとSwingの後継みたいな感じですかね。
SwingはUIも全部Javaで書かなければいけなくて結構地獄のような感じでしたが、JavaFXではFXMLというファイルにデザインを抽出したのでJavaでUIを書くことはないみたいです。
#環境構築&プロジェクト作成
こちらの記事を参考にさせていただきました。
【超初心者向け】JavaFX超入門
プロジェクト構成、Mainクラスの記述は完全にコピペさせていただきました。
Scene Builderがかなり便利でパーツのドラッグ・アンド・ドロップでUIの構築は終わってしまいました。
こんな感じです。
一つ注意点として上げるならば、JavaSE11からOracleJDKの無償版がなくなりOpenJDKを使用している人が大多数だと思いますが、OpenJDKにはなんとJavaFXが含まれていません。
今回は対応するのも面倒だったのでEclipseでプロジェクトを作成する際Java8を選択しました。
ちなみに対応方法もあるようです。
OpenJFX + OpenJDK で JavaFX を動かす
[OpenJDK 11にJavaFXを導入する]
(https://blogs.osdn.jp/2018/11/12/merge-openjfx.html)
#FXMLをControllerに紐付ける
Scene BuilderでUIを作成して保存するとFXMLファイルで保存されます。
今回作ったFXMLファイルがこちら
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.Pane?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<TextField layoutX="69.0" layoutY="98.0" />
<TextField layoutX="300.0" layoutY="98.0" />
<TextField layoutX="69.0" layoutY="201.0" />
<TextField layoutX="300.0" layoutY="201.0" />
<Button layoutX="503.0" layoutY="201.0" mnemonicParsing="false" text="計算する" />
<Label layoutX="33.0" layoutY="103.0" text="1." />
<Label layoutX="33.0" layoutY="206.0" text="2." />
<Label layoutX="240.0" layoutY="103.0" text="ml" />
<Label layoutX="240.0" layoutY="206.0" text="ml" />
<Label layoutX="471.0" layoutY="103.0" text="\%" />
<Label layoutX="471.0" layoutY="206.0" text="\%" />
<Label layoutX="100.0" layoutY="285.0" prefHeight="48.0" prefWidth="401.0" />
</children>
</Pane>
実際にやりたいこととしては、計算すると言うボタンが押下された際、4つのフォームに入力された値を取得して計算、と言う流れなのでボタン押下や4つのフォームに入力された値をJavaのControllerクラスで受け止められるようfxmlファイルを修正していきます。
そして出来上がったのがこちら
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.Pane?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.AlcoholController">
<children>
<TextField layoutX="69.0" layoutY="98.0" fx:id="amountFst" />
<TextField layoutX="300.0" layoutY="98.0" fx:id="alcoholFst" />
<TextField layoutX="69.0" layoutY="201.0" fx:id="amountSec" />
<TextField layoutX="300.0" layoutY="201.0" fx:id="alcoholSec" />
<Button layoutX="503.0" layoutY="201.0" mnemonicParsing="false" text="計算する" fx:id="button" onAction="#onClick" />
<Label layoutX="33.0" layoutY="103.0" text="1." />
<Label layoutX="33.0" layoutY="206.0" text="2." />
<Label layoutX="240.0" layoutY="103.0" text="ml" />
<Label layoutX="240.0" layoutY="206.0" text="ml" />
<Label layoutX="471.0" layoutY="103.0" text="\%" />
<Label layoutX="471.0" layoutY="206.0" text="\%" />
<Label layoutX="100.0" layoutY="285.0" prefHeight="48.0" prefWidth="401.0" fx:id="result" />
</children>
</Pane>
fx:
で始まるタグが追加されているのがわかると思います。
まず一番大きなパネルの記述部分にfx:controller
でFXMLファイルと紐付けるControllerを記述します。
TextFieldはfx:id
をつけてあげます。これが後にControllerの変数と紐付きます。
ButtonにはonAction
でonClick
を定義してあげます。
これでボタンが押下された際onClickというメソッドが動き出すはずです。
上記FXMLに合わせてControllerを作成します。
package controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
public class AlcoholController implements Initializable {
@FXML
private TextField amountFst;
@FXML
private TextField alcoholFst;
@FXML
private TextField amountSec;
@FXML
private TextField alcoholSec;
@FXML
private Button button;
@FXML
private Label result;
@Override
public void initialize(URL location, ResourceBundle resources) {
}
@FXML
public void onClick(ActionEvent event) {
}
}
こんな感じです。
@FXML
をつけることで先程定義したFXMLファイルと紐づくみたいです。
あとはonClickに簡単な計算を書いて完成です。
これはアルコール9%のロング缶をほろよいで割った時のアルコール度数です。
__極めて健康的な数値__になっているのがわかります。
あとはEclipseから実行可能jarで書き出せば立派なアプリになりますね。
#最後に
Swingを書いた経験もありますが、やはりScene Builderがかなり便利だったのもあってSwingより断然楽でした。
Javaのコード自体もスッキリするので読みやすいですし、__数日間サボって日にちが空いても全然読めました__ね。
今回書いたソースはGithubにあげておくので良かったらご参考までに。
https://github.com/SomeyaHotaka/AlcoholCalc
このアプリで私は健康生活を送っていこうと思います。
それではまた。