日本語
GitHub
テーマ

Java のデスクトップ UI

Java のデスクトップアプリを、ゼロから描く。

Limn はピクセルを自分で描きます。ウィジェット、レイアウト、テキスト、チャート、メディア、3D ビューポートが依存 1 つで手に入り、Swing も JavaFX も、下敷きになるネイティブツールキットもありません。

JDK 17 · Windows, macOS, Linux · Apache-2.0

Claude Code で、隠さずに作っています。コードを書いたのは Claude、方向を決めて検証したのは人間です。作るためのコストはもう支払われているので、あなたがもう一度支払う必要はありません。 Limn の作り方

このビルド中に Limn が描画したデモアプリケーション。
このビルド中に Limn が描画したデモアプリケーション。
このビルド中に Limn が描画したデモアプリケーション。

今すぐ試す

デモとテーマエディターを、Maven Central から直接。クローン不要。JDK がなければ jbang が取得します。JBang は最新リリースを一度だけ解決して保持します。より新しいリリースを取得するには --fresh を付けてください。

# ショーケース
jbang demo@limn-toolkit/limn-toolkit
# テーマエディタ
jbang theme-editor@limn-toolkit/limn-toolkit
# ショーケース
jbang --java-options=-XstartOnFirstThread demo@limn-toolkit/limn-toolkit
# テーマエディタ
jbang --java-options=-XstartOnFirstThread theme-editor@limn-toolkit/limn-toolkit

5 分

依存 1 つと main メソッド

マークアップ言語も、アノテーションプロセッサーも、ビルドプラグインもありません。ツールキットを連れてくるバックエンドを追加して素の Java を書けば、ウィンドウができます。

インストールガイドを読む
build.gradle.kts
dependencies {
    implementation("io.github.limn-toolkit:limn-backend-lwjgl:1.0.0")
}
pom.xml
<dependency>
  <groupId>io.github.limn-toolkit</groupId>
  <artifactId>limn-backend-lwjgl</artifactId>
  <version>1.0.0</version>
</dependency>
Main.java
import limn.backend.Backend;
import limn.backend.NativeWindow;
import limn.backend.WindowConfig;
import limn.backend.lwjgl.LwjglBackend;
import limn.components.Button;
import limn.components.Label;
import limn.scene.Insets;
import limn.scene.Scene;
import limn.scene.layout.Column;
import limn.scene.layout.Padding;

/** A window with a label and a button that closes it. */
public final class HelloWindow {

    public static void main(String[] args) {
        // macOS needs -XstartOnFirstThread on the JVM command line; it is macOS-only and a
        // JVM elsewhere given it will not start.
        try (Backend backend = new LwjglBackend()) {
            NativeWindow window = backend.createWindow(
                    WindowConfig.of("Hello, Limn", 480, 320));

            Column column = new Column();
            column.gap(12);
            column.add(new Label("A window, drawn by Limn."));
            column.add(new Button("Close").onAction(window::requestClose));

            Scene scene = new Scene(new Padding(Insets.all(24), column));
            scene.bind(window);

            backend.runEventLoop();
        }
    }
}

手に入るもの

自分で作らなくていいコンポーネント一式

ボタン、入力欄、リスト、テーブル、ツリー、日付ピッカー、タブ、メニュー、ダイアログ、カード、分割ペイン、カラーピッカー、棒・折れ線・ドーナツのチャート、そして 100 万行でも 20 行と同じコストで済む仮想化リスト。どれも色・形・密度をテーマから読むので、ハードコードされた値はなく、コンパクトモードは 1 行です。ウィンドウの外でも、アプリケーションは紙や PDF に印刷し、トレイにアイコンを置き、macOS のメニューバーにメニューを出し、ほかのプログラムとドラッグ&ドロップでやり取りします。

すべて見る
Button
Button
ComboBox
ComboBox
Slider
Slider
SegmentedControl
SegmentedControl
Checkbox and switch
Checkbox and switch
Spinner
Spinner

頭に収まるレイアウト

ウィジェット 6 つとマーカー 1 つ。列は積み、行は並べ、ラップは幅が尽きると次の行へ折り返し、グリッドはセルを縦横にそろえ、スタックは重ね、パディングは内側に寄せ、Expanded が残りの空間を誰が取るかを決めます。Opacity と Transform は、周りのレイアウトを乱さずに、ウィンドウの一部をフェードさせ、動かし、拡大縮小し、回転させます。設定すべき制約ソルバーも、導入すべきレイアウトマネージャーもありません。

レイアウトガイドを読む
Limn でレイアウトしたウィンドウ
Limn でレイアウトしたウィンドウ
列、行、分割、そして Expanded 1 つで組んだウィンドウ。

フレームワークのないフォーム

入力欄はウィジェット、検証ルールはリスナー、送信はメソッド呼び出しです。バインドするものも登録するものもなく、ユーザーが直したその瞬間に入力欄の色が戻ります。

フォームガイドを読む
Limn で作ったフォーム
Limn で作ったフォーム
ラベル、検証、選択、そしてアクション行。

テーブルも、ツリーも、日付も、作ってあります

テーブルは、アプリケーションが持つリストの上に置く型付きの列で、ツールキットかあなたのサーバーが並べ替え、フッターが合計します。ツリーは、あなたが渡す子要素の上に置くアウトラインで、行は子の名前を挙げられる前から子がいると約束できます。日付フィールドは読み手自身の暦で ISO の日付を入力し、日付ピッカーはその後ろに月のグリッドを開きます。

リストガイドを読む
Limn のウィンドウに並んだテーブル、ツリー、2 つの日付ウィジェット
Limn のウィンドウに並んだテーブル、ツリー、2 つの日付ウィジェット
1 つのウィンドウに並んだテーブル、ツリー、日付フィールド、日付ピッカー。

動画も 3D もウィジェット

物理ベースの 3D ビューポートと動画プレーヤーが、普通のウィジェットとして合成されます。スクロールビューが切り取り、スタックが上に描き、ラベルと同じようにレイアウトに参加します。

メディアガイドを読む
Limn の 3D ビューポート
Limn の 3D ビューポート
普通のウィンドウに合成された 3D ビューポート。

すべての人へ

あらゆる言語と、あらゆるスクリーンリーダー

ユーザーの言語で

ラテン文字・ギリシャ文字・キリル文字・CJK がひとつの文字列に混在し、フォントは同じ文字体系の連なりごとに選ばれます。アラビア文字、ヘブライ文字、デーヴァナーガリー、タイ文字は正しく整形され(連結形、合字、結合記号)、右から左へ書く言語ではウィンドウ全体が鏡像になります:行、余白、スクロールバー、矢印キー。入力メソッドはフィールド内で変換し、編集は書記素単位で進みます。

テキストのガイドを読む
同じ画面を日本語・簡体中国語・韓国語・ロシア語で撮影し、一つの窓に継ぎ合わせたもの。
同じ画面を日本語・簡体中国語・韓国語・ロシア語で撮影し、一つの窓に継ぎ合わせたもの。
このビルド中に 4 言語で撮った、同じ画面。

同じ言語で、読み上げられる

Windows 上のスクリーンリーダー、macOS の VoiceOver、Linux の Orca は、各プラットフォーム自身のアクセシビリティ API を通して Limn のウィンドウを読み上げます。アプリケーションにプラットフォーム固有のコードは不要です。各コントロールは、インターフェースの表示言語で、ロール・名前・状態を自分で伝えます。コントロールに名前を付けるのは呼び出しひとつです。

アクセシビリティガイドを読む
  1. heading“Create your account”
  2. label“Full name”
  3. text field“Full name”label · focusable, editable, required
  4. label“12 / 40”
  5. label“Email”
  6. text field“Email”label · focusable, editable, invalid, required
  7. label“Enter an address like ada@example.com”
  8. label“Password”
  9. password field“Password”label · focusable, editable, password
  10. label“At least 12 characters”
  11. label“Plan”
  12. combo box“Plan”label · focusable, expandable, has-popup
  13. switch“Email me release notes”focusable, checked
  14. separatorhorizontal
上のフォームを、スクリーンリーダーに伝えられるとおりに。このビルド中に取得。

あなたの製品の見た目に、ツールキットの見た目を持ち込まない

アプリケーションは、それを作ったライブラリではなく、あなたの製品らしく見えるべきです。テーマは単なるデータ(すべての色、角の丸み、各コントロールが継承するサイズ段階)で、実行中に一度の呼び出しで差し替わります。ブランドの書体は自分の管理下のファイルから読み込めるので、ツールキット由来の見た目は何も残りません。

テーマの仕組み
コントロールが密に並ぶ同じ画面を七回横並びに描画したもの。帯ごとにパレット、サイズ段階、書体が異なります。

同じコンポーネント、7 つのテーマ

列にポインターを合わせると、そのテーマが画面全体に広がります。列をタップするとそのテーマが表示され、横にスワイプすると切り替わります。

一つの画面、七つのテーマ。どの帯も背後のコードは同一です。

隠さずに

Limn の作り方

Limn のコードは、Anthropic のモデルである Claude が Claude Code の中で書き、人間が方向を決めて検証しています。知っておきたいはずのことなので、最初にお伝えします。

方向を決めるとは、設計上の決定をすべてコードより先に docs/adr の文書として書き、議論し、承認することです。検証するとは、すべての変更を、コード本体より大きなテストスイートにかけること、アクセシビリティを推測ではなく実際に聞いて確かめること(Windows 上のスクリーンリーダー、macOS の VoiceOver、Linux の Orca に実際のウィンドウを読ませて)、そして正しさ・性能・API 設計について監査を繰り返すことです。

ここまでに、何千回ものモデル呼び出しと何百万もの生成トークンを費やしました。見積もりモデル COCOMO II によれば、テストを除いても 10 万行を超えるコードは、約 20 人のチームが 2 年以上かけて行う仕事に相当します。その仕事はもう済んでいます。やり直す代わりに、その上に作ることができます。

設計記録を読む

5 分で画面にウィンドウを

インストールガイドは動くプログラムで終わります。その先はガイドと、コンポーネントギャラリーと、API リファレンスです。