| name | swing-flatlaf-miglayout-principles |
| description | Use when modifying EasyPostman Swing forms that use FlatLaf and MigLayout, especially when layout refactors introduce clipped focus rings, truncated text, clipped status badges, dense spacing, border conflicts, or inconsistent form structure. |
Swing FlatLaf MigLayout Principles
Use this skill when editing Swing form layouts in this repo. The goal is not just fixing one bug, but following stable layout principles that work well with FlatLaf and MigLayout.
When to use
- A
JTextField, JPasswordField, or JComboBox looks fine until focused
- Focus/highlight borders are clipped or hidden
- A list item, sidebar row, badge, tab, or localized label is truncated or spills out of its container
- A refactor added borders, cards, sections, or sub-panels and spacing became unstable
- A dense toolbar/form row in MigLayout starts to look cramped or visually inconsistent
- A Swing form in EasyPostman needs to be reorganized without regressing FlatLaf behavior
Core principles
-
Preserve focus visibility first.
In this repo, form controls must keep the full FlatLaf focus ring visible on all sides.
-
Prefer layout fixes over padding hacks.
If the issue appears only on focus, suspect layout constraints or border interaction before adding more empty space.
-
Avoid decorative borders around dense input areas.
Dense forms usually behave better with separators, spacing, and simple line borders than with TitledBorder.
-
Keep form hierarchy shallow.
Extra wrapper panels often make focus rendering and spacing harder to reason about.
-
Follow existing repo form patterns.
Reuse the simpler top-bar/form-row patterns already used in other toolbox panels where possible.
-
Treat localized text as variable-width UI.
English status strings and Chinese labels can have very different widths. Do not rely on one locale fitting a fixed row.
Preferred fix order
-
Check whether the affected container uses MigLayout.
If yes, evaluate whether visualPadding is the real cause.
-
Add novisualpadding to the relevant MigLayout containers first.
Apply it to the form layout and the immediate child panels that place focusable controls.
-
If clipping remains, simplify borders around the focused components.
Prefer:
EmptyBorder
- a plain
LineBorder
- separators between sections
-
Only then tune insets/gaps.
Padding should refine the layout, not compensate for the wrong layout model.
-
If a refactor introduced titles inside borders, remove the titles first.
If grouping is still needed, use borderless sections plus separators, or a plain line border without title text.
-
For truncated text or badges in list renderers, inspect row/column constraints before changing fonts.
Long labels in [pref!], shrink 0, or same-row title/status layouts can force clipping inside fixed-width sidebars.
Narrow list and badge layouts
- In fixed-width sidebars, avoid putting a variable-length title and a variable-length status badge in the same row.
Prefer:
- row 1: title spans all columns with
span 2, growx, wmin 0, wrap
- row 2: version/meta in a growing column, compact status badge in a right-aligned
pref column
- Keep
wmin 0 on labels that may need to shrink or ellipsize. Without it, MigLayout can preserve the label's preferred width and push siblings out.
- Use
shrink 0 only for controls or badges whose displayed text is intentionally short. Never apply it to long localized status strings.
- If a status must be semantically long, add a short list-specific i18n key for the badge and keep the full text in the details panel or tooltip.
- Do not fix repeated clipping by reducing font sizes. Use
FontsUtil only to preserve hierarchy after the layout constraints are correct.
- Recheck both installed and marketplace renderers when they share the same list pattern; otherwise the bug usually comes back in the sibling view.
Repo-specific guidance
- For module placement before changing shared UI, read
docs/ARCHITECTURE_MODULES_zh.md and keep reusable Swing components, colors, fonts, icons, notifications, and editor theme helpers in easy-postman-ui.
- Kafka top connection form is the known reference case:
easy-postman-plugins/plugin-kafka/src/main/java/com/laker/postman/plugin/kafka/connection/ui/KafkaConnectionPanel.java
- The correct direction there was:
- keep the layout in MigLayout
- add
novisualpadding
- avoid titled section borders
- reintroduce only plain borders after focus behavior is stable
- If the user says "it is probably MigLayout", take that seriously and verify MigLayout constraints before touching theme or component code.
Theme entry points in this repo
When the task is about light/dark theme colors instead of layout, start from these files instead of scattering hard-coded colors in panel code:
- Shared semantic colors for both themes:
easy-postman-ui/src/main/java/com/laker/postman/common/constants/ModernColors.java
- FlatLaf light theme tokens and component defaults:
easy-postman-app/src/main/resources/com/laker/postman/common/themes/EasyLightLaf.properties
- FlatLaf dark theme tokens and component defaults:
easy-postman-app/src/main/resources/com/laker/postman/common/themes/EasyDarkLaf.properties
- RSyntaxTextArea editor theme for light mode:
easy-postman-app/src/main/resources/themes/easypostman-light.xml
- RSyntaxTextArea editor theme for dark mode:
easy-postman-app/src/main/resources/themes/easypostman-dark.xml
Use the files with this intent:
ModernColors.java
Use for shared semantic brand colors such as primary blue, hover blue, status colors, and colors referenced directly by custom Swing painting or custom components.
EasyLightLaf.properties / EasyDarkLaf.properties
Use for FlatLaf UI defaults such as Component.accentColor, Table.selectionBackground, Tree.selectionBackground, TabbedPane.*, borders, backgrounds, and hover states.
easypostman-light.xml / easypostman-dark.xml
Use only for editor syntax colors inside RSyntaxTextArea. These files are loaded by EditorThemeUtil, not by FlatLaf itself.
Preferred order when adjusting theme:
- If the change is a shared accent or semantic status color, start with
ModernColors.java.
- If the change is a standard Swing/FlatLaf control state, start with
EasyLightLaf.properties or EasyDarkLaf.properties.
- If the change is only about code editor token colors, caret, selection, or current-line styling, change the
easypostman-*.xml files.
- Do not hard-code new colors directly in panels before checking whether one of the files above is the right source of truth.
Design heuristics for this repo
- Top tool panels should prefer:
- one clear outer border strategy
- simple horizontal/vertical separators
- compact but not crowded form rows
- Section grouping should be visual, not heavy-handed.
- If a grouped layout costs too much vertical space or breaks focus rendering, simplify it.
- Sidebars with action/status rows should favor scanability over cramming: let the main label breathe, then place status/meta on the next row.
Anti-patterns
- Stacking
EmptyBorder repeatedly without changing MigLayout behavior
- Keeping
TitledBorder on dense editable forms after focus clipping appears
- Solving a layout bug by moving controls farther apart without understanding the container behavior
- Adding more nested panels than the visual structure actually needs
- Combining long title text and long status text in a fixed-width list row with both components preserving preferred width
- Adding absolute point-size font tweaks to make one English string fit
Verification
After the fix, verify all of the following:
- Focus a text field in the affected row.
- Focus a combo box in the same area.
- Confirm the highlight ring is visible on top, bottom, left, and right.
- Confirm spacing still looks intentional when the control is unfocused.
- For truncation fixes, verify the longest English and Chinese labels/statuses in the affected fixed-width container.
- Rebuild with
mvn -q -DskipTests compile.