Communityコーディング&開発github.com

java-swing

Build, design, fix, review and test Java Swing desktop apps so they look modern and stay fast. Use when code imports javax.swing or java.awt, or the task mentions Swing, JFrame, JTable, JList, JTree, the EDT, FlatLaf, look and feel, a dated or ugly UI, a frozen or flickering window, HiDPI/display scaling, dark mode, custom painting, big data in tables or lists, UI/visual tests, xvfb, or packaging a Java desktop app with jpackage.

java-swing とは?

java-swing is a Claude Code agent skill that build, design, fix, review and test Java Swing desktop apps so they look modern and stay fast. Use when code imports javax.swing or java.awt, or the task mentions Swing, JFrame, JTable, JList, JTree, the EDT, FlatLaf, look and feel, a dated or ugly UI, a frozen or flickering window, HiDPI/display scaling, dark mode, custom painting, big data in tables or lists, UI/visual tests, xvfb, or packaging a Java desktop app with jpackage.

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/bdarwin/java-swing-skill/tree/HEAD/skills/java-swing

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Java Swing

Swing can build apps that look current and handle huge data, but its defaults point the other way: a 2005 look, one thread for everything, and components designed for small data at 1x scaling. This skill is how to get from the defaults to a good app.

Workflow for any UI work

  1. Find what's there: look and feel, layout style, the background-task helper, the test setup, the app's spacing and colors. Follow them.
  2. New app? Start from templates/desktop-app/: FlatLaf, a sidebar/header/content/status layout, empty states, dark mode, settings, remembered window bounds, keyboard shortcuts, and a screenshot test. Rename and build on it.
  3. Build it following the rules below and references/design.md.
  4. Look at it. You can't see the window, so render it: examples/Snapshot.java writes PNGs of any panel, without a display. Render light and dark, 1x and 2x, the empty state, a narrow window and long text. Open the images and review them with the checklist at the end of references/design.md. Fix and render again. Don't call UI work done without having looked.
  5. Test it: logic in plain unit tests, components painted headless, the real window in a visual test (references/testing.md).

Taste: the short version

Read references/design.md before building or restyling a screen. In brief:

  • FlatLaf, one accent color, one corner radius. Never Metal for a user-facing app.
  • A clear window anatomy: sidebar for places, header with a large title and the one primary action, content with room, a quiet status bar.
  • Spacing from one scale (4, 8, 12, 16, 24, 32), 24–32 px from window edges. Group with space and small headings, never TitledBorder/etched boxes.
  • Type hierarchy from two or three sizes (FlatLaf h1…h4, small) and one muted color for secondary text. Sentence case. Verbs on buttons.
  • Every view has an empty state with a line of explanation and the action that fills it. Loading is inline, never a modal "Please wait". Errors appear inline next to what failed, and say what to do.
  • Few dialogs. Inline editing and undo instead of "Are you sure?".
  • Keyboard: every action in a menu, frequent ones with platform shortcuts shown in menus and tooltips.

The five engineering rules

  1. Touch components only on the Event Dispatch Thread (EDT). Create, change, read and lay out components inside SwingUtilities.invokeLater, including the first window in main. Models (TableModel, Document, ListModel) count as components.
  2. Never block the EDT. Every file, network, process, database or lock wait goes to a background thread, even if it "should be fast". File.exists() on a network drive, InetAddress.getByName, Process.waitFor, Files.size on a cloud folder and a JDBC connect have all frozen real windows. Results come back with invokeLater.
  3. Collapse floods of updates. A background thread that calls invokeLater per item (per line, per row, per progress tick) buries the EDT. Post at most one pending update that reads the latest state (examples/Coalescer.java).
  4. Paint only what is visible, and never wait in paintComponent. If data isn't in memory, draw a placeholder, load it in the background, repaint() when it arrives.
  5. Resolve colors, fonts and sizes at paint time. Colors stored in fields break dark-mode switches; pixel math assuming 1x breaks at 125%/150% scaling.

Doing common jobs right

JobDoDon't
Long task with a resultSwingWorker or your executor, then invokeLater(() -> show(result))Run it in actionPerformed
Progress from a workerStore progress in an atomic field, post one coalesced updateinvokeLater per item
Add/remove componentsrevalidate() then repaint() on the parentOnly repaint(), or validate() off the EDT
Switch viewsCardLayout.show(parent, name)Put one component in two containers (it leaves the first)
ShortcutsKeyStroke with getMenuShortcutKeyMaskEx() (⌘ on macOS, Ctrl elsewhere)Hard-code CTRL_DOWN_MASK
Key bindingsInputMap/ActionMap, or an Action with an accelerator in a menuKeyListener
Custom paintingOverride paintComponent, call super, g.create() and dispose()Override paint, or change state in paint
Theme colorsFlatLaf styles with $Key references, UIManager.getColor in paint, or examples/LiveColor.javanew Color(...) fields set once
List/table rows with several partsA renderer panel that sets every property per call, and is opaque with its background set (FlatLaf then rounds the selection)A panel per row in a BoxLayout
Text in a grid (editors, logs)Measure at 1x, draw with drawGlyphVector (examples/GridText.java)drawString at fractional scales
Millions of rowsA view whose scroll bar counts rows (examples/VirtualRowView.java)JTable with DefaultTableModel
Files opened from FinderDesktop.setOpenFileHandler(...)Only main(String[] args)
One window per appexamples/SingleInstance.java (file lock + loopback socket)A second window per double-click

Reference files

Read the one that matches the task:

  • references/design.md: taste: window anatomy, spacing, type, color, controls, icons, empty/loading/error states, dialogs, wording, review checklist.
  • references/threading.md: EDT rules, SwingWorker limits, executors, stale results, coalescing, modal dialogs from workers, finding violations and stalls, shutdown.
  • references/big-data.md: where JTable/JList stop, compact models, sorting millions of rows, paint that never waits, virtual views, wide tables, overview bars.
  • references/painting-and-hidpi.md: paintComponent, rendering hints, fractional scaling, text on a grid, crisp lines, icons and images, animation, charts.
  • references/theming.md: FlatLaf, how UIResource decides colors, dark mode switching, palettes, fonts, FlatLaf client properties.
  • references/layout.md: choosing layouts, sizes from fonts, revalidate, one parent per component, CardLayout, JSplitPane, JScrollPane, wrapping rows, RTL.
  • references/tables-lists-trees.md: renderers, models, view vs. model indexes, sorting, editing, columns, selection, lazy trees.
  • references/text-components.md: choosing a text component, documents and threads, validation, search fields, highlights, undo, HTML in Swing.
  • references/dialogs-focus-keyboard.md: dialogs done right, focus, key bindings, accessibility, tooltips, popup menus.
  • references/dnd-clipboard.md: dropping files (including Linux text/uri-list), dragging inside the app, clipboard.
  • references/testing.md: unit, headless component and visual tests, waiting instead of sleeping, the displayable trap, responsiveness tests, xvfb in CI, packaged-app tests.
  • references/desktop-integration.md: macOS, Windows and Linux specifics, single instance, jpackage, startup time, settings, updates and errors.
  • references/performance.md: finding the cause, fast painting, less EDT work, budgets.

Copyable helpers (examples/)

Dependency-free classes, compiled and checked by tests/SelfTest.java in CI. Copy one and change its package:

FileWhat it does
Snapshot.javaRenders any panel or window to PNG, at any scale, without a display
OnEdt.javaTest helpers: run on the EDT with results and exceptions, waitFor with a message, settle
Coalescer.javaAt most one pending EDT update for a flood of changes
EdtWatchdog.javaMeasures EDT responsiveness and records where it was stuck
EdtViolationChecker.javaReports components changed off the EDT (debug/tests)
LiveColor.javaA Color that follows light/dark switches
GridText.javaMonospaced text that stays on its grid at 125%/150%/175%
VirtualRowView.javaScrolls hundreds of millions of rows; paint never waits for data
SingleInstance.javaOne window for the app; later launches hand over their files

Traps that waste hours

SymptomCause
Rows of a list/table are blank in a headless screenshot or testThe tree isn't displayable, so renderer panels never lay out. Snapshot.render calls addNotify(); do the same.
FlatLaf shows no rounded selection in a list with a custom rendererThe renderer isn't opaque, or its background isn't set to the selection color when selected
A color stays light after switching to darkIt was set with a plain Color; use a $Key style, UIManager at paint time, or LiveColor
Text drifts from its highlights at 125% on WindowsFontMetrics and drawString disagree at fractional scales; use GridText
setDividerLocation(0.3) does nothingCalled before the split pane has a size; call after the window is shown
A component vanished from one panelIt was added to another; a component has one parent
Window freezes only for some usersFile or network calls on the EDT that are slow on their drives or network
The app stays running after the window closedA non-daemon thread, a running javax.swing.Timer, or an undisposed window
A KeyListener shortcut works only sometimesIt needs focus; use key bindings or menu accelerators
Sorted table edits the wrong rowView index used as model index; convertRowIndexToModel

When reviewing Swing code

Look for, in order of how often they hurt users:

  1. I/O, sleep, join, waitFor, locks or invokeAndWait inside listeners, paintComponent or anything they call.
  2. Components, models or Documents touched from executor threads, java.util.Timer, library callbacks (HTTP, SSH, JDBC, file watchers).
  3. invokeLater inside a loop over data.
  4. Work in paintComponent that grows with the data rather than the visible area.
  5. Colors, fonts, borders or icons computed once and stored; titled/etched borders; Metal.
  6. Pixel math assuming 1x; FontMetrics from one context, drawing in another.
  7. Tests that sleep and then assert, or check focus/tooltips without waiting.
grep -rn "invokeAndWait" src/main          # can it run on the EDT, or while holding a lock?
grep -rn "Thread.sleep" src/main           # any on the EDT?
grep -rn "java.util.Timer\b" src/main      # callbacks run off the EDT
grep -rnE "new Color\(|Color\.(WHITE|BLACK|GRAY)" src/main/java   # fixed colors that ignore dark mode
grep -rnE "TitledBorder|EtchedBorder|createTitledBorder" src/main/java   # dated grouping
grep -rn "MetalLookAndFeel\|getCrossPlatformLookAndFeel" src/main/java

関連スキル