Skip to content

React-like, declarative Kotlin library for creating Swing desktop apps

License

Notifications You must be signed in to change notification settings

karol-202/uranium-swing

Repository files navigation

uranium-swing

Deployment Download License: MIT

uranium-swing is a Kotlin library allowing you to create Swing-based desktop applications using a concise DSL in React way. For more details how the uranium library works, visit the Uranium page.

Contents

How to install?

uranium-swing is located in jCenter, you can add it as a dependency to your Gradle or Maven project.

Gradle (Kotlin DSL):

dependencies {
    implementation("pl.karol202.uranium.swing:uranium-swing:0.2.2")
}

Gradle (Groovy):

dependencies {
    implementation "pl.karol202.uranium.swing:uranium-swing:0.2.2"
}

Maven:

<dependency>
    <groupId>pl.karol202.uranium.swing</groupId>
    <artifactId>uranium-swing</artifactId>
    <version>0.2.2</version>
</dependency>

Make sure that you have jCenter in your repositories section:

repositories {
    jcenter()
}

Comparision with Swing

Swing like many other UI libraries is based on the imperative paradigm. That means, that in order to have layout, first you have to create a container, then create components and then add the components to container. Thing can get messy, when your layouts are nested. More problems arises, when it comes to state management.

With Uranium instead of writing such code:

class NamePanel(initialName: String) : JPanel(), ActionListener
{
	private lateinit var textField: JTextField
	private lateinit var label: JLabel
	
	init
	{
		layout = BoxLayout(this, BoxLayout.Y_AXIS)

		val label = JLabel()

		val textField = JTextField(createText(initialName))
		textField.addActionListener(this)

		add(label)
		add(textField)
	}

	override fun actionPerformed(e: ActionEvent?)
	{
		label.text = createText(textField.text)
	}

	private fun createText(text: String) = "Hello, $text"
}

you can write:

class NameComponent(props: Props) : SwingAbstractAppComponent<NameComponent.Props>(props),
                                    UStateful<NameComponent.State>
{
    data class Props(override val key: Any,
                     val initialName: String) : UProps

    data class State(val name: String) : UState

    override var state by state(State(props.initialName))

    override fun SwingRenderScope.render() = boxLayout(axis = BoxAxis.Y) {
        + textField()
                .text(state.name)
                .onTextChange(::setName)
        + label()
                .text("Hello, ${state.name}")
    }

    private fun setName(text: String) = setState { copy(name = text) }
}

The latter one is much more convenient, scalable and easy to manage when it comes to state management (thanks to the unidirectional data flow).

State of the project

During the development of this project a lot of design flaws and inconsistent behaviours of Swing has been discovered, so I'm not sure whether this library should be still developed. Probably no further features will have been introduced and only little improvements and bug fixes will be done.

Contributing

Contributions are highly welcome.

If you find a bug or would like have some feature implemented, file an issue. You can also create a pull request if you have working solution for some issue.

About

React-like, declarative Kotlin library for creating Swing desktop apps

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages