globaltcad / swing-tree

A small DSL library for building Swing UIs
MIT License
6 stars 0 forks source link

SwingTree License: MIT Java Version

Modern Declarative UI Design for Swing

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.


Getting started with Apache Maven

<dependency>
  <groupId>io.github.globaltcad</groupId>
  <artifactId>swing-tree</artifactId>
  <version>0.12.0</version>
</dependency>

Getting started with Gradle

Groovy DSL:

implementation 'io.github.globaltcad:swing-tree:0.12.0'

Kotlin DSL:

implementation("io.github.globaltcad:swing-tree:0.12.0")

Getting started with

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...
}