What is the best way to do GUIs in Clojure?

What is the best way to do GUIs in Clojure?

Is there an example of some functional Swing or SWT wrapper? Or some integration with JavaFX declarative GUI description which could be easily wrapped to s-expressions using some macrology?

Any tutorials?

Asked by: Roland914 | Posted: 28-01-2022

Answer 1

I will humbly suggest Seesaw.

Here's a REPL-based tutorial that assumes no Java or Swing knowledge.

Seesaw's a lot like what @tomjen suggests. Here's "Hello, World":

(use 'seesaw.core)

(-> (frame :title "Hello"
       :content "Hello, Seesaw"
       :on-close :exit)

and here's @Abhijith and @dsm's example, translated pretty literally:

(ns seesaw-test.core
  (:use seesaw.core))

(defn handler
  (alert event
    (str "<html>Hello from <b>Clojure</b>. Button "
      (.getActionCommand event) " clicked.")))

(-> (frame :title "Hello Swing" :on-close :exit
           :content (button :text "Click Me" :listen [:action handler]))

Answered by: Miller448 | Posted: 01-03-2022

Answer 2

Stuart Sierra recently published a series of blog posts on GUI-development with clojure (and swing). Start off here: http://stuartsierra.com/2010/01/02/first-steps-with-clojure-swing

Answered by: Lily407 | Posted: 01-03-2022

Answer 3

If you want to do GUI programming I'd point to Temperature Converter or the ants colony.

Many things in Swing are done by sub-classing, particularly if you are creating custom components. For that there are two essential functions/macros: proxy and gen-class.

Now I understand where you are going with the more Lispy way. I don't think there's anything like that yet. I would strongly advise against trying to build a grandiose GUI-building framework a-la CLIM, but to do something more Lispy: start writing your Swing application and abstract out your common patterns with macros. When doing that you may end up with a language to write your kind of GUIs, or maybe some very generic stuff that can be shared and grow.

One thing you lose when writing the GUIs in Clojure is the use of tools like Matisse. That can be a strong pointing to write some parts in Java (the GUI) and some parts in Clojure (the logic). Which actually makes sense as in the logic you'll be able to build a language for your kind of logic using macros and I think there's more to gain there than with the GUI. Obviously, it depends on your application.

Answered by: Rubie283 | Posted: 01-03-2022

Answer 4

Nobody yet suggested it, so I will: Browser as UI platform. You could write your app in Clojure, including an HTTP server and then develop the UI using anything from HTML to hiccup, ClojureScript and any of the billions of JS libaries you need. If you wanted consistent browser behaviour and "desktop app look'n'feel" you could bundle chrome with your app.

This seems to be how Light Table is distributed.

Answered by: Ada246 | Posted: 01-03-2022

Answer 5

From this page:

(import '(javax.swing JFrame JButton JOptionPane)) ;'
(import '(java.awt.event ActionListener))          ;'

(let [frame (JFrame. "Hello Swing")
     button (JButton. "Click Me")]
 (.addActionListener button
   (proxy [ActionListener] []
     (actionPerformed [evt]
       (JOptionPane/showMessageDialog  nil,
          (str "<html>Hello from <b>Clojure</b>. Button "
               (.getActionCommand evt) " clicked.")))))

 (.. frame getContentPane (add button))

 (doto frame
   (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
   (.setVisible true)))

print("code sample");

And, of course, it would be worth looking at the interoperability section of clojure's website.

Answered by: Kevin634 | Posted: 01-03-2022

Answer 6

There is a wrapper for MigLayout in clojure contrib. You can also take a look at this gist. I am basically putting up whatever code I am writing as I am learning swing/miglayout.

dsm's example re-written in a lispy way using contrib.swing-utils

(ns test
      (:import (javax.swing JButton JFrame))
      (:use (clojure.contrib
          [swing-utils :only (add-action-listener)])))

    (defn handler
      (JOptionPane/showMessageDialog nil,
        (str "<html>Hello from <b>Clojure</b>. Button "
          (.getActionCommand event) " clicked.")))

    (let [ frame (JFrame. "Hello Swing") 
           button (JButton. "Click Me")  ]
      (add-action-listener button handler)
        (doto frame
          (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
          (.add button)
          (.setVisible true)))

Answered by: Abigail191 | Posted: 01-03-2022

Answer 7

I would rather go for clojurefx, it is a bit premature, but it does work and saves you time.

I started my GUI with seesaw and then tried another component in clojurefx.

I have finished both, and I am convinced that I am going to refactor the seesaw one to clojurefx.

After all, JavaFX is the way to go forward.

It feels lighter than seesaw. Or at least, writing it..

Bindings work, listeners work, most of the component work, otherwise, just use one of the macros to create a constructor for that particular case and job done. Or, if you find it difficult, write some methods in Java and ask for help to improve clojurefx.

The guy who wrote clojurefx is busy at the moment, but you can fork the project and do some fixes.

Answered by: Lucas217 | Posted: 01-03-2022

Answer 8

There's been talk on the mailing list about a few Cells (a la Kenny Tilton's Cells) implementations. It's a pretty neat way to do GUI programming.

Answered by: Robert394 | Posted: 01-03-2022

Answer 9

Here is another very basic swing wrapping example:

; time for some swing
(import '(javax.swing JFrame JTable JScrollPane))
(import '(javax.swing.table DefaultTableModel))

  [frame (JFrame. "Hello Swing")
    dm (DefaultTableModel.)
      table (JTable. dm)
        scroll (JScrollPane. table)]
  (doto dm
      (.setNumRows 30)
        (.setColumnCount 5))
  (.. frame getContentPane (add scroll))
    (doto frame
      (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE) 
        (.setVisible true)))

Answered by: Elise308 | Posted: 01-03-2022

Answer 10

I asked myself the same question of writing a GUI in Clojure with Swing and came up with the library signe

It lets you use represent your domain model as a single Clojure data structure wrapped inside an atom.

See the examples here.

Answered by: Elise936 | Posted: 01-03-2022

Answer 11

I've been developing a Java applet in which everything is written in Clojure except the applet code, which is written in Java. The applet invokes the Clojure code's callbacks of init, paint, etc from java's hooks for those methods that are defined by the applet model. So the code ends up being 99.999 percent Clojure and you don't have to think about the tiny Java piece at all for the most part.

There are some drawbacks to this approach, which I hope to discuss in more detail on the Clojure Google Group. I think the Clojure developers should include a native way of building applications. Presently you can do whatever GUI stuff you like from the REPL, but if you want a deliverable GUI application, it is necessary to write some Java to call the Clojure code. Also, it seems like the architecture of a Java Applet kind of forces you outside of Clojure's more idiomatic best practices, requiring you to use mutable state, etc.

But also, I am not very far along with Clojure yet and it might be the case that it is possible and I just haven't discovered how to do it correctly yet.

Answered by: Anna542 | Posted: 01-03-2022

Answer 12

I don't think there is an official one, but personally I would take advantage of the fact that I am using one of the most powerful language in the world and just imagine what the perfect gui code would look like:

(form {:title :on-close dispose :x-size 500 :y-size 450}
  [(button {:text "Close" :id 5 :on-click #(System/exit 0) :align :bottom})
   (text-field {:text "" :on-change #(.println System/out (:value %)) :align :center})
   (combo-box {:text "Chose background colour" :on-change background-update-function
               :items valid-colours})])

Your idea would differ but this should hopefully the above gives you some idea.

Answered by: Dexter571 | Posted: 01-03-2022

Answer 13

My preferred Clojure UI environment uses IO.js (Node for ES6) + Electron (Container) + Quiescent (ReactJS wrapper).

Answered by: Miranda147 | Posted: 01-03-2022

Answer 14

So I didn't see Fn-Fx on this list, from Timothy Baldridge (halgiri). This is a Clojure library providing a functional abstraction over JavaFX.

It can be found on Github at https://github.com/halgari/fn-fx.

To use, make sure you are using a recent version of Java (1.8 90+) and add a dependency to the github repo by adding the following to your project.clj:

:plugins [[lein-git-deps "0.0.1-SNAPSHOT"]]
:git-dependencies [["https://github.com/halgari/fn-fx.git"]]

I have tried it, and it works out of the box.

Answered by: Michael415 | Posted: 01-03-2022

Answer 15

Clojure and SWT is the best approach for doing GUI(s). Essentially, SWT is a plug and play style approach for developing software.

Answered by: Victoria486 | Posted: 01-03-2022

Answer 16

I know that you are hinting for classical desktop solutions, but web fits quite well with clojure. I've written a complete audio application where everything is hooked up so that if you add music to the audio folder it is reflected in the web UI. Just saying that Desktop application isn't the only way :)

Answered by: John116 | Posted: 01-03-2022

Answer 17

cljfx is described as a

Declarative, functional and extensible wrapper of JavaFX inspired by better parts of react and re-frame

and JavaFx as

... an open source, next generation client application platform for desktop, mobile and embedded systems built on Java. It is a collaborative effort by many individuals and companies with the goal of producing a modern, efficient, and fully featured toolkit for developing rich client applications.

Its creator uses it to build reveal, and a hackernews demo that features various capabilities and some bundling for multiple OSs via jpackage.

You can get Clojure REPL-driven development with this by leveraging JavaFX to build UIs for desktop, mobile, and web.

Answered by: Roman694 | Posted: 01-03-2022

Similar questions

java - Clojure While Loop

I trying clojure i am trying to figure out how to implement the following algorithm, I am reading from an input stream i want to continue reading until it is not a delimiter character. i can do this in java with a while loop but i can't seem to figure out how to do it in clojure? while read readChar != delimiter do some processing.... end while

java - Weird Clojure Box - library (dll) issue

I am trying to use the JACOB library with Clojure using Clojure Box. I have added this to my .emacs: (setq swank-clojure-library-paths (list "c:/dev/dlls")) C:/dev/dlls/ contains the jacob-1.14.3-x86.dll. I have added a .clojure dir to my ~/ dir and that contains the jacob.jar. At the Clojure Box REP...

java - Clojure While Loop

I trying clojure i am trying to figure out how to implement the following algorithm, I am reading from an input stream i want to continue reading until it is not a delimiter character. i can do this in java with a while loop but i can't seem to figure out how to do it in clojure? while read readChar != delimiter do some processing.... end while

clojure - How do I include java stuff in .jar files?

Okay. So here's my question: I am making a data parser in Clojure. One part of my program is that it has to be able to graph the data. I figure, I'll use jFreeChart. However, I have absolutely NO IDEA how to include stuff in JAR files. What I mean is: if I have a app.jar file in my classpath, I don't seem to be able to do: import app.thing.thing2 without changing the classpath to be inside the jar file....

clojure - What does the future look like for Java Applets?

In the past, java applets were unreliable, due to the Microsoft/Sun JVM split. Flash took over, and Java applets became known for browser crashes and performance issues. Now that the JVM is enjoying resurgence as a platform for dynamic languages like Clojure and Scala, what is the current and future outlook for the JVM for in-browser applets? Are browser vendors continuing to address ...

api - Java for Clojure users

I've been using Lisp on and off, and I'm catching up with clojure. The good thing about clojure is that I can use all the java functions naturally, and the bad thing about clojure is also that I have to know java function naturally. For example, I had to spend some time (googling) to find square function in Java (Math/sqrt in clojure notation). Could you recommend me some good information resource for Java...

java - Attach a clojure / scala repl to a running JVM

I have a java web application running under tomcat in a Sun java 6 JVM. Is there a way to attach a scala or clojure REPL to the running JVM ? Once the webapp is up and running, the context in which the calls are to be made is already setup in the running VM. Hence, this can be really helpful in invoking arbitrary java method calls for incremental, exploratory development and for debugging.

Does all clojure code work within a java proxy?

I was wondering if there is any clojure code or macros that does not work when embedded within a clojure proxy for java code, eg: (proxy [Some Java Interface] [] (some Java Method [args] ... Clojure code ... ) ) Or, can I only embed calls to Java functions within the proxy?

java - GUI sys tray app on Ubuntu with Clojure

I want to make a GUI application for Ubuntu written in Clojure (so using Java GUI libraries). I know how to write Swing apps, to run as 'normal' GUI apps. I want to do something a little different and am not sure how to approach it; I want to write a program to run in the sys tray, and every X minutes remind me something in a small window that shows near the sys tray. Thanks for the help, Alex

java - JUnit and Clojure unit testing

I'm creating a library that includes both Clojure and Java code, and would like to be able to run a single test JUnit suite across the entire code base. Seems that this should be possible since they are both running on the JVM and there is good Clojure/Java interop. However, currently Clojure code seems to favour unit testing done through the clojure.test API using "(run-all-tests)" and friends. Is there a ...

Java to Clojure rewrite

I have just been asked by my company to rewrite a largish (50,000 single lines of code) Java application (a web app using JSP and servlets) in Clojure. Has anyone else got tips as to what I should watch out for? Please bear in mind that I know both Java AND Clojure quite well. Update I did the rewrite and it went into production. It's quite strange as the rewrite ended up going so fast that it was...

Still can't find your answer? Check out these amazing Java communities for help...

Java Reddit Community | Java Help Reddit Community | Dev.to Java Community | Java Discord | Java Programmers (Facebook) | Java developers (Facebook)