イントロダクション
前回、ようやく画面切り替えを実装できました。長かったような短かったような。。。しかし、これで終わりではなく、むしろ始まる感じです (笑)
とりあえず、今回は自分の作業時間の都合があり、リファクタリングのみで終わります。
リファクタリングの内容
今回は、Eclipseで比較します。。。
- <プロジェクト・エクスプローラーで右クリック→チーム→ヒストリー>でコミット履歴を表示する
- <現在のソースと比較したいリビジョン(コミットした時の番号)を選択して右クリック>
- 現在のソースと比較をクリックする
https://www.youtube.com/watch?v=_9syqIs6-5o&feature=youtu.be
Gitでのソース比較です。
<修正後のソース>
package jp.zenryoku.fx; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; 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; import jp.zenryoku.fx.pane.JavaBasicPane; import jp.zenryoku.fx.pane.WebLoaderPane; /** * 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; /** startメソッドから引っ越ししてフィールド変数にします */ private BorderPane baseLayout; /** * 親クラスのメソッドをオーバーライドする。 * 画面を作成したり、ペインを作成したり、色々。。。 * * @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(JavaBasicPane.getInstance()); // このクラスのメソッドであることを明示的に示すのに「this」を使用する baseLayout.setBottom(this.createFooterPanel()); // 土台になるレイアウト(ペイン)をステージに追加する primaryStage.setScene(new Scene(baseLayout, VIEW_WIDTH, VIEW_HEIGHT)); primaryStage.show(); } /** * 画面のフッター部分にコントロール用のボタンを配置する。 * * @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(WebLoaderPane.getInstance()); }); 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; } }
前バージョンのソースに比べて、画面ペインの作成メソッドが全て無くなっています。実質2つのメソッドですが。。。
どこに引っ越したかというと、「JavaBasicPain」「WebLoaderPane」クラスに引越ししました。
各クラスはシンプルにコンストラクタ(private)とインスタンス(getInstance)を取得するメソッドが実装してあります。
/** * Copyright (c) 2012-present Lightweight Java Game Library All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name Lightweight Java Game Library nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. */ package jp.zenryoku.fx.pane; import javafx.geometry.Pos; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import javafx.scene.text.Font; /** * JavaBasic用の画面クラス。 * Paneクラスを継承して、画面の表示部分を作成します。 * * @author takunoji * 2019/01/28 */ public class JavaBasicPane extends Pane { /** このクラスのインスタンス */ private static JavaBasicPane instance; /** * コンストラクタ。 * デフォルト設定でのJavaBasic画面を作成します。 */ private JavaBasicPane() { // 暗黙的に起動される親クラスのコンストラクタ super(); // レイアウトたて VBox vBox = new VBox(5); // レイアウト横 HBox hBox = new HBox(8); // ラベルの設定 Label label = new Label(); // ハローワールドを出力する label.setText("Hello World"); 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); // 子供(中身)のペインを追加 this.getChildren().add(vBox); } /** * インスタンを取得する。 * このクラスのインスタンスは、必ず1つなので「static」をつけて良い。 * @return JavaBasicPane */ public static JavaBasicPane getInstance() { if (instance == null) { instance = new JavaBasicPane(); } return instance; } }
インスタンスを取得するメソッドは自分が気に入っている、実装方法です。
シングルトン・パターン
public static JavaBasicPane getInstance() { if (instance == null) { instance = new JavaBasicPane(); } return instance; }
このクラスのインスタンスが既にあるのならば、フィールドにあるインスタンスを返すメソッドになっています。つまりコンストラクタは一回しか通らない。。。
そして、フィールド変数には自分自身(JavaBasicPane)のインスタンスが格納できるようになっています。
こうすると、インスタンスが沢山できて余計なメモリを食わないで済みます。
ちなみに、ウェブサーバーにログインするときはインスタンスが1つだと複数人でログインした時に、どのインスタンスがどのユーザーかわからないので、インスタンスが複数になるようにクラスを作ります。したのはサンプルです。
public class LoginClass { // ユーザー名 private String userName; // 性別 private int sex; /* ログイン処理メソッド */ public login() { // ログイン用の処理 } }