イントロダクション

前回は、Paneクラスを切り替えて画面の切り替え処理ができるようになりました。

今回は切り替えたあとに画面を表示する処理を実装します。

HTMLをロードする

単純に指定したURLのHTMLをダウンロードして表示するというものです。

HTMLのダウンロード〜表示までは「WebEngine」クラスがやってくれているので実装する側としては気にする必要がありません。

そして今まで作成していたソースに改変を大きめというほどではないですが、入れました。下のはGitでソースの差分を出したものです。

実際エラーが下の方に出ています。がそれは気にしなくても良いもののようです。→調べてみたらWebKit(ブラウザ)の履いているエラーらしい。。。

とりあえずはこんな感じでロードできました。

ソース

package jp.zenryoku.fx;

import java.util.ArrayList;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.concurrent.Worker.State;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

/**
 * JavaFXでのハローワールド〜OpenCVなどの
 * 作成したアプリをテストするための、スタンドアロンアプリ。
 * 
 * @author takunoji
 * 2019/01/23
 */
public class RootFxMain2 extends Application {
	/** 画面の縦幅 */
	private static final double VIEW_HEIGHT = 500.0;
	/** 画面の横幅 */
	private static final double VIEW_WIDTH = 500.0;
	/** コントロールボタンのリスト */
	private ArrayList\<Button\> buttonList; // ポイント1
	/** startメソッドから引っ越ししてフィールド変数にします */
	private BorderPane baseLayout; // ポイント2

	/**
	 * 親クラスのメソッドをオーバーライドする。
	 * 画面を作成したり、シーンを作成したり、色々。。。
	 * 
	 * @see javafx.application.Application#start(javafx.stage.Stage)
	 */
	@Override
	public void start(Stage primaryStage) throws Exception {
		// JavaBasic画面用のコントロールボタンを作成する
		this.cretateControllButtonList();
		// 画面部分とコントロールボタン部分にレイアウト(表示領域を分ける)
		baseLayout = new BorderPane();
		
		// Stageの設定
		primaryStage.setHeight(VIEW_HEIGHT);
		primaryStage.setWidth(VIEW_WIDTH);

		// このクラスにあるメソッドなので名前だけで呼び出せる
		baseLayout.setCenter(createJavaBasicPane());
		// このクラスのメソッドであることを明示的に示すのに「this」を使用する
		baseLayout.setBottom(this.createFooterPanel());
		// 土台になるレイアウト(ペイン)をステージに追加する
		primaryStage.setScene(new Scene(baseLayout, VIEW_WIDTH, VIEW_HEIGHT));
		primaryStage.show();
	}

	/**
	 * シーンの作成部分を切り出ししました。
	 * このシーンはJavaの基本を実行する時用にします。
	 * 
	 * @see http://zenryokuservice.com/wp/2019/01/25/java-stepupprogr…avafxで画面切り替えを作る〜/
	 * @return JavaBasic用のPane
	 */
	private Pane createJavaBasicPane() {
		// レイアウトたて
		VBox vBox = new VBox(5);
		// レイアウト横
		HBox hBox = new HBox(8);
		// ラベルの設定
		Label label = new Label();
		// ハローワールドを出力する
		label.setText(myFirstProgram());
		label.setFont(new Font("RobotRegular", 24));
		vBox.getChildren().add(label);
	
		// 1個目の数値、テキストフィールド
		TextField text1 = new TextField();
		text1.setPrefColumnCount(3);
		text1.setAlignment(Pos.BASELINE_CENTER);
		hBox.getChildren().add(text1);
		// 計算式のラベル
		Label ope = new Label("+");
		hBox.getChildren().add(ope);
	
		// 2個目の数値、テキストフィールド
		TextField text2 = new TextField();
		text1.setPrefColumnCount(3);
		text1.setAlignment(Pos.BASELINE_CENTER);
		hBox.getChildren().add(text2);
	
		// 縦のレイアウトに追加する
		vBox.getChildren().add(hBox);
	
		// シーンの作成
		return vBox;
	}

	/**
	 * HTMLローダーの画面(シーン)を作成します。
	 * 
	 * @return HTンLローダー画面
	 */
	private Pane createHtmlLoaderPane() {
		StackPane pane = new StackPane();
		WebView web = new WebView();
		web.setPrefWidth(VIEW_WIDTH);
		web.setPrefHeight(VIEW_HEIGHT - 20);
		WebEngine engine = web.getEngine();
		engine.getLoadWorker().stateProperty()
			.addListener((observer, oldValue, newValue) -> {
				if (newValue == State.SUCCEEDED) {
					System.out.println("*** Load is finished! ***");
				}
			});
		engine.load("http://zenryokuservice.com/wp/");
		pane.getChildren().add(web);
		System.out.println("非同期ロード処理開始");
		return pane;
	}

	/**
	 * 画面のフッター部分にコントロール用のボタンを配置する。
	 * 
	 * @return Pane レイアウトコンテナ
	 */
	private Pane createFooterPanel() {
		HBox hBox = new HBox(buttonList.size());
		for(Button ctlBtn : buttonList) {
			hBox.getChildren().add(ctlBtn);
		}
		return hBox;
	}

	/**
	 * コントロールボタンを作成する。
	 * 
	 */
	private void cretateControllButtonList() {
		// デザインパターン:シングルトンの実装
		if (buttonList == null) {
			buttonList = new ArrayList\<Button\>();
		}
		Button viewChangeBtn = new Button("画面切り替え");
		viewChangeBtn.setOnAction(event -> {
			baseLayout.getChildren().remove(0);
			baseLayout.setCenter(createHtmlLoaderPane());
		});
		buttonList.add(viewChangeBtn);
		Button closeBtn = new Button("閉じる");
		buttonList.add(closeBtn);
	}
	/**
	 * メインメソッド
	 * @param args プログラム引数
	 */
	public static void main(String[] args) {
		// 親クラスのメソッドを呼び出す、これは上のstart()を呼び出す。
		launch();
	}

	/**
	 * JavaFX版のハローワールド実装用のメソッドになります。
	 * @return 画面に出力する文字列
	 */
	public String myFirstProgram() {
		// この「hyoji = ""」を「"hyoji = "Hello World"」と修正してください。
		String hyoji = "Hello World";
		long num = 12345678901L;
		float shosu = 123.09876543f;
		return hyoji;
	}
}

ソース中赤い字で記載している部分が、HTMLをロードする部分のコードになります。

ソースが長くなって来たので、まぁみづらい感じですが。。。以下の順番で処理は走っています。

  1.  mainメソッド
  2.  start()
  3.  cretateControllButtonList()
  4.  createJavaBasicPane()
  5.  createFooterPanel()
  6.    myFirstProgram()

赤い字の「ポイント1」

フィールド変数のボタンクラスのリスト(ArrayList)にボタンを作成して追加します。その後「createFooterPanel()」でリストからボタンを取得してPaneに登録しています。

赤い字の「ポイント2」

今回のJavaFX画面は「BorderLayout」の①「Center」と②「Bottom」を使用しています。

①は入力するとかWebの画面など「View」の部分です。

②は画面の下にあるボタンを配置する部分です。

おめでとうございます

なんやかんやと、JavaBasic画面とHTMLロード画面の(とりあえずの)作成が完了しました。

「初めてJavaをやった方」へ
よく頑張ったと思います。自分にご褒美をあげてください(笑)

「久しぶりやった方」へ
ネットワークのアクセス部分は新鮮だったのではないでしょうか?

「普段からコーディングしている方」へ
ネットワークのアクセス部分は新鮮だったのではないでしょうか?

「Java歴〜年の方」へ
まだまだ序の口なので、ご安心ください。そのうちにデザインパターンなども触れていきます。

体制を整えます。

ちょっとソースが汚くなって来たのと、OpenCVでのチュートリアルを行うために、一度ソースを綺麗に(リファクタリング)しようと思います。

それは次回行いますが、目的としては以下の通り

  • FXMLをロードして画面コンポーネントとして画面に表示する
  • 今まで作成したものも使えるようにする
  • OpenCVを使うときの設定(プロジェクト)も改めてやる

というわけで、作成したものを移動してEclipseの1つのプロジェクトに整理しようと思います。※現状(2019/01/27)はPracticeJava1というプロジェクトに入っていますが、それを別プロジェクトを作成します。

でわでわ。。。