Pregunta

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

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

¿Algún tutorial?

¿Fue útil?

Solución

Humildemente sugeriré Seesaw .

Aquí hay un tutorial basado en REPL que no supone ningún conocimiento de Java o Swing.


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

(use 'seesaw.core)

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

y aquí está el ejemplo de @Abhijith y @ dsm, traducido 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!)

Otros consejos

Stuart Sierra publicó recientemente una serie de publicaciones de blog sobre desarrollo de GUI con clojure (y swing). Comience aquí: http://stuartsierra.com/2010/ 01/02 / primeros pasos con clojure swing

Si desea realizar la programación de la GUI, apuntaría a Convertidor de temperatura o la colonia de hormigas .

Muchas cosas en Swing se realizan mediante subclasificación, 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 manera más Lispy. No creo que haya nada de eso todavía. Recomiendo encarecidamente que no intente crear un marco de creación de GUI grandioso a-la CLIM , sino hacer algo. más Lispy: comience a escribir su aplicación Swing y abstraiga 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 compartirse y crecer.

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

De esta página :

(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 ver la sección interoperabilidad del sitio web de clojure.

Nadie lo ha sugerido aún, así que lo haré: Navegador como plataforma de interfaz de usuario. Puede escribir su aplicación en Clojure, incluido un servidor HTTP y luego desarrollar la interfaz de usuario usando cualquier cosa, desde HTML a hipo , ClojureScript y cualquiera de Los billones de libertades de JS que necesitas. Si deseaba un comportamiento coherente del navegador y la " aplicación de escritorio look'n'feel " podría agrupar Chrome con su aplicación .

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

Hay un envoltorio para MigLayout en clojure contrib. También puede consultar este gist . Básicamente, estoy colocando el código que estoy escribiendo mientras estoy aprendiendo swing / miglayout.

El ejemplo de

dsm se reescribió de forma sencilla utilizando 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)))

Ha habido hablar en la lista de correo sobre algunas Cells ( a implementaciones de Celdas de Kenny Tilton ). Es una forma bastante buena de hacer la programación GUI.

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

Comencé mi GUI con balancín y luego probé otro componente en clojurefx.

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

Después de todo, JavaFX es el camino a seguir.

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

Los enlaces funcionan, los oyentes funcionan, la mayoría de los componentes funcionan, de lo contrario, solo use una de las macros para crear un constructor para ese caso particular y el trabajo realizado. O, si lo encuentra 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.

Aquí hay otro ejemplo de ajuste de swing muy básico:

; 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)))

Me hice la misma pregunta de escribir una GUI en Clojure con Swing y encontré la biblioteca signe

Le permite usar representar su modelo de dominio como una única estructura de datos de Clojure dentro de un átomo.

Consulte los ejemplos aquí .

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 Clojure de init, paint, etc. desde los ganchos de java para aquellos métodos que están definidos por el modelo del applet. Así que el código termina siendo 99.999 por ciento de Clojure y no tienes que pensar en la pequeña pieza de Java en su mayor parte.

Este enfoque presenta algunos inconvenientes, que espero analizar más detalladamente en el Grupo de Google Clojure. Creo que los desarrolladores de Clojure deberían incluir una forma nativa de crear aplicaciones. Actualmente, puede hacer cualquier cosa de GUI que desee desde el REPL, pero si desea una aplicación de GUI que se pueda entregar, 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 dejar de lado las mejores prácticas idiomáticas de Clojure, que requieren que uses un estado mutable, etc.

Pero también, todavía no estoy muy de acuerdo con Clojure y puede ser que sea posible y todavía no haya descubierto cómo hacerlo correctamente.

Así que no vi a 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 usar, asegúrate de estar usando una versión reciente de Java (1.8 90+) y agrega una dependencia al repositorio de github agregando lo siguiente a tu project.clj:

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

Lo he intentado y funciona fuera 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.

No creo que haya uno oficial, pero personalmente aprovecharía el hecho de que estoy usando uno de los lenguajes más poderosos del mundo y me imagino 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 esto te dé alguna idea.

Sé que estás 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 para que, si agrega música a la carpeta de audio, se refleje en la interfaz de usuario web. Solo digo que la aplicación de escritorio no es la única manera :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top