うちのゼミの活動を通してわかったことをまとめてマニュアルにしています.
まだ世間では Java は SE 7 が標準なのでしょうか.
Java SE 8 / Java FX 8 に関する情報がまだ世間に少なすぎて,仕方がないので本家ORACLEのサイトを見ながら,サンプルプログラム作って実験しながら自力で使い方を発掘しています.
まだまだ発展途上で,やり残し満載のマニュアルですが,どんどん加筆してゆきます.
PDFで約2.7MBです→javafx_main.pdf
まだクレームをいただけるような状態でもないですが,ご意見いただけたらありがたいです.
→ katsu_wm%mukogawa-u.ac.jp (%を@に変えてください)
【マニュアル中のサンプルプログラム】
● FXsample01.java
● FXsample02.java
● FX3Dsample01.java
● FX3Dsample03.java
貼り付ける画像:texture.gif
● FXMLsample01.fxml
● FXMLsample01.java
● FXMLappl001.java
● FXMLDocumentController.java
● FXMLDocument.fxml
● FXChart01.java
● FXChart02.java
● FXChart03.java
● FXChart04.java
● FXimage01.java
● FXimage02.java
読み込む画像:Earth.jpg
● AnimSample01.java
● FX3Dsample04.java
貼り付ける画像:physical-free-world-map-b1.jpg
● DateTest01.java
● DateTest02.java
● DateTest06.java
● DateTest07.java
● FXsample05.java
● LmbdSample01.java
● SoundTest01.java
● SoundTest02.java
● SoundTest03.java
サウンドサンプル:music001.wav(サイズに注意!:17MB)
(提供元:フリーBGM素材 『霞む道を』 試聴ページ フリーBGM DOVA-SYNDROME)
● GUIdesign01のプロジェクト
● FXsample04.java
—– 目次 —————————————————–
1 はじめに
2 GUI構築の基本
2.1 Applicationクラス
2.2 StageクラスとSceneクラス
2.3 ウィンドウサイズの変更を禁止する設定
2.4 GUIの可視属性の設定
2.5 複数のウィンドウを生成する方法
2.6 アプリケーションの終了に関する処理
2.6.1 アプリケーション終了時に呼び出されるメソッド
3 三次元グラフィックス
3.1 基礎事項
3.2 直方体,円柱,球
3.2.1 シーングラフの準備
3.2.2 Colorクラスによる色の指定
3.2.3 基本的な三次元オブジェクトの扱い
3.2.4 平行移動,回転,拡縮
3.2.5 光源
3.2.6 直投影型カメラ
3.2.7 透視投影型カメラ
3.3 メッシュ・グラフィックス
3.3.1 メッシュへのテクスチャの貼付け
4 FXMLを利用したGUI構築
4.1 サンプルプログラム
4.2 NetBeans IDEの利用
4.2.1 生成された雛形を利用したアプリケーション開発
4.2.2 単独で動作するアプリケーションの生成について
4.3 Java FX Scene Builder
4.3.1 インスペクタ
4.3.2 イベントハンドラとの関連付け
4.3.3 NetBeans IDEとの連携
5 図形の描画
5.1 Shapeを利用した描画
5.1.1 線の描画: Line / Polyline
5.1.2 線に属性を与えるメソッド
5.1.3 図形描画における「枠」と「塗り」
5.1.4 各種図形の描画: Rectangle / Circle / Ellipse / Arc / Polygon
5.1.5 塗りの属性
5.1.6 文字の描画: Text
5.1.6.1 システムで利用できるフォントを調べる方法
5.1.7 画像の表示: ImageView
5.1.8 Shapeオブジェクトの位置の設定: relocate
5.2 Canvasを利用した描画
5.2.1 GraphicsContext
5.2.2 各種の描画メソッド
5.3 チャートの描画
5.3.1 棒グラフ:BarChart
5.3.2 折れ線グラフ:LineChart
5.3.3 円グラフ:PieChart
5.4 画像データの扱い
5.4.1 画像データの入力: Imageクラス
5.4.2 画素(ピクセル)の操作
5.4.3 画像データの出力
5.4.4 サンプルプログラム
5.4.5 ノードの描画状態のキャプチャ
6 時間によるイベント処理(アニメーション)
6.1 タイミング・イベントについて
6.2 タイムラインとキーフレーム
6.3 サンプルプログラム
7 日付と時刻
7.1 旧来のAPI(Java SE 7)
7.1.1 日付と時刻のためのクラス
7.2 新しいAPI(Java SE 8)
7.2.1 基本的なクラス
7.2.2 日付・時刻に関する基本的な処理
7.2.3 和暦の扱い
8 ラムダ式
8.1 イベントハンドラ登録への応用
8.2 関数型インターフェースでの応用
9 サウンドの再生(Java SE 7)
9.1 基礎事項
9.2 実用的なサウンド再生
10 メディアデータの再生(Java FX 8)
10.1 動画再生に関すること
11 付録
11.1 Java FXで利用できるGUIの部品(代表的なもの)
11.1.1 コンテナ:Containers
11.1.1.1 HBox,VBoxを用いたGUIの配置
11.1.2 コントロール:Controlls
11.1.2.1 項目データを与える方法
11.1.3 値の変化を検知するイベント
11.2 メニューの構築
11.3 ファイル選択ダイアログの実装
11.4 Java FX 8 の重要なクラス
11.5 イベントについて
11.5.1 旧来のGUIで扱うイベント
11.5.2 タッチデバイスで扱うイベント
—————————————————————-
「Java」カテゴリーアーカイブ
超入門:立体の表示,回転と平行移動,カメラ,光源の基本
超入門:立体の表示,回転と平行移動,カメラ,光源の基本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | import javafx.application.Application; import javafx.scene.*; import javafx.scene.layout.*; import javafx.scene.paint.*; import javafx.stage.Stage; import javafx.scene.shape.*; import javafx.scene.transform.*; import javafx.geometry.Point3D; public class FX3Dsample01 extends Application { @Override public void start(Stage Stage) { //--- Top Node and Scene --- Group root = new Group(); Scene scene = new Scene(root, 1024, 768, Color.rgb(0,0,0)); // Axis for Rotation Point3D aX = new Point3D(100,0,0); Point3D aY = new Point3D(0,100,0); Point3D aZ = new Point3D(0,0,100); //--- Solid Model Generation --- // (Box) Box bx1 = new Box(300d,200d,150d); root.getChildren().add(bx1); PhongMaterial mt1 = new PhongMaterial(); // 別々に作る! mt1.setDiffuseColor(Color.rgb(255,0,0)); bx1.setMaterial(mt1); bx1.getTransforms().addAll( new Translate(-300d,0d,0d), // 先に平行移動 new Rotate(30,aX), new Rotate(30,aY), new Rotate(20,aZ) ); // (Cylinder) Cylinder cl1 = new Cylinder(80d,300d); root.getChildren().add(cl1); PhongMaterial mt2 = new PhongMaterial(); // 別々に作る! mt2.setDiffuseColor(Color.rgb(0,255,0)); cl1.setMaterial(mt2); cl1.getTransforms().addAll( new Rotate(30,aX), new Rotate(0,aY), new Rotate(-20,aZ) ); // (Sphere) Sphere sp1 = new Sphere(140d); root.getChildren().add(sp1); PhongMaterial mt3 = new PhongMaterial(); // 別々に作る! mt3.setDiffuseColor(Color.rgb(0,0,255)); sp1.setMaterial(mt3); sp1.getTransforms().addAll( new Translate(280d,0d,0d) ); //--- Light Setting --- AmbientLight aLight = new AmbientLight(Color.rgb(127, 127, 127)); root.getChildren().add(aLight); PointLight pLight = new PointLight(Color.rgb(255,255,255)); pLight.setTranslateX(500d); pLight.setTranslateY(-300d); pLight.setTranslateZ(-200d); root.getChildren().add(pLight); //--- Camera Setting --- ParallelCamera cmr = new ParallelCamera(); cmr.getTransforms().addAll( new Translate(-512d,-384d,0d) ); scene.setCamera(cmr); //--- Window Activation --- Stage.setTitle("FX3Dsample01"); Stage.setScene(scene); Stage.show(); } public static void main(String[] args) { launch(args); } } |
Java FX による3次元CG作成入門
マニュアルをまとめつつあります.
■ 超入門: 立体の表示,回転と平行移動,カメラ,光源の基本
FXMLアプリケーション構築例(NetBeans IDE & Java FX Scene Builder)
(マニュアルをまとめつつあります.)
ここでは,NetBeansIDEとJava FX Scene Builerを用いた画像ビューワのアプリ構築の例を紹介します.
1. 新規プロジェクトの作成(FXMLappl01)
「Java FX FXMLアプリケーション」を選択します.
「プロジェクト名」と「FXML名」を設定します.
空のFXMLを追加します.
FXMLファイルの名前を指定します.
ここでは既存のFXMLコントローラを使うことにします.
FXMLのコード:FXML1.fxml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version="1.0" encoding="UTF-8"?> <?import java.lang.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <AnchorPane id="AnchorPane" prefHeight="92.0" prefWidth="243.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="fxmlappl01.FXML1Controller"> <children> <Button fx:id="btn1" layoutX="36.0" layoutY="33.0" mnemonicParsing="false" onAction="#handleButton_btn1" prefHeight="26.0" prefWidth="172.0" text="Open Another Window" /> </children> </AnchorPane> |
FXMLのコード:FXML2.fxml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?xml version="1.0" encoding="UTF-8"?> <?import java.lang.*?> <?import javafx.scene.control.*?> <?import javafx.scene.image.*?> <?import javafx.scene.layout.*?> <AnchorPane id="AnchorPane" prefHeight="482.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="fxmlappl01.FXML1Controller"> <children> <Button fx:id="btn21" layoutX="14.176322937011719" layoutY="1.0" mnemonicParsing="false" onAction="#handleButton_btn21" text="image 1" /> <Button fx:id="btn22" layoutX="88.17632293701172" layoutY="1.0" mnemonicParsing="false" onAction="#handleButton_btn22" text="image 2" /> <Button fx:id="btn23" layoutX="163.17632293701172" layoutY="1.0" mnemonicParsing="false" onAction="#handleButton_btn23" text="erase" /> <ImageView fx:id="iv1" fitHeight="437.0" fitWidth="574.0" layoutX="14.0" layoutY="35.0" pickOnBounds="true" preserveRatio="true" /> </children></AnchorPane> |
ファイル:FXMLappl01.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | package fxmlappl01; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.stage.Stage; public class FXMLappl01 extends Application { public static Stage stage2; @Override public void start(Stage stage) throws Exception { Parent root = FXMLLoader.load(getClass().getResource("FXML1.fxml")); Scene scene = new Scene(root); stage.setTitle("Main Window"); stage.setScene(scene); stage.show(); /* Another Window */ stage2 = new Stage(); stage2.initOwner(stage); Parent root2 = FXMLLoader.load(getClass().getResource("FXML2.fxml")); Scene scene2 = new Scene(root2); stage2.setTitle("Picture Window"); stage2.setScene(scene2); stage2.show(); /* image from "http://www.ashinari.com/" */ Share.img1 = new Image(getClass().getResourceAsStream("1.jpg")); Share.img2 = new Image(getClass().getResourceAsStream("2.jpg")); } public static void main(String[] args) { launch(args); } } |
ファイル:Share.java
1 2 3 4 5 6 7 | package fxmlappl01; import javafx.scene.image.*; public class Share { public static Image img1, img2; } |
ファイル:FXML1Controller.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | package fxmlappl01; import java.net.URL; import java.util.ResourceBundle; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.*; import javafx.scene.image.*; public class FXML1Controller implements Initializable { @FXML private Button btn1, btn21, bnt22, btn23; @FXML private ImageView iv1; @FXML private void handleButton_btn1(ActionEvent ev) { System.out.println("Open Another Window!"); FXMLappl01.stage2.show(); } @FXML private void handleButton_btn21(ActionEvent ev) { iv1.setImage(Share.img1); } @FXML private void handleButton_btn22(ActionEvent ev) { iv1.setImage(Share.img2); } @FXML private void handleButton_btn23(ActionEvent ev) { iv1.setImage(null); } @Override public void initialize(URL url, ResourceBundle rb) { // TODO } } |
このアプリを実行したところ:
プロジェクト全体(Zip圧縮):FXMLappl01.zip
アプリケーションプログラムを作るには
プログラミング言語の最終的な目的は,アプリケーションプログラムの作成です.
いわゆる「アプリ」を作るのが目的です.
ここではJavaで実現するアプリにはどのような形があるのかを紹介します.
● コマンドとしてアプリを作る
Windowsのコマンドプロンプトウィンドウ(Macの場合はターミナルウィンドウ)で実行するプログラムで,基本的にはグラフィックスは扱いません.これの実現は最も手軽で,標準入力(System.inなど)からユーザの操作を受付,標準出力(System.outなど)に対してメッセージを表示するスタイルです.
● アプレットを作る
Webブラウザ上で実行するプログラムで,HTMLコンテンツの中に埋め込んで使います.
● GUIアプリを作る (1) : Swingの利用
● GUIアプリを作る (2) : SWTの利用
● GUIアプリを作る (3) : FXの利用
日付と時間(2)
「日付と時刻」をデータとして扱う方法です.Date クラスのオブジェクトは生成時にその時点の日付&時刻を取得しますが,ここで紹介する Calendar クラスのオブジェクトは日付&時刻を1つのデータと見て日数計算(「〜日あと」とか「〜週間前」,「〜時間後」とかの計算)をするためのものです.
下のサンプルプログラム “CalendarTest1.java” では最初に「2014/01/01,00:00:00」の日付をデータとして用意して「〜日後」「〜時間後」のような計算をしている例です.
set() メソッドで日付や時刻を設定し,add() メソッドで日数や時間を加算し,get() メソッドで日付や時刻を取り出します.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | import java.util.*; class CalendarTest1 { public static void main( String argv[] ) { int y, m, d, wd2, h, min, sec; Calendar cal = Calendar.getInstance(); String wd[] = { "日", "月", "火", "水", "木", "金", "土" }; /* 2014/01/01, 00:00:00 */ cal.set(Calendar.YEAR,2012); cal.set(Calendar.MONTH,1-1); cal.set(Calendar.DATE,1); cal.set(Calendar.HOUR_OF_DAY,0); cal.set(Calendar.MINUTE,0); cal.set(Calendar.SECOND,0); /* after 86,400 seconds */ cal.add(Calendar.SECOND,86400); y = cal.get(Calendar.YEAR); m = cal.get(Calendar.MONTH) + 1; d = cal.get(Calendar.DATE); wd2 = cal.get(Calendar.DAY_OF_WEEK) - 1; System.out.printf("%d/%02d/%02d(%s)\n",y,m,d,wd[wd2]); /* after 12 Months */ cal.add(Calendar.MONTH,12); y = cal.get(Calendar.YEAR); m = cal.get(Calendar.MONTH) + 1; d = cal.get(Calendar.DATE); wd2 = cal.get(Calendar.DAY_OF_WEEK) - 1; System.out.printf("%d/%02d/%02d(%s)\n",y,m,d,wd[wd2]); /* after 28 Days */ cal.add(Calendar.DATE,28); y = cal.get(Calendar.YEAR); m = cal.get(Calendar.MONTH) + 1; d = cal.get(Calendar.DATE); wd2 = cal.get(Calendar.DAY_OF_WEEK) - 1; System.out.printf("%d/%02d/%02d(%s)\n",y,m,d,wd[wd2]); /* after 24 Hours */ cal.add(Calendar.HOUR_OF_DAY,24); y = cal.get(Calendar.YEAR); m = cal.get(Calendar.MONTH) + 1; d = cal.get(Calendar.DATE); wd2 = cal.get(Calendar.DAY_OF_WEEK) - 1; System.out.printf("%d/%02d/%02d(%s)\n",y,m,d,wd[wd2]); /* after 31,536,000 Seconds */ cal.add(Calendar.SECOND,31536000); y = cal.get(Calendar.YEAR); m = cal.get(Calendar.MONTH) + 1; d = cal.get(Calendar.DATE); wd2 = cal.get(Calendar.DAY_OF_WEEK) - 1; System.out.printf("%d/%02d/%02d(%s)\n",y,m,d,wd[wd2]); } } |
このプログラムを実行すると,次のような内容が表示されます.
2012/01/02(月) 2013/01/02(水) 2013/01/30(水) 2013/01/31(木) 2014/01/31(金) |
文字列⇔数値の変換
int, long, double といった数値の型の変数と文字列(String)オブジェクトの間で値の変換をすることは,実際のプログラミングでよく行われます.
数値から文字列に変換するには valueOf() メソッドを使います.また逆に文字列として表現されている数値を解釈して int, long, double などの型の変数に値を入れるには parse型名() メソッドを用います.
これらのメソッドを用いたサンプルを “valueConv1.java” に示します.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class valueConv1 { public static void main( String argv[] ) { int i = 1; long l = 2; double f = 3.4; String is, ls, fs; is = String.valueOf(i); // int -> String ls = String.valueOf(l); // long -> String fs = String.valueOf(f); // double -> String System.out.printf("\'%s\' , \'%s\' , \'%s\'\n",is,ls,fs); i = Integer.parseInt(is); // String -> int l = Long.parseLong(ls); // String -> long f = Double.parseDouble(fs); // String -> double System.out.printf("%d , %d , %.1f\n",i,l,f); } } |
これを実行すると次のような表示になります.
'1' , '2' , '3.4' 1 , 2 , 3.4 |
オブジェクトのクラスを調べる方法
オブジェクトが属するクラスを調べる方法です.
getClass() メソッドでクラス情報を取得して,それに対して getName() メソッドをを実行することで,オブジェクトが属するクラスの名前を文字列(String)オブジェクトとして取得することができます.
次のサンプルプログラム “ClassCheck1.java” はそれを実行する例です.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class TestClass { } class ClassCheck1 { public static void main( String argv[] ) { String name = "test"; TestClass o = new TestClass(); name = o.getClass().getName(); System.out.println(name); name = name.getClass().getName(); System.out.println(name); } } |
このプログラムを実行すると,次のような表示になります.
TestClass java.lang.String |
ファイルへの出力:テキストファイル
ファイルへの出力の方法です.
ここでは,テキストファイルとしてデータを出力する方法を紹介します.
【基本】
次のプログラム “FileWrite1.java” はファイル “text2.txt” に対してテキストデータを出力する例です.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import java.io.*; class FileWrite1 { public static void main( String argv[] ) { FileWriter fw; try { fw = new FileWriter("text2.txt"); fw.write("This is an output data from\n"); fw.write("FileWrite1.\n"); fw.write("日本語の出力です.\n"); fw.close(); } catch( IOException e ) { } } } |
ファイルを FileWriter というクラスのオブジェクトとして生成しています.これを実行すると,ファイル “text2.txt” に次のような内容が書き込まれます.
This is an output data from FileWrite1. 日本語の出力です. |
【便利な方法】
FileWriter を元に PrintWriter というクラスのオブジェクトを生成すると,それに対して print, println, printf といった出力用のメソッドを用いて内容を出力することができます.次のプログラム “FileWrite2.java” は printf メソッドを用いて書式を指定して正弦関数の定義域と値域を出力する例です.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import java.io.*; class FileWrite2 { public static void main( String argv[] ) { FileWriter fw; PrintWriter pw; try { fw = new FileWriter("text3.txt"); pw = new PrintWriter(fw); double x, y; for ( x = 0.0; x < 6.3; x += 0.1 ) { y = Math.sin(x); pw.printf("sin(%.1f) = %.10f\n",x,y); } fw.close(); } catch( IOException e ) { } } } |
これを実行すると,ファイル “text3.txt” に次のような内容が出力されます.
sin(0.0) = 0.0000000000 sin(0.1) = 0.0998334166 sin(0.2) = 0.1986693308 sin(0.3) = 0.2955202067 sin(0.4) = 0.3894183423 (以下省略) |
日付と時間
Javaには日付と時間(時刻)のデータを扱うための高度な機能があります.
ただ,初心者には理解し難いものもあるので,ここでは素朴な例を挙げます.
Javaのクラスライブラリに Date というクラスがあり,このクラスのインスタンスを new で生成すると,現在の日付と時刻に関するデータを保持するオブジェクトができます.
下の例 “DateTest1.java” では年,月,日,曜日,時,分,秒を手軽に取り出すメソッドを備えたクラス Date2(Dateクラスの拡張)を実装しています.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | import java.util.*; import java.text.*; class Date2 extends Date { /*--------------------------------------* * constructor * *--------------------------------------*/ Date2(int year, int month, int day) { } Date2() { } /*--------------------------------------* * methods * *--------------------------------------*/ /* Date2 -> Year */ public int Date2Year() { int y; SimpleDateFormat f; f = new SimpleDateFormat("yyyy"); y = Integer.parseInt(f.format(this)); return( y ); } /* Date2 -> Month */ public int Date2Month() { int m; SimpleDateFormat f; f = new SimpleDateFormat("MM"); m = Integer.parseInt(f.format(this)); return( m ); } /* Date2 -> Day */ public int Date2Day() { int d; SimpleDateFormat f; f = new SimpleDateFormat("dd"); d = Integer.parseInt(f.format(this)); return( d ); } /* Date2 -> Week day */ public String Date2WDay() { String wd; SimpleDateFormat f; f = new SimpleDateFormat("E"); wd = f.format(this); return( wd ); } /* Date2 -> Hour */ public int Date2Hour() { int h; SimpleDateFormat f; f = new SimpleDateFormat("hh"); h = Integer.parseInt(f.format(this)); return( h ); } /* Date2 -> Minute */ public int Date2Min() { int m; SimpleDateFormat f; f = new SimpleDateFormat("mm"); m = Integer.parseInt(f.format(this)); return( m ); } /* Date2 -> Second */ public int Date2Sec() { int s; SimpleDateFormat f; f = new SimpleDateFormat("ss"); s = Integer.parseInt(f.format(this)); return( s ); } } class DateTest1 { public static void main( String argv[] ) { int y,m,day,h,min,sec; String wd; Date2 d = new Date2(); // 現在の日付,時刻の取得 y = d.Date2Year(); // 年の取得 m = d.Date2Month(); // 月の取得 day = d.Date2Day(); // 日の取得 wd = d.Date2WDay(); // 曜日の取得 h = d.Date2Hour(); // 時の取得 min = d.Date2Min(); // 分の取得 sec = d.Date2Sec(); // 秒の取得 System.out.printf("%d/%d/%d (%s), %s:%s:%s\n", y,m,day,wd,h,min,sec); } } |
このプログラムを実行すると,その時の日付と時刻を表示します.
ファイルの読込み:テキストファイル
テキストファイルを読み込む方法です.
基本的にファイルは入力ストリームなので,内容は先頭から順番に読み込まれます.
ここでは次の3つの方法を順番に説明します.
1) ファイルから「1バイトづつ」読み込む方法
2) ファイルから「1文字(多国語含む)づつ」読み込む方法
3) ファイルから「1行づつ」読み込む方法
次ような内容のファイル “text1.txt” があるものとして,この内容を読み込む方法を説明します.
1 2 3 | Alphabet 日本語 English and 日本語 混在 |
【ファイルから「1バイトづつ」読み込む方法】
ファイルを FileInputStream として開き,それに対して read() メソッドを実行すると1バイトづつ読み込むことができます.読み取ったデータは int 型整数として与えられます.(下記:”FileRead1.java”)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import java.io.*; class FileRead1 { public static void main( String argv[] ) { FileInputStream fi; int c, i = 0; try { fi = new FileInputStream("text1.txt"); while ( (c = fi.read()) != -1 ) { i++; System.out.println( i+":"+(char)c ); } fi.close(); } catch( IOException e ) { System.out.println("ファイルがオープンできません\n"); System.exit(-1); } } } |
この方法は最も基本的ですが,1バイトづつ読むため能率がよくありません.また多バイトからなる多国語文字を認識しないため実行すると文字化けが起こります.実行結果の表示を下に示します.
1:A 2:l 3:p 4:h 5:a 6:b 7:e 8:t 9: 10:æ 11: 12:¥ 13:æ 14: 15:¬ 16:è 17:ª 18: 19: 20:E 21:n 22:g 23:l 24:i 25:s 26:h 27: 28:a 29:n 30:d 31: 32:æ 33: 34:¥ 35:æ 36: 37:¬ 38:è 39:ª 40: 41:ã 42: 43: 44:æ 45:· 46:· 47:å 48: 49:¨ 50: |
【ファイルから「1文字(多国語含む)づつ」読み込む方法】
入力するデータを「文字データ」として認識して1文字づつ読み取る方法です.ファイルを FileInputStream として開き,更にそれを元にして InputStreamReader というオブジェクトを生成し,それに対して read() メソッドを実行すると「1文字づつ」読み込むことができます.読み取ったデータは int 型整数として与えられます.(下記:”FileRead2.java”)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import java.io.*; class FileRead2 { public static void main( String argv[] ) { FileInputStream fi; InputStreamReader isr; int c, i = 0; try { fi = new FileInputStream("text1.txt"); isr = new InputStreamReader(fi,"UTF-8"); while ( (c = isr.read()) != -1 ) { i++; System.out.println( i+":"+(char)c ); } fi.close(); } catch( IOException e ) { System.out.println("ファイルがオープンできません\n"); System.exit(-1); } } } |
この方法では多バイトからなる多国語文字を認識するため,文字化けは起こりません.実行結果の表示を下に示します.
1:A 2:l 3:p 4:h 5:a 6:b 7:e 8:t 9: 10:日 11:本 12:語 13: 14:E 15:n 16:g 17:l 18:i 19:s 20:h 21: 22:a 23:n 24:d 25: 26:日 27:本 28:語 29: 30:混 31:在 32: |
また,ファイルを FileReader として開いてそれに対して read() メソッドを実行する方法(下記;”FileRead3.java”)もあり,同じ結果を得ることができます.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import java.io.*; class FileRead3 { public static void main( String argv[] ) { FileReader fr; int c, i = 0; try { fr = new FileReader("text1.txt"); while ( (c = fr.read()) != -1 ) { i++; System.out.println( i+":"+(char)c ); } fr.close(); } catch( IOException e ) { System.out.println("ファイルがオープンできません\n"); System.exit(-1); } } } |
【ファイルから「1行づつ」読み込む方法】
おそらく一番実用的な方法かと思います.テキストファイルを「1行づつ」読み取って String クラスの文字列オブジェクトとして取り出す方法です.(下記:”FileRead4.java”)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import java.io.*; class FileRead4 { public static void main( String argv[] ) { FileReader fr; int i = 0; String b; try { fr = new FileReader("text1.txt"); BufferedReader br = new BufferedReader(fr); while ( (b = br.readLine()) != null ) { i++; System.out.println( i+":"+b ); } fr.close(); } catch( IOException e ) { System.out.println("ファイルがオープンできません\n"); System.exit(-1); } } } |
これを実行すると次のようになります.
1:Alphabet 2:日本語 3:English and 日本語 混在 |
【コンマ区切りの文字列(CSVデータ)の分離】
コンマ区切りデータ(CSVデータ)を1行づつ読み取った場合に,その行をコンマ毎に区切ってバラバラの文字列にする方法を説明します.今回例に使用するのは,総務省が配布する「標準地域コード」です.このデータは次のように8つの項目からなり,それをCSVデータにしたファイル “ChiikiCode.csv” を読み込む例です.
1. 都道府県コード
2. 市町村コード
3. 地域コード
4. 都道府県名
5. 市町村名1
6. 市町村名2
7. 市町村名3
8. 読みがな
このファイルの内容は次のようなものです.
1,0,1000,北海道,,,,ほっかいどう 1,100,1100,北海道,札幌市,,,さっぽろし 1,101,1101,北海道,札幌市,,中央区,ちゅうおうく 1,102,1102,北海道,札幌市,,北区,きたく (以下省略) |
このデータを読み取って,3〜8の項目を表示するプログラム “CSVtest1.java” を下に示します.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | import java.io.*; class CSVtest1 { public static void main( String argv[] ) { FileReader fr; int i = 0; String b; String csv[] = new String[20]; try { fr = new FileReader("ChiikiCode.csv"); BufferedReader br = new BufferedReader(fr); while ( (b = br.readLine()) != null ) { i++; csv = b.split(","); System.out.print("("+i+")"); System.out.printf("\t地域コード: %s\n",csv[2]); System.out.printf("\t%s%s%s%s",csv[3],csv[4],csv[5],csv[6]); System.out.printf("(%s)\n",csv[7]); } fr.close(); } catch( IOException e ) { System.out.println("ファイルがオープンできません\n"); System.exit(-1); } } } |
このプログラムを実行した様子を下に示します.
(1) 地域コード: 1000 北海道(ほっかいどう) (2) 地域コード: 1100 北海道札幌市(さっぽろし) (3) 地域コード: 1101 北海道札幌市中央区(ちゅうおうく) (4) 地域コード: 1102 北海道札幌市北区(きたく) (以下省略) |
JavaFX GUIアプリ構築入門(NetBeans IDE)
(マニュアルをまとめつつあります.)
実用的なGUIアプリを構築するにはボタンやメニューを始めとする各種のコントロール(GUI部品)を多数使用しますが,それらを全て手作業でコーディング(プログラムのソースコードの手入力)するのはとても煩わしく,生産的ではありません.
統合開発環境(IDE)と呼ばれるツールを用いることで直感的にGUIを構築することができ,それに対応するコースコードを自動的に生成することができます.ここでは NetBeans IDE というツールを用いて手軽にGUIアプリを構築する手順を紹介します.
NetBeans IDEはこのサイトからダウンロードできます.
またGUIを直感的に構築・編集するためには JavaFX SceneBuilder も入手してインストールしておく必要があります.(入手はこちら)
【プログラム作成手順】
NetBeans IDEを起動して「ファイル」→「新規プロジェクト」を選びます.(下図参照)
次に,下のような表示になるので,「カテゴリ」から「JavaFX」を選択し,「プロジェクト」から「JavaFX FXMLアプリケーション」を選んで「次へ」ボタンをクリックします.
次に,下のような表示になるので,プロジェクト名やプロジェクトに関連するファイル群を保存する場所などを設定して「終了」ボタンをクリックします.
プロジェクトとはプログラム開発作業に関連するファイルや設定などをまとめたものだと考えてください.1つの開発単位は1つのプロジェクトとして1つのフォルダにまとめて保存されます.この例では “JavaFXMLApplication1” という名前のプロジェクトを作成しています.
以上の作業で新規プロジェクトの作成が完了してプログラムの開発作業が可能になります.(下のような表示となります)
プロジェクトを作成して開発準備が整うと最初の段階で次のようなファイル群が生成されます.
- mainメソッドを収めたアプリケーションの最上位のソースコード
プロジェクト名と同じ名前のソースファイルが生成されます.上の例では “JavaFXMLApplication1.java” というソースファイルが生成されます. - GUIを記述するFXMLファイル
JavaFXではXML形式(FXML形式)でGUIを構築することができ,デフォルトでは “FXMLDocument.fxml” という名前のファイルが生成されます. - GUIのイベントハンドリングのためのソースコード
GUIからのイベントを受けて起動するメソッド群を記述するソースコードで,デフォルトでは “FXMLDocumentController.java” という名前のファイルが生成されます.
プロジェクト生成直後は,サンプルとして1つのボタンのみを備えたGUIのアプリケーションのためのソースコードになっており,これを改造して独自のアプリケーションに仕上げていきます.
GUIの追加とイベントハンドリングの記述:
NetBeans IDEの「プロジェクト」タブからFXMLファイルをダブルクリックすると JavaFX SceneBuilder が起動してGUIの編集が始まります.(下図)
例えばこのインターフェースにメニューバーを取り付け,「File」メニューの「Close」を選択するとプログラムが終了するようなアプリケーションに改造してみます.
- ステップ1: メニューバーの取り付け
SceneBuilderウィンドウの左端の「Control」の中から「MenuBar」を選び,これをGUIの上にドラッグ&ドロップするとメニューバーが設置できます.(下図)
- ステップ2: メニューとメニュー項目の取り付け
ウィンドウ左端の「Menu」から「Menu」や「MenuItem」を選んでメニューバーに取り付けていきます.この例では,予め登録されているメニュー項目「Close」があるので,取り付け作業の説明は省略します. - ステップ3: GUIへのイベントハンドリングの登録
GUIのメニューバーを選択しておき,ウィンドウ左端の「Hierarchy」の中から「MenuItem Close」を選択します.次にウィンドウ右端の「Code : MenuItem」の中にある該当イベントの部分(この例では「OnAction」)に,そのイベントが起こったときに起動するメソッドの名前を入力します.この例では「Close」を選択したときに “QuitAction” というメソッドが起動するように設定しています. - ステップ4: ソースコードの追加
”FXMLDocumentController.java” の中に,イベントに対応して起動するメソッドを記述します.この例では「QuitAction」というメソッドの記述を追加しています.
以上の作業で出来上がったコードを下に示します.
ソースコード “JavaFXMLApplication1.java”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package javafxmlapplication1; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class JavaFXMLApplication1 extends Application { @Override public void start(Stage stage) throws Exception { Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml")); Scene scene = new Scene(root); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } } |
FXMLのコード “FXMLDocument.fxml”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <?xml version="1.0" encoding="UTF-8"?> <?import java.lang.*?> <?import java.util.*?> <?import javafx.scene.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="javafxmlapplication1.FXMLDocumentController"> <children> <Button fx:id="button" layoutX="126" layoutY="90" onAction="#handleButtonAction" text="Click Me!" /> <Label fx:id="label" layoutX="126" layoutY="120" minHeight="16" minWidth="69" /> <MenuBar layoutY="2.0" prefHeight="25.0" prefWidth="320.0"> <menus> <Menu mnemonicParsing="false" text="File"> <items> <MenuItem mnemonicParsing="false" onAction="#QuitAction" text="Close" /> </items> </Menu> <Menu mnemonicParsing="false" text="Edit"> <items> <MenuItem mnemonicParsing="false" text="Delete" /> </items> </Menu> <Menu mnemonicParsing="false" text="Help"> <items> <MenuItem mnemonicParsing="false" text="About" /> </items> </Menu> </menus> </MenuBar> </children> </AnchorPane> |
イベントハンドリングのためのソースコード “FXMLDocumentController.java”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | package javafxmlapplication1; import java.net.URL; import java.util.ResourceBundle; import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Label; public class FXMLDocumentController implements Initializable { @FXML private Label label; @FXML private void handleButtonAction(ActionEvent event) { System.out.println("You clicked me!"); label.setText("Hello World!"); } @FXML private void QuitAction(ActionEvent event) { System.out.println("You Selected Quit from menu."); Platform.exit(); } @Override public void initialize(URL url, ResourceBundle rb) { // TODO } } |
上のコードに追加したイベント用のメソッド「QuitAction」の中の Platform.exit(); という記述はアプリケーションの終了処理を行うものです.
注意: FXMLで構築したコントロール(GUI部品)はこのクラス内のオブジェクトとして宣言する必要があり,宣言文の直前にはアノテーション「@FXML」を記述する必要があります.
【プログラムの実行】
作成したプログラムを実行するには,NetBeans IDEのメニュー「実行」から「プロジェクト…を実行」を選びます.(下図)
するとプログラムがコンパイルされて実行されます.(下図)
【アプリケーションのビルド】
作成したプログラムを,単体で実行できるパッケージにビルドするには,NetBeans IDEのメニュー「実行」から「プロジェクト…をビルド」を選びます.(下図)
この操作によって,ビルドされたパッケージが “.jar” という拡張子のついたファイルとして,プロジェクトフォルダ内の “dist” フォルダの中に生成されます.(下図)
このjarファイルはダブルクリックで実行を開始することができます.
——————————————————-
● FXMLアプリケーション構築例(NetBeans IDE & Java FX Scene Builder)
画像ビューワ(複数ウィンドウを持つアプリ)
JavaFX GUIアプリ構築入門
(マニュアルをまとめつつあります.)
JavaFXによるGUIアプリ構築の入門です.
【基本1】
・ JavaFXアプリは Application クラスの拡張クラスとして作成する.
・ mainの中で launch メソッドを呼び出すことでGUIアプリが開始する.
・ launchメソッドは start メソッドを呼び出す.startメソッドの中で具体的にGUIを構築する.
サンプルプログラム:
サンプルプログラム “JavaFXApplicationSample1.java” を次に示します.これは非常に単純なGUIアプリのサンプルで,「”Say ‘Hello World'”」ボタンをクリックすると “Hello World!” を標準出力(コマンド画面)に表示するだけです.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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 JavaFXApplicationSample1 extends Application { @Override public void start(Stage primaryStage) { 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); Scene scene = new Scene(root, 300, 250); primaryStage.setTitle("Hello World!"); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } } |
これをコンパイルして実行した例を次に示します.
サンプル “JavaFXApplicationSample1.java” でのGUI構築の流れ:
GUIのインスタンスは Pane (ペイン)と呼ばれる「台紙」のようなものの上に取り付けて行きます.Paneには特徴がそれぞれ異なる複数のクラスがあり,例のプログラムでは StackPane というクラスのインスタンス “root” を生成して,それをGUIの「台紙」にしています.また複数のPaneを階層構造で管理することができます.
例のプログラムでは root に対して予め生成しておいたボタン “btn” を下位のオブジェクトとして登録して取り付けています.ボタンにイベントを登録するために setOnAction メソッドを使用しています.
————————————————————————-
【JavaFXアプリ構築の考え方】
JavaFXアプリは Stage の上に構築される世界です.すなわち,Stage の上にウィンドウとなる Pane オブジェクトを配置して,それをアプリのGUIとします.
Stage は Pane オブジェクト毎に設置します.すなわち,複数の Pane オブジェクトを用いる場合は,そのオブジェクト毎に Stage を生成し,それらを最初の Stage の配下に配置します.(initOwnerメソッドを使って Stage の上下関係を結びます)
Paneオブジェクトの配下に Controlls(GUI部品群)を配置する空間が Scene です.Scene オブジェクトは Pane オブジェクト毎に生成します.
あとは,Pane オブジェクトに必要なコントロール(GUI部品)群を登録します.
このようにしてGUI世界ができあがります.
このようなGUI構築作業を start メソッドの中に記述するわけです.
————————————————————————-
【特徴的な Pane】
● Accordion
● ScrollPane
● SplitPane(水平)
● SplitPane(垂直)
● TabPane
——————————————————-
● FXMLアプリケーション構築例(NetBeans IDE & Java FX Scene Builder)
画像ビューワ(複数ウィンドウを持つアプリ)