JavaFX ワンポイント 〜Fontを指定する〜

TextFIeldやTextAreaを使用するときにFontの設定をしてやると大きさなど変更できます。

設定方法は以下のようなコードです。

newWindow = new Stage();
StackPane stack = new StackPane();
textArea = new TextArea();
textArea.setFont(Font.font("MS UI Gothic", FontWeight.BLACK, 19));
textArea.setOnKeyPressed(keyEvent -> {
    KeyCode code = keyEvent.getCode();
    if (keyEvent.isShiftDown() && KeyCode.SPACE.equals(code)) {
        newWindow.close();
        isTextIn = false;
    }
});
textArea.setOnKeyReleased(keyEvent -> {
    KeyCode code = keyEvent.getCode();
    if (keyEvent.isShiftDown() && KeyCode.ENTER.equals(code)) {
        textArea.setText("");
        textArea.positionCaret(0);
    }
});
stack.getChildren().add(textArea);
Scene scene = new Scene(stack, 450, 100);
newWindow.setScene(scene);
newWindow.initModality(Modality.WINDOW_MODAL);
newWindow.initOwner(primary);
newWindow.setX(primary.getWidth() * 0.4);
newWindow.setY(primary.getHeight() * 0.8);
newWindow.show();

return newWindow;

TextAreaで実装しましたが、これはTextFieldにも使用できます。

でわでわ。。。



関連ページ一覧

Eclipse セットアップ

  1. Java Install Eclipse〜開発ツールのインストール〜
  2. TensorFlow C++環境〜EclipseCDTをインストール〜
  3. Setup OpenGL with JavaJOGLを使う準備 for Eclipse
  4. Eclipse Meven 開発手順〜プロジェクトの作成〜
  5. Java OpenCV 環境セットアップ(on Mac)
  6. Eclipse SceneBuilderを追加する
  7. JavaFX SceneBuilder EclipseSceneBuilder連携~

Java Basic一覧

  1. Java Basic Level 1 〜Hello Java〜
  2. Java Basic Level2 〜Arithmetic Calculate〜
  3. Java Basic Level3 〜About String class〜
  4. Java Basic Level 4〜Boolean〜
  5. Java Basic Level 5〜If Statement〜
  6. Java Basic Summary from Level1 to 5
  7. Java Basic Level 6 〜Traning of If statement〜
  8. Java Basic Level8 〜How to use for statement〜
  9. Java Basic Level 8.5 〜Array〜
  10. Java Basic Level 9〜Training of for statement〜
  11. Java Basic Level 10 〜While statement 〜
  12. Java Basic Swing〜オブジェクト指向〜
  13. Java Basic Swing Level 2〜オブジェクト指向2〜
  14. サンプル実装〜コンソールゲーム〜
  15. Java Basic インターフェース・抽象クラスの作り方
  16. Java Basic クラスとは〜Step2_1〜
  17. Java Basic JUnit 〜テストスイートの作り方〜

Git関連

  1. Java Git clone in Eclipse 〜サンプルの取得〜
  2. Eclipse Gitリポジトリの取得 GitからソースをPullしよう〜
  3. IntelliJ IDEA GitGitリポジトリからクローン〜

JavaFX ワンポイント 〜新しいWindowを立ち上げる〜

JavaFXを起動するときにすでにウィンドウを1つ起動していますが、さらにウィンドウを使いたいとき。。。

今回はそんなところを「ワンポイントレッスン」的に記載したいと思います。

ちなみに、JavaFXはこんな感じのものです。余計な音が入っています。そして、文言を表示する部分でnewWindowを使用しています。

ウィンドウを新しく作る

WindowはStageです。なので、下のように実装したらできました。
参考にしたサイトはこちらです。

private Stage createNewWindow(Stage primary) {
    newWindow = new Stage();
    StackPane stack = new StackPane();
    textArea = new TextArea();
    textArea.setOnKeyPressed(keyEvent -> {
        KeyCode code = keyEvent.getCode();
        if (keyEvent.isShiftDown() && KeyCode.SPACE.equals(code)) {
            newWindow.close();
            isTextIn = false;
        }
    });
    textArea.setOnKeyReleased(keyEvent -> {
        KeyCode code = keyEvent.getCode();
        if (keyEvent.isShiftDown() && KeyCode.ENTER.equals(code)) {
            textArea.setText("");
            textArea.positionCaret(0);
        }
    });
    stack.getChildren().add(textArea);
    Scene scene = new Scene(stack, 250, 50);
    newWindow.setScene(scene);
    newWindow.initModality(Modality.WINDOW_MODAL);
    newWindow.initOwner(primary);
    newWindow.setX(primary.getWidth() * 0.4);
    newWindow.setY(primary.getHeight() * 0.8);
    newWindow.show();

    return newWindow;
}

作成したウィンドウにキーイベントを追加して見ました。

ちなみに、
簡単ですが、こんな感じで。。。

でわでわ。。。



関連ページ一覧

Eclipse セットアップ

  1. Java Install Eclipse〜開発ツールのインストール〜
  2. TensorFlow C++環境〜EclipseCDTをインストール〜
  3. Setup OpenGL with JavaJOGLを使う準備 for Eclipse
  4. Eclipse Meven 開発手順〜プロジェクトの作成〜
  5. Java OpenCV 環境セットアップ(on Mac)
  6. Eclipse SceneBuilderを追加する
  7. JavaFX SceneBuilder EclipseSceneBuilder連携~

Java Basic一覧

  1. Java Basic Level 1 〜Hello Java〜
  2. Java Basic Level2 〜Arithmetic Calculate〜
  3. Java Basic Level3 〜About String class〜
  4. Java Basic Level 4〜Boolean〜
  5. Java Basic Level 5〜If Statement〜
  6. Java Basic Summary from Level1 to 5
  7. Java Basic Level 6 〜Traning of If statement〜
  8. Java Basic Level8 〜How to use for statement〜
  9. Java Basic Level 8.5 〜Array〜
  10. Java Basic Level 9〜Training of for statement〜
  11. Java Basic Level 10 〜While statement 〜
  12. Java Basic Swing〜オブジェクト指向〜
  13. Java Basic Swing Level 2〜オブジェクト指向2〜
  14. サンプル実装〜コンソールゲーム〜
  15. Java Basic インターフェース・抽象クラスの作り方
  16. Java Basic クラスとは〜Step2_1〜
  17. Java Basic JUnit 〜テストスイートの作り方〜

Git関連

  1. Java Git clone in Eclipse 〜サンプルの取得〜
  2. Eclipse Gitリポジトリの取得 GitからソースをPullしよう〜
  3. IntelliJ IDEA GitGitリポジトリからクローン〜

Java OpenGL JOGLを使う 〜3Dモデルを読み込むために1〜

今まで、プロコン用ゲームを作成するために、仕様の作成を行なっていましたが、ちょいと仕様作成につまづいて(調査することが多いため)ゲームで使用する(使用したい)3Dモデルの読み込みアプリを作成しようと考えています。

以前、LWJGLを使用して実装したのですが、ライセンスなどが、面倒なのとインストール(セットアップ)が面倒なのでシンプルにJOGLを使用してみようと考えています。

JOGL= OpenGL

Java版のOpenGLということらしいです。LWJGLでも同じようなメソッドとかクラスとか使用していました。
なので、LWJGLよりも使いやすいと思ったのです。

早速写経

参考サイトはこちらです
写経したものを、実行してみます。クラス名は自分の作成したクラス名になっています。そして、オーバーライドするメソッドが増えていたので、それも追加しました。

public class ModelUtil implements GLEventListener {
    @Override
    public void display(GLAutoDrawable drawable) {
        final GL2 gl = drawable.getGL().getGL2();

        gl.glBegin (GL2.GL_LINES);//static field
        gl.glVertex3f(0.50f,-0.50f,0);
        gl.glVertex3f(-0.50f,0.50f,0);
        gl.glEnd();

     }

    @Override
    public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {
    }

     @Override
     public void dispose(GLAutoDrawable arg0) {
     }

     @Override
     public void init(GLAutoDrawable arg0) {
     }

     public static void main(String[] args) {

        final GLProfile profile = GLProfile.get(GLProfile.GL2);
        GLCapabilities capabilities = new GLCapabilities(profile);

        final GLCanvas glcanvas = new GLCanvas(capabilities);
        Line l = new Line();
        glcanvas.addGLEventListener((GLEventListener) l);
        glcanvas.setSize(400, 400);

        final JFrame frame = new JFrame ("straight Line");

        frame.getContentPane().add(glcanvas);

        frame.setSize(frame.getContentPane().getPreferredSize());
        frame.setVisible(true);
    }
}

描画するのに使用するのはJavaFXではなく、「Swing」のようです。
サンプルはこちらのサイトにありました。

写経してみて

動画にありますが、写経後に色々と気がつくことが多いです。
とりあえずは、今回作成したコードからして、画面に何かしらを描画するためには下のクラスを使用する必要があるということがわかりました。

  1. GLProfile
  2. GLCapabilities
  3. GLCanvas
  4. GLEventListener

コードを眺める

今回作成した「ModelUtil」クラスはGLEventListenerの実装クラスです。
このインターフェースクラスを実装(implements)すると必ず、下のメソッドをオーバーライドしなくてはいけません。
Javaはそういうルールをコンパイラで作っています。→このようにしないとビルドエラーになるということです。

  1. display()
  2. reshape()
  3. dispose()
  4. init()

ちなみにこれらのメソッドはから実装です(笑)。下のような形です。

@Override
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {
}

 @Override
 public void dispose(GLAutoDrawable arg0) {
 }

 @Override
 public void init(GLAutoDrawable arg0) {
 }

それでも、Mainメソッドで動かしているので問題なく表示できました。

とりあえず、写経して線を引いただけですが、ここからVoxcelやBlenderなどで作成した#Dモデルを表示することを目指します。

でわでわ。。。

関連ページ

  1.  Chapter1[外枠の表示のみ]
  2. Chapter2-1〜クラスの構成〜
  3. Chapter2-2〜インターフェースの使い方と詳細〜
  4. Chapter2-3〜GameEngineクラス(サンプルクラス)〜/li>
  5. Chapter2-4〜Windowクラス(サンプルクラス)〜
  6. Chapter3〜描画処理を読む〜
  7. Chapter4〜シェーダについて〜
  8. Chapter5-1〜レンダリングについて〜
  9. Chapter5-2〜レンダリング詳細〜
  10. Chapter6〜Projection(投影)〜
  11. Chapter7-1〜Cubeを作る〜
  12. Chapter7-2〜Texture〜

@Override
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {
}

@Override
public void dispose(GLAutoDrawable arg0) {
}

@Override
public void init(GLAutoDrawable arg0) {
}

JavaFX in RPi 〜IFrame Youtube Player自動再生〜

今回は、以前作成したプロパティファイルを読み込む処理を連携して、以下のような処理を作成したいと思います。

  1. プロパティファイルを読み込む
  2. 取得したURLを15秒おきに再生

前回JavaFXでHTML+JSで作成した Youtube Playerを表示しました。

ポイント

  1. JavaFXでプロパティファイルを読み込みます
  2. 読み込んだデータをJSに出力します。
    engine.executeScript("var data = " + videoIds + ";");
  3. あとはHTML(+JS)でVideoIDの数だけ動画をループして表示します。

HTMLに実装したJSはこのページをコピって作成しました

作成したコードはGithubにアップしてあります。

  1. Main.java
  2. iframePlayer.html

とりあえず、JSでYoutubeの動画を15秒ずつ切り替えるところが大変でした。

動画の指定方法として、URLではなくVideoIDを使用するところがキーポイントでした。

でわでわ。。。

https://github.com/ZenryokuService/RPiMediaPlayer/blob/master/RPiMediaPlayer/src/application/iframePlayer.html

JavaFX in RPi 〜IFrame Youtube Player を作る〜

今回はHTML(とJS)でYoutubePlayerを作成します。
目的と実行手順は以下の通りです。

参考サイトはこちらのGoogle Developperページです。

IFrame Youtube Player

  1. HTMLでYoutubePlayerを作成
  2. JavaFXで作成したHTMLをロード
  3. RPiで起動するように設定
  4. TVなどで再生してみれるようにする

サンプルコードをコピペで動かしてみました。

<!DOCTYPE html>
<html>
  <body>
    <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
    <div id="player"></div>

    <script>
      // 2. This code loads the IFrame Player API code asynchronously.
      var tag = document.createElement('script');

      tag.src = "https://www.youtube.com/iframe_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

      // 3. This function creates an <iframe> (and YouTube player)
      //    after the API code downloads.
      var player;
      function onYouTubeIframeAPIReady() {
        player = new YT.Player('player', {
          height: '360', // window.innerHeight * 0.9などで値を変更する
          width: '640',
          videoId: 'M7lc1UVf-VE',
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });
      }

      // 4. The API will call this function when the video player is ready.
      function onPlayerReady(event) {
        event.target.playVideo();
      }

      // 5. The API calls this function when the player's state changes.
      //    The function indicates that when playing a video (state=1),
      //    the player should play for six seconds and then stop.
      var done = false;
      function onPlayerStateChange(event) {
        if (event.data == YT.PlayerState.PLAYING && !done) {
          setTimeout(stopVideo, 6000);
          done = true;
        }
      }
      function stopVideo() {
        player.stopVideo();
      }
    </script>
  </body>
</html>

しかし、このままだと全画面表示でないのでカスタムしてやる必要があります。

カスタムする

ここで、変更したいのはボタンなどをつけて「チャンネルなどを変えることができる」ということをユーザーに気づいてもらえるようにすることです。
具体的には下のようなイメージです。。。
しかし、仮の状態です。

「▶︎」などをつけてみました。
とりあえずは、見た目のみです。

バージョンについて

今回作成するのは、特定のYoutubeの動画IDを15秒おきに再生するものを作成するので、正直のところは「▶︎」ボタンなどはいらないのです。。。
しかし、バージョンわけで表示できるような工夫をしてみたいと思います。
<Version1>
Youtubeを15置きに動画IDを変更して連続的に再生する、アプリが止まるまで続ける自動再生プレーヤ

<Version2>
Youtubeだけでなく、インターネットTVなど表示するテレビ局などを変更、チャンネルの変更などができるようにする。
当然、RPi(ラズパイ)をテレビに接続して表示できるようにする。(試行錯誤中ですが・・・・)

以上のように考えております。

でわでわ。。。



JavaFX in RPi 〜HTMLをロードする〜

今回は作成したHTMLファイルをJavaFXでロードします。
前回URLをロードしてみた結果、表示したくない部分も画面に出てきたのでそれをなくします。

問題と解決策

早い話が、HTMLにiframeを使用して動画部分のみを表示しようというところです。
下の画像がJavaFXでロードした結果です。

HTMLをロードする

JavaFXでHTMLをロードするのはとても簡単でした。
<ロードした結果>

<ロードしたHTML>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
    <iframe width="560" height="315"
         src="https://www.youtube.com/embed/S0LbTzCrkiw"
         frameborder="0"
         allow="accelerometer;
         autoplay;
         encrypted-media;
         gyroscope;
         picture-in-picture"
         allowfullscreen>
    </iframe>
</body>

</html>

<Javaコード>

public void start(Stage primaryStage) {
    try {
        // レイアウト(土台)になるペインを作成
        BorderPane root = new BorderPane();

        // WebView(ブラウザ)の作成
        WebView browser = new WebView();
        WebEngine engine = browser.getEngine();
        String aaa = getClass().getResource("iframe.html").toExternalForm();
        System.out.println(aaa);
        engine.load(aaa);

        root.setCenter(browser);
        // 画面を表示する土台(シーン)を作成
        Scene scene = new Scene(root,this.windowWidth,this.windowHeight);
        // JavaFX用のCSSを読み込む
        scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.setOnCloseRequest(event -> Platform.exit());
        primaryStage.show();
    } catch(Exception e) {
        e.printStackTrace();
    }
}

今回の課題

ロードしたHTMLファイルのプロパティ(画面サイズや、そのほかのコントロール)を操作したい

上の要件を満たすために、通常のHTML + JSで実装するのであれば、シンプルにHTMLファイルに全部記述してしまうのが手っ取り早く、メンテナンス性も優れています。

というわけで、Youtubeを単純に全画面表示する場合は下のようなHTMLファイルを作成してやればOKな感じでした。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body width="100%" height="100%">
    <iframe style="border: 0; position:fixed; top:0; left:0; right:0; bottom:0; width:100%; height:100%"
         src="https://www.youtube.com/embed/S0LbTzCrkiw"
         frameborder="0"
         allow="accelerometer;
         autoplay;
         encrypted-media;
         gyroscope;
         picture-in-picture"
         allowfullscreen>
    </iframe>
</body>

</html>

しかし、自動再生が走らないのでちょいといじります。
iframeタグのsrcにautoplay=1を、allow属性にallow="accelerometer"を追加しました。HTMLを直接開いた場合は自動再生が始まらなかったのですが、JavaFXでロードしたら自動再生が始まりました。

ちょっと腑に落ちませんが、まぁよしとします(笑)

作成したコードはこちらにアップしてあります。

でわでわ。。。



JavaFX in RPi 〜URLでYoutubeにアクセス〜

JavaFXでのWeb画面表示をやろうと思います。
・参考にするのはORACLEのJavaドキュメント(日本語)です、このページはWebViewクラスの使い方が記載してありました。

・もう1つ使うものがあります。BorderPaneクラスです。
のクラスの使い方はこちらのページにありました

WebView & BorderPane

実行することは以下のような内容らしいです。

  1. ローカルおよびリモートURLからのHTMLコンテンツのレンダリング
  2. Web履歴の取得
  3. JavaScriptコマンドの実行
  4. JavaScriptからJavaFXへのアップコールの実行
  5. Webポップアップ・ウィンドウの管理
  6. 埋込みブラウザへの効果の適用

基本的な使い方は下のようなコードでやるようです。

WebView browser = new WebView();
WebEngine webEngine = browser.getEngine();
webEngine.load("http://mySite.com");

URLでYoutubeへ。。。

それではシンプルに実装してみます。以前やったプロパティファイルの読み込みと画面サイズの取得はそれぞれ以下のメソッドに実装しています。
・initWindowInfo(画面サイズの取得)
・loadProperties(プロパティファイルの読み込み)

ちなみにコードはGithubにアップしています。

上にあるWebViewの使い方を真似してURLを以下のものを指定して表示します。
https://www.youtube.com/watch?v=6qhJsvpd0ds

ちなみに、動画は下のようなものです。

しかし、実行結果は下のような見た目です。

コードは以下に。。。
ちなみにコードはGithubにアップしています。

public class Main extends Application {
    /** プロパティファイル */
    private Properties prop;
    /** プロパティファイルのキー・セット */
    private Set keySet;
    /** 最大ウィンドウサイズ(幅) */
    private double windowWidth;
    /** 最大ウィンドウサイズ(高さ) */
    private int windowHeight;

    @Override
    public void start(Stage primaryStage) {
        try {
            // レイアウト(土台)になるペインを作成
            BorderPane root = new BorderPane();

            // WebView(ブラウザ)の作成
            WebView browser = new WebView();
            WebEngine engine = browser.getEngine();
            engine.load("https://www.youtube.com/watch?v=6qhJsvpd0ds");

            root.setCenter(browser);
            // 画面を表示する土台(シーン)を作成
            Scene scene = new Scene(root,this.windowWidth,this.windowHeight);
            // JavaFX用のCSSを読み込む
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

    /** コンストラクタ */
    public Main() {
        windowWidth = 0;
        windowHeight = 0;
        // プロパティファイルの読み込み
        prop = new Properties();
        loadProperties();
        // ウィンドウ情報の取得(縦横の幅)
        initWindowInfo();
    }
      ・
      ・
      ・

問題

表示したいのは動画のみでページ全体ではない

これをなんとかするのに頭を一捻りする必要があります。。。

頭から煙が出てきたのでそろそろと失礼します。

でわでわ。。。



Java FX in RPi 〜画面サイズの取得〜

今回は、起動しているPCの画面サイズを取得する実装を行います。なかなかJavaFXならではの実装にたどり着きませんが、必要な実装ですのでやります。

画面サイズの取得

画面サイズを取得する前に、予備知識として記載します。
Javaの画面関連のパッケージはjava.awtというものですが、OSを起動した時に画面を表示するのに使用している(グラフィック担当)サーバーがあり、それをXサーバー(X-Server)と言います。X-Window Systemのことです、常駐アプリで「表示してください」というリクエストに応えるので「サーバー」です。

java.awtはX-Serverに依存

以前、CUIでラズパイを起動してからJavaFXで画面を表示しようと試みたところJavaFXはGUIモードでないと起動できないことを知りました。。。
つまりX-Serverが動かないとJavaFXも動かない・・・ということです。

画面サイズを取得する

画面サイズを取得するのに「java.awt」を使用します。
そして、実際に使用するクラスはGraphicsEnvironmentです。

テスト駆動なので。。。

まずは、テストケースから入ります。
シンプルな内容なのでテストもシンプルです。
<仕様>
画面のサイズを取得しMainクラスのフィールドにセットする
このメソッドを使用します。

これだけです。
なので作成するテストケースは下のようになります。

/** 画面サイズの取得テスト */
@Test
public void testInitWindowInfo() {
    // privateメソッドの呼び出し
    try {
        // メソッドの取得
        Method mes = target.getClass().getDeclaredMethod("initWindowInfo");
        // メソッドのアクセス範囲をpublicに変更
        mes.setAccessible(true);
        // メソッドの実行(引数も返り値もない
        mes.invoke(target);

    } catch (NoSuchMethodException | SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    // テストの起動確認
    assertFalse(target.getWindowHeight() == 0);
    assertFalse(target.getWindowWidth() == 0);
}

そして、テストケースを作成する最中に実装も終わっていました。

/** コンストラクタ */
public Main() {
    prop = new Properties();
    windowWidth = 0;
    windowHeight = 0;
}

こんな感じです。

次回は、JavaFXの画面作成に着手したいと思います。

でわでわ。。。



Java FX in RPi 〜プロパティファイルの読み込み JavaFX実装〜

今回は、プロパティファイルの読み込みを実装します。
以前、コンソールアプリ作成でやったものもあるのでそちらもどうぞ。

ちなみに、前回は大まかにどんなものを作るのか?ということと、実装環境に関して記載しました。

プロパティファイルを読む

目的は、アプリケーションの起動時に初めに設定を読み込み表示するYoutubeのURLを設定、?秒おきに表示を切り替えるものです。

ちなみに作成したプロパティファイルは下のようなものです。

# Properties for this application

#########################################################
# URL List for load Youtube (rule "url" + number        #
#########################################################
url1=https://www.youtube.com/watch?v=6qhJsvpd0ds
url2=https://www.youtube.com/watch?v=w9BubZIEGdg
url3=https://www.youtube.com/watch?v=YPuaUUvCdMg
url4=https://www.youtube.com/watch?v=w9iiCnX0STw
url5=https://www.youtube.com/watch?v=XW7FgoR5pzQ&t=63s
url6=https://www.youtube.com/watch?v=DZEWd0Viiuk&t=1s
url7=https://www.youtube.com/watch?v=45xcPvhGhDo
url8=https://www.youtube.com/watch?v=w9BubZIEGdg

プロパティファイルの読み込み

使用するクラスはPropertiesクラスです。

早速プログラムを作成しました。Githubにアップしてあります。
そして、テスト駆動開発ですので、テストケースから作成しています。

テストケースを作成する

JUnitでのテストを作るのに、以下のような手順で作成します。

  1. 作成するクラスはどのように動くか決める
  2. 作成したものが、想定通りに動く確認する処理をかきます
  3. 実行して緑色になることを確認(下の図を参照ください)

作成する時にJUnitでやる時のポイントも記載しておきます。
Junitをビルドパスニ追加しておく必要があります。そして、Mavenでdependencyを追加したときはすでにビルドパスに追加されています。。。

アノテーションで設定

「@Test」: 実行するテストを使用します。
「@Before」: テストを実行する前に起動する。主にテストの実行準備などを行う

具体的に。。。

public class MainTest {
    /** テスト対象クラス */
    private Main target;

    /**
     * テストを行うための準備処理
     */
    @Before
    public void initTest() {
        // テスト対象クラスのインスタンスを生成
        target = new Main();
    }

/** loadProperties()のテスト */
    @Test
    public void testLoadProperties() {
        target.loadProperties();
        Set keySet = target.getKeySet();
        keySet.forEach(System.out::println);
    }
}

上のコードを実行したものが、下のキャプチャです。

そして、@Beforeのついているメソッドは。。。

/**
 * テストを行うための準備処理
 */
@Before
public void initTest() {
    // テスト対象クラスのインスタンスを生成
    target = new Main();
}

のようになっています。単純にテスト対象クラスをインスタンス化してフィールド変数「target」に代入しています。

そして、テストケース(メソッド)「testLoadProperties()」

/** loadProperties()のテスト */
@Test
public void testLoadProperties() {
    target.loadProperties();
    Set keySet = target.getKeySet();
    keySet.forEach(System.out::println);
}

テストとして実行するメソッド(テストケース)は「@Test」をつけてやります。実行結果に関しては上のキャプチャに記載しています。
ちなみに実行したコードは下のものです。

/** loadProperties()のテスト */
@Test
public void testLoadProperties() {
    target.loadProperties();
    Set keySet = target.getKeySet();
    assertNull(keySet);
    keySet.forEach(System.out::println);
}

これは失敗したコードです。そしてテストとしては失敗しなくてはいけないコードです。

どーゆーことか?

コードに色付けができなかったのですが、下のようなコードを追加しました。
assertNull(keySet);このコードは取得したキーセットがNullにならないとAssertErrorを出力するメソッドです。
本当であれば、assertNotNull()を使わないといけません。このような部分はテスト仕様なのでどのような処理を行うかちゃんと設計しなくてはいけません。。。

そして、下のコードが直したものです。

/** loadProperties()のテスト */
@Test
public void testLoadProperties() {
    target.loadProperties();
    Set keySet = target.getKeySet();
    assertNotNull(keySet);
    keySet.forEach(System.out::println);
}

そして、実行結果は緑色になっています。

こんな感じでプロパティファイルが読めていることを確認しています。
keySet.forEach(System.out::println);
出力結果

*** testLoadProperties ***
url5
url6
url3
url4
url1
url2
url7
url8
*** testConvertKeySet ***
test4
test2
test3
test1

こんな感じで作成しました。

でわでわ。。。



Java FX in RPi 〜ラズパイで動くJavaFX〜

Javaで作成する、画面アプリをラズパイで動かそうと言うものです。
今回は、作成したアプリをラズパイ上で動かし、「Youtubeプレイヤーとして動かそう!」と言うものです。

JavaFX in RPi

開発環境構築

前提として、自分が使用している開発環境について記載します、

  1. SceneBuilderを使用しています。(JavaFXの初期コード生成などしてくれます)
  2. JDK1.8を使用(RPiもJDK1.8を使用します)

SceneBuilderのインストール

こちらの記事にインストール手順と実際に動かした時の内容を記載しました。(動かしてみた時の記事)
このセットアップをしておくとJavaFXのプロジェクトを作成した時に、下のようなコードを生成してくれます。

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            BorderPane root = new BorderPane();
            Scene scene = new Scene(root,400,400);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

ちなみに、プロジェクトをMaven化しているのでPOMファイルがあります。生成されるのはapplication.cssとMain.javaです。

開発開始

現状(上こコード)では下のような表示ができます。

まぁ何も実装していないので何もないです(笑)
ここに必要なもの(コンポーネント(ボタンなど))を追加していきます。

設計

設計の大まかなところはGithubにアップしています。
なので、とりあえずはURLをロードして、表示する画面を作成します。
大まかな仕様は以下の通りです。
<仕様>

  1. JavaFXを起動
  2. プロパティファイルをロード(読み込む)
  3. プロパティファイルにあるURLを読み込み表示する

とりあえずはここまで実装しようと思っています。

JavaFXの起動

とりあえず生成されたコードで動いているので、この部分は飛ばします。

1.プロパティファイルの読み込み

RPi(ラズパイ)で動かす時にはMavenのプラグインで出力するJARファイルを起動して動かすので、別途プロパティファイルをJARファイルの隣(同じ階層)に配置する必要があります。
しかし、開発段階では気にしなくて良いので、resources/いかにプロパティファイルを配置します。

そんなわけで実装開始〜

プロジェクトの設定

単純に使用したいライブラリ、JARファイルの出力を設定します。
まずは使用するJUNIT(使い方など)dependencyに追加、使用できるようにします。

ちなみに、EclipseのMavenプロジェクトの場合はPOMファイルに下のような設定をかき、ビルド(Install)すると必要なライブラリが追加されます。

実行するときは下のようにPOMファイルを右クリックして Maven Installを実行します。

ちなみに、自分が作成したPOMファイル(コピペで作成)は以下のようなものです。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>RPiMediaPlayer</groupId>
  <artifactId>RPiMediaPlayer</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>RPi メディアプレーヤー</name>

<!-- 必要な情報をプロパティとしてもつ -->
  <properties>
      <java.version>1.8</java.version>
      <maven.compiler.target>${java.version}</maven.compiler.target>
      <maven.compiler.source>${java.version}</maven.compiler.source>
  </properties>  
<!-- 使用したいライブラリ(依存性)の設定 -->
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
<!-- ビルドの設定 -->
  <build>
    <sourceDirectory>src</sourceDirectory>
    <resources>
      <resource>
        <directory>src</directory>
        <excludes>
          <exclude>**/*.java</exclude>
        </excludes>
      </resource>
    </resources>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.7.0</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <configuration>
        <archive>
          <manifest>
            <addClasspath>true</addClasspath>
            <mainClass>zenryokuservice.socket.server.SocketServerBasic</mainClass>
            <classpathPrefix>dependency-jars/</classpathPrefix>
          </manifest>
          </archive>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
      </configuration>
      <executions>
        <execution>
          <id>make-assembly</id> <!-- this is used for inheritance merges -->
          <phase>package</phase> <!-- bind to the packaging phase -->
          <goals>
            <goal>single</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-dependency-plugin</artifactId>
      <version>2.5.1</version>
      <executions>
        <execution>
          <id>copy-dependencies</id>
          <phase>package</phase>
          <goals>
          <goal>copy-dependencies</goal>
          </goals>
          <configuration>
           <outputDirectory>
             ${project.build.directory}/dependency-jars/
           </outputDirectory>
          </configuration>
         </execution>
       </executions>
     </plugin>
    </plugins>
  </build>
</project>

実装まで行きませんでしたが、ここら辺で失礼いたします。

でわでわ。。。