Solving JavaFX’s CSS problems with cljfx css
We like to browse GitHub and occasionally shed some light on interesting or useful open source repositories. Today we are taking a closer look at a few projects written in Clojure: clfx and cljfx css. Cljfx css is “charmingly simple styling” for cljfx. What’s under the hood of this styling library for JavaFX? Find out how it simplifies CSS for JavaFX and what requirements you need to run it.
JavaFX is a client application platform used for devices built on Java; the latest version landed in September. Today, we are highlighting two projects for JavaFX built with Clojure, both by the same creator.
GitHub user vlaaad developed the Cljfx and Cljfx CSS repos.
Cljfx is a declarative, functional Clojure wrapper for JavaFX. It is dynamic and provides a reagent-like experience for JavaFX apps.
Under the hood, it takes some design inspiration from different parts of React, re-frame, and fn-fx.
From the README:
Like react, it allows to specify only desired layout, and handles all actual changes underneath. Unlike react (and web in general) it does not impose xml-like structure of everything possibly having multiple children, thus it uses maps instead of hiccup for describing layout.
Like reagent, it allows to specify component descriptions using simple constructs such as data and functions. Unlike reagent, it rejects using multiple stateful reactive atoms for state and instead prefers composing ui in more pure manner.
Like re-frame, it provides an approach to building large applications using subscriptions and events to separate view from logic. Unlike re-frame, it has no hard-coded global state, and subscriptions work on referentially transparent values instead of ever-changing atoms.
Like fn-fx, it wraps underlying JavaFX library so developer can describe everything with clojure data. Unlike fn-fx, it is more dynamic, allowing users to use maps and functions instead of macros and deftypes, and has more explicit and extensible lifecycle for components.
In order to extend cljfx to fill in the missing gaps, users can create extension lifecycles. Creating an extension lifecycle requires a deep knowledge of cljfx. Refer to the cljfx.lifecycle namespace for an example of how it is implemented.
On November 5, 2019, it added support for Java 8 with version 1.6.0.
tools.deps, Clojure 1.10 or newer, and
cljfx added as a maven dependency.
Let’s take a look at a styling library for JavaFX built in Clojure. Cljfx css is a styling library for JavaFX. CSS (Charmingly Simple Styling) can be implemented with vanilla JavaFX or with cljfx. Thus, it can be used with all JavaFX apps built with Clojure.
According to the Cljfx CSS’s README, the rationale for its creation came from a desire to fix the problems CSS causes in JavaFX.
Unfortunately, CSS is unavoidable, because controls don’t provide access to their internal nodes, and they can be targeted only with CSS selectors. What’s worse, JavaFX does not allow loading CSS from strings or some other data structures, instead expecting an URL pointing to a CSS file. In addition to that, CSS is not always enough for styling JavaFX application: not every Node is styleable (for example, Shapes aren’t). All this leads to a slow iteration cycle on styling and also to duplication of styling information in CSS and code.
The library fixes all of the aforementioned issues by using a set of recommendations. It does so by providing a way for users to configure application style using Clojure data structures. With it, users can rapidly iterate in a live app.
Users can define styles, register them, and feed the constructed URL to JavaFX.
The CSS guidelines for JavaFX can oftentimes be complicated and involves a few confusing priority rules. Thus, the creator of cljfx css recommends users have the official reference guide on hand when styling applications.
Clojure version 1.10 is required for cljfx css.