Java
Grails
Groovy

Java プラットフォームで動作する Groovy を使ってクロスプラットフォーム GUI アプリの Hello World

More than 1 year has passed since last update.

Groovy とは

Java 上で動作するスクリプト言語のこと。
Java に必要な機能を追加した結果とのこと。

Groovy クイックインストール

Windows の場合

  1. 無ければ JDK (Java SE Development Kit) をインストールする。
  2. groovyのサイト からインストーラをダウンロードする。 記載当時 Groovy 2.4 が最新の安定版だった。
  3. インストーラを実行する。
  4. もし Groovy の環境変数が PATH に見つからない場合は追加する。(アンインストーラはこの情報を削除しない) JAVA_HOME が未設定だと警告が出る。これがないと Groovy が正常に動作しない。 もし警告が出たら JDK をインストールしていない可能性があるので確認すること。
  5. スタートメニューに「Start GroovyConsole」が表示されたらインストール完了。

Hello Groovy World

  1. Start GroovyConsole を起動する。
  2. 画面上部(スクリプト記述エリア)に次のスクリプトを記載する。 println("HelloWorld");
  3. Execute GroovyScriptボタンを押すか、Ctrl+Rを押してスクリプトを実行する。
  4. 画面下部に実行結果としてHelloWorldが表示されたら成功。 image.png

GUI(AWTのFrame)も試してみる。下記はHelloGroovyWorld(AWT)の実行画面。

image.png

例)HelloGroovyWorld(AWT)
/* Hello World (GUI) スクリプト */
import java.awt.*;
import java.awt.event.*;

/**
 * MainFrame クラス
 */
class MainFrame extends Frame
{
  def _menuBar;
  def _labelBody;

 /**
  * コンストラクタ
  */
  MainFrame() {

    /* タイトルを初期化 */
    setTitle("Hello World")

    /* メニューを初期化 */
    _menuBar = new MenuBar();
    def _menu = new Menu("ファイル");
    def _menuItem = new MenuItem("閉じる");
    _menuItem.addActionListener(new java.awt.event.ActionListener()
    {
        public void actionPerformed(ActionEvent e) {
            closeFrame(e);
        }
    });
    _menu.add(_menuItem);
    _menuBar.add(_menu);
    setMenuBar(_menuBar);

    /* フレーム内表示コンテンツを初期化 */
    _labelBody = new Label("Hello World");
    this.add(_labelBody);

    /* サイズを初期化 */
    setSize(new Dimension(300, 200));
  }

  /* フレームクローズ操作 */
  def closeFrame(e)
  {
    this.dispose();
  }
}

/* エントリポイント */
new MainFrame().show();

Java に対する Groovy の特徴

参考情報:Apache Groovy - Differences with Java
参考情報:Code Zine - Groovyってどんな言語?
JavaプログラマのためのGroovy入門

  • 一般的に利用する機会の多いクラスパッケージのいくつかがデフォルトでimportされているため宣言せず利用できる。
    • java.io.*, java.lang.*, java.math.BigDecimal, java.math.BigInteger, java.net.*, java.util.*, groovy.lang.*, groovy.util.*
  • マルチメソッド(又はランタイムディスパッチ)により、メソッド名と返値の型が同一で、引数の型が異なるメソッドが定義できる。これらは、実行時に与えた引数の型に応じて実行するメソッドが選択される。※どういったケースで便利なのかいまいち分からない。
  • クロージャが使える。
    • クロージャは引数を取ることが出来る。引数は暗黙的に仮引数itで表される。明示的に指定することも可能。clodure = { println("${it}が渡された。"); }; clodure("テスト");clodure = { name,age -> println("${name}は${age}才です。"); }; clodure("Alice",10);
    • クロージャは引数として指定できる。そのため each メソッドなどの引数に与えることで、制御構文を使わず配列の全要素へのアクセスが簡単に記述できる。sum = 0; (1..10).each { sum += it }; println(sum);
    • クロージャは宣言されたクラスの変数へアクセスできる。そのため、イベント駆動動作を容易に定義できる。
  • 配列の初期化書式が異なる。(クロージャにより {} が予約されているため)int[] array = [1,2,3];
  • 変数定義時のアクセス制御子を省略した際は private フィールドと認識され、Getter/Setter が自動定義される。また、パッケージ内で有効な package-private として定義する場合は、@PackageScope を記載する。(private と書かれているが、アクセス制御されていない様子)
    • Getter/Setter のメソッド名は getXXX(), setXXX() となる。※コンパイル時に自分が宣言していないメソッド名でエラーとなる場合はこの動作が原因である可能性がある。
  • Automatic Resource Management (ARM) は使えない。同等の処理はクロージャを使って処理できる。new File('C:\\path\\to\\file.txt').eachLine('Shift-JIS'){ println it; }
  • 匿名内部クラスの動作は Java の指針に従うものの挙動は異なる。詳細は Groovy の Documentation を参照のこと。
  • Java 8 で定義されたラムダ式は匿名内部クラスとして認識できるが、Groovy ではシンタックスエラーとなる。代わりにクロージャを使うこと。
  • ダブルクオートで括られた文字列リテラルは GString 型の値として処理される。
  • シングルクオートで括られた文字列リテラルは明示的に char で宣言されない限り String 型として処理される。2 文字以上の文字列を char としてキャストすると最初の 1 文字だけの char として処理される。
  • データ型は Object として認識され、プリミティブ型等へのオートラップされるため、widening/narrowing 変換処理の結果と異なることがある。
  • 比較演算子 == の挙動が Java ではプロミティブ型の比較だが、Groovy では a.compareTo(b)==0 または a.equals(b) に置き換えられる。同一性を確認するためには a.is(b) を使う。
  • Groovy における暗黙の型変換の挙動は Java と異なる。詳細はGroovy の Documentation を参照のこと。
  • 他、as, def, in, trait がある。(予約文字)

  • Java と比べてソースコードの記述ルールが緩い(Strictの逆)。例えば、行末のコロンは不要であり、データ型を宣言しなくてよい。また、どのクラスにも属さない文を記述することができる。(ルーズステートメント)

  • def で変数を宣言すると、変数に代入された値に応じた適切な型を動的に変更する。

  • マップ型が利用できる。map = ["Alice":10, "Bob":20, "Charlie":30]; println(map["Alice"]);

  • 制御構文では暗黙で評価結果が 0 や null ならば false、他は true となる。

  • switch文は数値以外を評価してcase分けできる。

  • for文の書式が異なる。for (m in list) { print m.toString(); };

  • クラス定義の動的変更(Expando)機能が用意されている。def e = new Expando(); e.msg = "Hello World"; e.show = { println(msg); }; e.show();

  • java.sql パッケージにより SQL クエリ処理が楽に記述できる。

  • Builder により HTML/XML/Swing 等の構造化されたデータが簡単に記述できる。import groovy.xml.MarkupBuilder; new MarkupBuilder().html { body { div { mkp.yield( 'Hello World' ) }; div( style:'style.css' ) { mkp.yield('Groovy') } } }