🤪

SwingUI 爆誕!

に公開

宣言型の SwingUI フレームワークを発表、アプリ開発をよりインタラクティブなものに

JavaのGUIフレームワークSwingを宣言的UIに対応させたSwingUIが発表された。Swingを宣言型UIプログラミングパラダイムに対応させることで、開発者の生産性の大幅な向上と、コード行の削減を可能にしている。
これまでの命令型パラダイムでは、開発者はUIコンポーネントを構築し、表示の更新をするにはメソッドとセッターを使用して対応していた。新しいSwingUIを使用すれば、アプリケーションレイアウトを一度記述するだけでよい。実際、SwingUIのドキュメントでは、次のように説明されている。

SwingUIでは、バインドするデータの状態の変化をトリガーとして、ビューのレンダリングが一致するように更新します。

開発者は、データの変化に合わせてコンポーネントに対する操作を記述しなければならない負担から解放される。現在のUIの状態と、イベントに応じてその状態がどのように変化するかを記述し、あとはフレームワークに任せればよいのだ。


ログイン画面の例(FlatLaf利用)

上記のようなログイン画面を作成するには、以下のように記述する。
例えばコンポーネントを縦に並べる場合はVStack.of(JComponent...)を使い、TextField等のUIコンポーネントを並べていく。なお、VStackHStackは内部でJPanel(レイアウトはBoxLayout)を呼び出している。

final UIState<String> loginId = new UIState<>("");   // ログインID
final UIState<String> password = new UIState<>("");  // パスワード

Frame.of
(
    "ログイン",

    VStack.of
    (
        Spacer.fill(),

        // 画面タイトル
        Text.of("お小遣い帳")
            .font(new Font(Font.MONOSPACED, Font.BOLD, 14)),

        Spacer.of(0, 4),

        // 右端にクリアボタン設置
        ZStack.of
        (
            UIAlignmentX.RIGHT, UIAlignmentY.CENTER,

            // ログインID入力欄
            TextField.of(loginId)
                .rendering(new HintTextRenderer("ログインID"))
                .frame(140, 34),

            // クリア・ボタン
            Button.of(new ClearIcon(16, 16))
                .self((self) -> self.setUI(new UndecoratedButtonUI()))
                .self((self) -> self.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)))
                .onClicked((self) -> loginId.set(""))
        ),

        // 右端にクリアボタン設置
        ZStack.of
        (
            UIAlignmentX.RIGHT, UIAlignmentY.CENTER,

            // パスワード入力欄
            PasswordField.of(password)
                .rendering(new HintTextRenderer("パスワード"))
                .frame(140, 34),

            // クリア・ボタン
            Button.of(new ClearIcon(16, 16))
                .self((self) -> self.setUI(new UndecoratedButtonUI()))
                .self((self) -> self.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)))
                .onClicked((self) -> password.set(""))
        ),

        Spacer.fill(),

        // ログイン・ボタン
        Button.of("ログイン")
            .frame(ViewConstants.Size.BTN_WIDTH, ViewConstants.Size.BTN_HEIGHT)
            .onClicked((self) -> login())
    )
    .padding(ViewConstants.Size.FRAME_PADDING)
);

開発者の一部は、この発表を受け、肯定的なコメントをしている。

オー、コレハ... Swing デモ SwiftUI ノヨウナ カキカタガ デキルンスネー

JavaのGUIフレームワークはJavaFX以降、新しいフレームワークは提供されておらず、SwingUIの登場でJavaでのフロントエンド開発が進むことが期待される。

ちゃんと説明します🙋🏻

私が初めて宣言的UIに出会ったのはSwiftUIでした。それまで主流だったXMLでのデザイン作成が嫌で(コードで書かせて!)、新しい仕組みの登場を十数年待ちわびていました。そんな私の前に突如として現れたSwiftUI。その出会った時の感動は今も忘れません(ちょと大げさ過ぎました。スミマセン…)。

コードなのにHTMLライクに階層的に記述でき、それでいてCSSJSといった、別言語を組み合わせる必要もない。直感的に素晴らしいと思いました(理解不能なバグたちに出会うまでは…)。

昔は趣味でよくSwingをイジっていて、スマホのフロントエンドをメインの仕事にしたのも、その経験があったからこそでした(もちろん業務でSwing開発なんてなかったですけど)。ある時、「SwingでもSwiftUIのように記述できないかなぁー」、と思い、挑戦したものの全然ダメ。しばらくはそんな願望は忘れていたのですが、ふとある時に「何か今ならできそうな気がする!」と感じ、やってみると、それなりのモノができ上がりました。

ただ、私自身がSwingを知り尽くした猛者ではないことから、その内に行き詰りました。特にコンポーネントをZ軸方向に重ねる場合、下になるコンポーネントがひとつだけの場合は良かったのですが、パネルに乗せた複数コンポーネントだと、それらコンポーネント表示が崩れ、その解決にかなり苦悶しました。AIエージェントが登場した後にも、色々助けを借りながらトライしてみましたが、やはりダメ。最終的に諦め、現在に至ります。

今回の記事は日の目を見なかったSwingUIをとりあえず誰かの視界にでも入れば… くらいの気持ちで書いてみました。ジョーク記事なのですが、何か記念になれば良かったんです。お騒がせしました。テヘッ😝

ところで、もうJavaで新しいGUIフレームワークは出ないのでしょうか? なんだかモッタイないな、って気持ちです。。。

SwingUI適用アプリ動画
https://www.youtube.com/watch?v=hPO9b2dUjDk

GitHubで編集を提案

Discussion