SwingTree is a Swing based UI framework for creating boilerplate free
and composition based Swing UIs fluently.
Think Jetpack Compose, SwiftUI or Flutter but for Swing
(similar to JetBrain's UI DSL).
- lightweight and intuitive HTML like GUI code - powerful layout declaration based on `MigLayout` - compatible with custom swing components and legacy Swing code - a functional lambda friendly API for peeking into the underlying UI tree and manipulating swing components freely - concise event registration through `onClick`, `onChange` methods... - advanced styling through a CSS like DSL API - [animated styling](docs/markdown/An-Advanced-Style-Animation.md) | |
- built-in [property support](https://github.com/globaltcad/sprouts) for [MVVM](docs/markdown/Advanced-MVVM.md) and [MVI](docs/markdown/Functional-MVVM.md) architecture (for decoupling UI and business logic) - user friendly [stability oriented error handling](docs/markdown/Sane-Error-Handling.md) - tried, tested and used extensively in production | - [Motivation](docs/markdown/Motivation.md) - [Getting Started](docs/markdown/Climbing-Swing-Tree.md) - [Living Documentation](https://globaltcad.github.io/swing-tree/) |
Here an example of a simple calculator UI based on the FlatLaF
look-and-feel:
This was made using the following code:
FlatLightLaf.setup();
UI.of(this/*JPanel subtype*/).withLayout("fill, insets 10")
.add("grow, span, wrap",
UI.panel("fill, ins 0")
.add("shrink", UI.label("Result:"))
.add("grow, wrap",
UI.label("42.0", UI.HorizontalAlignment.RIGHT)
.withProperty("FlatLaf.styleClass", "large")
)
.add("grow, span, wrap", UI.textField(HorizontalAlignment.RIGHT, "73 - 31"))
)
.add("growx", UI.radioButton("DEG"), UI.radioButton("RAD"))
.add("shrinkx", UI.splitButton("sin"))
.add("growx, wrap", UI.button("Help").withProperty("JButton.buttonType", "help"))
.add("growx, span, wrap",
UI.panel("fill")
.add("span, grow, wrap",
UI.panel("fill, ins 0")
.add("grow",
UI.button("(").withProperty("JButton.buttonType", "roundRect"),
UI.button(")").withProperty("JButton.buttonType", "roundRect")
)
)
.add("grow",
UI.panel("fill, ins 0, wrap 3")
.apply( it -> {
String[] labels = {"7","8","9","4","5","6","1","2","3","0",".","C"};
for ( var l : labels ) it.add("grow", UI.button(l));
}),
UI.panel("fill, ins 0")
.add("grow", UI.button("-").withProperty("JButton.buttonType", "roundRect"))
.add("grow, wrap", UI.button("/").withProperty("JButton.buttonType", "roundRect"))
.add("span, grow, wrap",
UI.panel("fill, ins 0")
.add("grow",
UI.button("+").withProperty("JButton.buttonType", "roundRect"),
UI.panel("fill, ins 0")
.add("grow, wrap",
UI.button("*").withProperty("JButton.buttonType", "roundRect"),
UI.button("%").withProperty("JButton.buttonType", "roundRect")
)
),
UI.button("=")
.withBackground(new Color(103, 255, 190))
.withProperty("JButton.buttonType", "roundRect")
)
)
);
As you can see, swing tree has a very simple API, which only requires a
single class to be imported, the UI
class which can even be imported
statically to remove any UI.
prefixes.
Also, note that there are usually 2 arguments
added to a builder object:
a String
and then UI nodes.
This first argument simply translates
to the layout constraints which should be applied
to the UI element(s) added.
In this example, these are passed to the default layout manager,
a MigLayout
instance,
which is the most general purpose layout manager.
(However you can also use other layout managers of course.)
For more examples take a look at the examples folder inside the test suite.
<dependency>
<groupId>io.github.globaltcad</groupId>
<artifactId>swing-tree</artifactId>
<version>0.12.0</version>
</dependency>
Groovy DSL:
implementation 'io.github.globaltcad:swing-tree:0.12.0'
Kotlin DSL:
implementation("io.github.globaltcad:swing-tree:0.12.0")
1. Add the JitPack url in your root build.gradle
at the end of repositories
allprojects {
repositories {
//...
maven { url 'https://jitpack.io' }
}
}
2. Add swing-tree as dependency
...either by specifiying the version tag:
dependencies {
implementation 'com.github.globaltcad:swing-tree:0.12.0'
}
...or by using a custom commit hash instead:
dependencies {
implementation 'com.github.globaltcad:swing-tree:68f56d3'//Any commit hash...
}