world tutorial rich hickey hello example java user-interface lisp clojure

java - tutorial - ¿Cuál es la mejor manera de hacer GUI en Clojure?



clojure vs scala (16)

¿Cuál es la mejor manera de hacer GUI en Clojure ?

¿Hay algún ejemplo de algún contenedor Swing o SWT ? ¿O alguna integración con la descripción de GUI declarativa de JavaFX que podría ser fácilmente ajustada a s-expressions usando alguna macrología?

¿Algún tutorial?


Aquí hay otro ejemplo muy básico de envolver columpios.

; time for some swing (import ''(javax.swing JFrame JTable JScrollPane)) (import ''(javax.swing.table DefaultTableModel)) (let [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) (.pack) (.setVisible true)))


Así que no vi Fn-Fx en esta lista, de Timothy Baldridge (halgiri). Esta es una biblioteca de Clojure que proporciona una abstracción funcional sobre JavaFX.

Se puede encontrar en Github en https://github.com/halgari/fn-fx .

Para usarlo, asegúrese de estar utilizando una versión reciente de Java (1.8 90+) y agregue una dependencia al repositorio github agregando lo siguiente a su proyecto.clj:

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

Lo he intentado, y funciona de la caja.


Clojure y SWT es el mejor enfoque para hacer GUI (s). Esencialmente, SWT es un enfoque de estilo plug and play para desarrollar software.


De esta 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) .pack (.setVisible true))) print("code sample");

Y, por supuesto, valdría la pena mirar la sección de interoperabilidad del sitio web de clojure.


Hay un contenedor para MigLayout en clojure contrib. También puedes echar un vistazo a http://gist.github.com/261140 . Básicamente estoy poniendo cualquier código que estoy escribiendo mientras estoy aprendiendo swing / miglayout.

Ejemplo de dsm reescrito de manera lisina usando contrib.swing-utils

(ns test (:import (javax.swing JButton JFrame)) (:use (clojure.contrib [swing-utils :only (add-action-listener)]))) (defn handler [event] (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) (.pack) (.setVisible true)))


He estado desarrollando un applet de Java en el que todo está escrito en Clojure, excepto el código del applet, que está escrito en Java. El applet invoca las devoluciones de llamada del código de Clojure de init, paint, etc. desde los ganchos de java para aquellos métodos que están definidos por el modelo de applet. Entonces el código termina siendo 99.999 por ciento Clojure y no tienes que pensar en la pequeña pieza de Java en su mayor parte.

Hay algunos inconvenientes en este enfoque, que espero analizar con más detalle en el Grupo de Google Clojure. Creo que los desarrolladores de Clojure deberían incluir una forma nativa de crear aplicaciones. En la actualidad, puede hacer las cosas de GUI que desee desde REPL, pero si desea una aplicación de GUI entregable, es necesario escribir algo de Java para llamar al código de Clojure. Además, parece que la arquitectura de un applet de Java te obliga a estar fuera de las mejores prácticas idiomáticas de Clojure, lo que requiere que uses un estado mutable, etc.

Pero también, no estoy muy lejos con Clojure todavía y podría ser el caso de que sea posible y aún no haya descubierto cómo hacerlo correctamente todavía.




Nadie lo sugirió aún, así que lo haré: navegador como plataforma de interfaz de usuario. Podrías escribir tu aplicación en Clojure, incluido un servidor HTTP y luego desarrollar la interfaz de usuario utilizando cualquier cosa, desde HTML hasta hiccup , ClojureScript y cualquiera de los miles de millones de libretas de JS que necesites. Si desea un comportamiento coherente del navegador y una "apariencia de escritorio de la aplicación", puede combinar Chrome con su aplicación .

Esta parece ser la forma en que se distribuye Light Table .


No creo que haya uno oficial, pero personalmente me gustaría aprovechar el hecho de que estoy usando uno de los lenguajes más poderosos del mundo e imaginar cómo sería el código gui perfecto:

(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})])

Tu idea sería diferente, pero espero que lo anterior te dé una idea.


Prefiero ir a clojurefx, es un poco prematuro, pero funciona y le ahorra tiempo.

Inicié mi GUI con sube y baja y luego probé con otro componente en clojurefx.

He terminado ambos, y estoy convencido de que voy a refacturar el balancín uno para clojurefx.

Después de todo, JavaFX es la forma de avanzar.

Se siente más ligero que el balancín. O al menos, escribiéndolo ...

Las vinculaciones funcionan, los oyentes trabajan, la mayoría del trabajo de componentes; de lo contrario, simplemente use una de las macros para crear un constructor para ese caso particular y para el trabajo realizado. O, si le resulta difícil, escriba algunos métodos en Java y solicite ayuda para mejorar clojurefx.

El tipo que escribió clojurefx está ocupado en este momento, pero puedes dividir el proyecto y hacer algunas correcciones.


Sé que está sugiriendo soluciones de escritorio clásicas, pero la web encaja bastante bien con clojure. He escrito una aplicación de audio completa donde todo está conectado de modo que si agrega música a la carpeta de audio se refleja en la interfaz de usuario web. Solo digo que la aplicación de escritorio no es la única manera :)



Si quieres programar la GUI, apuntaré a Convertidor de temperatura o a la colonia de hormigas .

Muchas cosas en Swing se realizan subclasificando, especialmente si está creando componentes personalizados. Para eso hay dos funciones / macros esenciales: proxy y gen-class .

Ahora entiendo a dónde vas con la forma más Lispy. No creo que haya algo así todavía. Recomiendo encarecidamente no intentar crear un grandioso marco de construcción de GUI a-la CLIM , sino hacer algo más Lispy: comenzar a escribir su aplicación Swing y abstraer sus patrones comunes con macros. Al hacer eso, puede terminar con un lenguaje para escribir su tipo de GUI, o tal vez algunas cosas muy genéricas que pueden ser compartidas y crecer.

Una cosa que pierde al escribir las GUI en Clojure es el uso de herramientas como Matisse. Ese puede ser un fuerte apunte para escribir algunas partes en Java (la GUI) y algunas partes en Clojure (la lógica). Lo cual realmente tiene sentido, ya que en la lógica podrás construir un lenguaje para tu tipo de lógica usando macros y creo que hay mucho más que ganar que con la GUI. Obviamente, depende de tu aplicación.



Sugeriré Seesaw .

Aquí hay un tutorial basado en REPL que asume que no hay conocimiento de Java o Swing.

El balancín se parece mucho a lo que @tomjen sugiere. Aquí está "Hello, World":

(use ''seesaw.core) (-> (frame :title "Hello" :content "Hello, Seesaw" :on-close :exit) pack! show!)

y aquí está el ejemplo de @Abhijith y @ dsm, traducido bastante literalmente:

(ns seesaw-test.core (:use seesaw.core)) (defn handler [event] (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])) pack! show!)