繁體中文
GitHub
主題

Java 的桌面 UI

用 Java 寫桌面應用程式,像素自己畫。

Limn 自己畫出每一個像素。元件、版面、文字、圖表、媒體與 3D 視埠,只要一個相依套件,沒有 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

五分鐘

一個相依套件和一個 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();
        }
    }
}

你會得到什麼

一套不必自己做的元件

按鈕、輸入欄、清單、表格、樹狀結構、日期選擇器、分頁、選單、對話框、卡片、分割窗格、選色器,長條圖、折線圖與環圈圖,還有一個虛擬化清單,其中一百萬列的成本與二十列相同。每一個都從主題讀取顏色、形狀與密度,所以沒有寫死的值,緊湊模式只要一行。在視窗之外,應用程式還能列印到紙上或輸出 PDF,在系統匣放一個圖示,把選單放進 macOS 的選單列,並與其他程式互相拖放。

查看全部
Button
Button
ComboBox
ComboBox
Slider
Slider
SegmentedControl
SegmentedControl
Checkbox and switch
Checkbox and switch
Spinner
Spinner

裝得進腦袋的版面

六個元件加一個標記:欄往下堆疊,列往旁鋪開,折行容器在寬度用盡時另起一行,網格讓各個格子橫豎對齊,堆疊層層相覆,內距往內縮,Expanded 決定誰拿走剩下的空間。Opacity 與 Transform 讓視窗的一部分淡入淡出、移動、縮放與旋轉,而不打亂周圍的版面。沒有約束求解器要設定,也沒有版面管理員要安裝。

閱讀版面指南
用 Limn 排版的視窗
用 Limn 排版的視窗
由一欄、一列、一個分割與一個 Expanded 組成的視窗。

不需要框架的表單

欄位就是元件,驗證規則就是監聽器,送出就是一次方法呼叫。沒有要繫結的,也沒有要註冊的;使用者一改正,驗證狀態就把欄位的顏色換回來。

閱讀表單指南
用 Limn 建構的表單
用 Limn 建構的表單
標籤、驗證、一個選項與動作列。

表格、樹與日期,已經做好

表格是架在你的應用自己持有的清單上的具型別欄位,由工具包或你的伺服器排序,還有一列會加總的表尾。樹是架在你提供的子節點上的大綱,一列可以在說出子節點名字之前先承諾它們存在。日期欄位以讀者自己的曆法輸入一個 ISO 日期,日期選擇器則在它後面打開一個月份格線。

閱讀清單指南
Limn 視窗中的表格、樹狀清單與兩個日期元件
Limn 視窗中的表格、樹狀清單與兩個日期元件
一個視窗裡的表格、樹、日期欄位與日期選擇器。

影片與 3D 同樣是元件

基於物理的 3D 視埠與影片播放器,像一般元件那樣參與合成:捲動視圖會裁切它們,堆疊會畫在它們上面,它們參與版面的方式和一個標籤沒有兩樣。

閱讀媒體指南
Limn 的 3D 視口
Limn 的 3D 視口
合成進一般視窗中的 3D 視埠。

為每一個人

每一種語言,每一種螢幕閱讀器

用你的使用者的語言

拉丁、希臘、西里爾與中日韓文字可混在同一個字串裡,字型按同一種文字的連續片段選擇。阿拉伯文、希伯來文、天城文和泰文會被正確塑形——連寫、合字、附加符號——由右至左的語言則讓整個視窗鏡像:列、邊距、捲軸、方向鍵。輸入法在欄位內組字,編輯按字素移動。

閱讀文字指南
同一個介面分別用日語、簡體中文、韓語與俄語擷取,拼接成一個視窗。
同一個介面分別用日語、簡體中文、韓語與俄語擷取,拼接成一個視窗。
同一個畫面,在本次建置中以四種語言擷取。

用同樣的語言,讀出來

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
上面的表單,正如螢幕閱讀器被告知的那樣,在本次建置中擷取。

是你的產品氣質,不是工具包的

你的應用該像你的產品,而不像它所依賴的那個函式庫。主題就是純資料(每一種顏色、圓角半徑、每個控件繼承的尺寸級距),執行時一次呼叫即可整套替換。品牌字體從你自己掌握的檔案載入,工具包自帶的觀感一點都不會留下。

主題是怎麼運作的
同一個控件密集的介面並排渲染七次,每一條都用不同的配色、尺寸級距與字體。

同樣的元件,七種主題

把指標移到某一欄上,就能看到該主題鋪滿整個畫面。點按某一欄查看該主題,左右滑動即可切換。

同一個介面,七套主題。每一條背後的程式碼完全相同。

公開

Limn 是怎麼做出來的

Limn 的程式碼由 Anthropic 的模型 Claude 在 Claude Code 中撰寫,由人來掌握方向並加以驗證。我們一開始就說明這一點,因為你會想知道。

掌握方向,指的是每一項設計決定都先在 docs/adr 裡寫成文字、經過論證並被接受,然後才有程式碼。加以驗證,指的是每一次變更都要跑過比程式碼本身還龐大的測試套件;無障礙不靠假設,而是真的去聽——讓 Windows 上的螢幕閱讀器、macOS 的 VoiceOver 和 Linux 的 Orca 朗讀真實的視窗;程式碼也經過多輪關於正確性、效能與 API 設計的稽核。

走到這一步,用了成千上萬次模型呼叫和數以百萬計的生成 token。依 COCOMO II 估算模型,不計測試,這十餘萬行程式碼相當於一支約二十人的團隊兩年多的工作量。這份工作已經做完了。你可以在它之上建構,而不必重做一遍。

閱讀設計紀錄

五分鐘,讓視窗出現在畫面上

安裝指南以一個跑得起來的程式收尾。之後的一切,就是指南、元件展示與 API 參考。