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

Respuestas:

121

Humildemente sugeriré a Seesaw .

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


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!)
Dave Ray
fuente
2
haciendo que Swing sea divertido? ¡Dijeron que no era posible!
Michael Bylstra
9
No hay necesidad de ser humilde, ¡puedes estar muy orgulloso de este! +1!
mydoghasworms
77
-1: Hay un error en tu código. Dice "Hola, balancín" en lugar de "Hola, mundo". </Joke>
Thomas Eding
1
De Verdad? ¿Columpio? ¿No limita esto al desarrollador a la funcionalidad que ofrece Swing, solo en un nivel más alto de abstracción, si existe? ¿Clojure de alguna manera hace que las aplicaciones se vean menos desactualizadas, o de alguna manera mejora todas las áreas en las que Swing es débil? Estoy hablando de enlaces y MVC y todas esas cosas "nuevas", que Swing ahora ofrece per se. ¿Está de alguna manera arreglado por las características del lenguaje de Clojure?
Zelphir Kaltstahl
1
Eligió hacer una abstracción enfocada sobre Swing específicamente. No hay nada de malo en eso ...
Kenogu Labz
16

Si quieres hacer programación de GUI, te diría que convertidor de temperatura o la colonia de hormigas .

Muchas cosas en Swing se hacen subclasificando, particularmente 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 que no intente construir un marco de creación de GUI grandioso a CLIM , pero para hacer algo más Lispy: comience a escribir su aplicación Swing y resuma sus patrones comunes con macros. Al hacerlo, puede terminar con un idioma para escribir su tipo de GUI, o tal vez algunas cosas muy genéricas que pueden compartirse y crecer.

Una cosa que pierde al escribir las GUI en Clojure es el uso de herramientas como Matisse. Eso puede ser un buen punto para escribir algunas partes en Java (la GUI) y algunas partes en Clojure (la lógica). Lo que en realidad 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 más que ganar que con la GUI. Obviamente, depende de su aplicación.

pupeno
fuente
2
No te preocupes por perder a Mattisse. Puede usar miglayout.com , que es lo suficientemente potente como para hacer los diseños a mano.
tomjen
Puede usar Matisse con Clojure, porque el código generado es solo código Java al que Clojure puede acceder sin problemas. En realidad, hay un tutorial para eso en alguna parte ...
Rayne
3
Me pregunto cuándo obtendremos el primer diseñador de GUI de clojure-outputing. Debido a la homoiconicidad, ¡el código generado ni siquiera debería ser malo!
nperson325681
15

Nadie lo sugirió 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 utilizando cualquier cosa, desde HTML hasta hipo , ClojureScript y cualquiera de los miles de millones de bibliotecas JS que necesita. Si desea un comportamiento coherente del navegador y una "apariencia de aplicación de escritorio", puede agrupar Chrome con su aplicación .

Así parece ser cómo se distribuye la mesa de luz .

Matthew Gilliard
fuente
esto es genial, pero determinar el puerto adecuado puede ser complicado en cada máquina cliente
escape
14

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, sería digno de mirar la interoperabilidad sección del sitio web del clojure.

dsm
fuente
3
Sí, sé que puedes recurrir a Swing directamente, pero estaba preguntando si hay una manera más clara de hacerlo.
Marko
También tenga en cuenta que en las versiones más recientes de cierre necesita agregar un. delante de la función miembro llama al bloque de tareas.
Jeroen Dirks
8

Hay un contenedor para MigLayout en clojure contrib. También puedes echar un vistazo a esta esencia . Básicamente estoy poniendo el código que estoy escribiendo mientras estoy aprendiendo swing / miglayout.

El ejemplo de dsm se reescribió de manera simple 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)))
Abhijith
fuente
6

Prefiero ir a clojurefx, es un poco prematuro, pero funciona y le 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 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 trabajan, la mayoría del trabajo de componentes, de lo contrario, solo use una de las macros para crear un constructor para ese caso particular y 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 puede bifurcar el proyecto y hacer algunas correcciones.

Efrain Bergillos
fuente
¿JavaFX ha resuelto los problemas de no parecer muy nativo todavía? Pregunta seria, porque cuando lo revisé por primera vez, fue hace mucho tiempo, y parecía menos correcto que Swing.
Trejkaz
4

Aquí hay otro ejemplo muy básico de envoltura de columpio:

; 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)))
Jeroen Dirks
fuente
3

Me hice la misma pregunta de escribir una GUI en Clojure con Swing y se me ocurrió la señal de la biblioteca

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

Vea los ejemplos aquí .

Rulle
fuente
2

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 definidos por el modelo de applet. Entonces, el código termina siendo 99.999 por ciento de Clojure y no tiene 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 Clojure Google. 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 REPL, pero si desea una aplicación GUI entregable, es necesario escribir algo de Java para llamar al código Clojure. Además, parece que la arquitectura de un Applet de Java lo obliga a salir de las mejores prácticas más idiomáticas de Clojure, lo que requiere que use un estado mutable, etc.

Pero también, todavía no estoy muy lejos de Clojure y podría ser posible y todavía no he descubierto cómo hacerlo correctamente.


fuente
2

Mi entorno de IU Clojure preferido utiliza IO.js (Nodo para ES6) + Electrón (Contenedor) + Quiescente (envoltorio ReactJS) .

TWR Cole
fuente
1
Esto puede ser complejo, pero aún quiero preguntar: ¿Puede proporcionar un ejemplo sobre cómo comenzar con estas piezas? ¿O describa qué parte de una aplicación sería manejada por cuál de esos marcos / bibliotecas que mencionó?
Zelphir Kaltstahl
2

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

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

Para usar, asegúrese de estar usando una versión reciente de Java (1.8 90+) y agregue una dependencia al repositorio de github agregando lo siguiente a su 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.

Bill Barnhill
fuente
1

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

Berlin Brown
fuente
1
¿Puedes proporcionar un enlace o un ejemplo? Me interesaría pero no tengo idea de cómo comenzar.
Carl Smotricz el
1
Carl, segundo eso. Un buen tutorial sobre cómo escribir complementos de Eclipse usando clojure sería bastante bueno.
Egon Willighagen
1

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

Su idea sería diferente, pero es de esperar que lo anterior le dé alguna idea.

tomjen
fuente
Parece un maravilloso SwingBuilder dsl traducido a Clojure.
Marko el
@ dev-er-dev que es muy posible, nunca he utilizado maravilloso, pero las grandes mentes hacer algo por igual :)
tomjen
1

Sé que estás sugiriendo soluciones de escritorio clásicas, pero la web se adapta 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 forma :)

Anders Rune Jensen
fuente