2008-10-24 33 views

Respuesta

116

Sugeriré humildemente Seesaw.

Here's a REPL-based tutorial que no asume ningún conocimiento de Java o Swing.


Balancín es muy parecido a lo que sugiere @tomjen. Aquí es "Hola, mundo":

(use 'seesaw.core) 

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

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

¡Eso se ve muy bien! – danlei

+2

haciendo Swing Fun? ¡Dijeron que no era posible! –

+7

No hay necesidad de ser humilde, ¡puede estar muy orgulloso de este! +1! – mydoghasworms

14

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, sería digno de mirar la sección de la página web de interoperability clojure.

+3

Sí, sé que puedes recurrir al uso de Swing directamente, pero me pregunto si hay una forma más lisa de hacerlo. – Marko

+0

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 pendientes. –

+0

@Juegos - editó la respuesta para reflejar que – dsm

16

Si desea hacer la programación de GUI apuntaría a Temperature Converter o the ants colony.

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

Ahora entiendo a dónde va con la manera 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, pero para hacer algo más Lispy: comience a escribir su aplicación Swing y resuma 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 se 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.

+2

No se preocupe por perder Mattisse. Puede usar http://www.miglayout.com/, que es lo suficientemente potente como para poder hacer los diseños a mano. – tomjen

+0

Puede usar Matisse con Clojure, porque el código generado es solo código de Java al que Clojure puede acceder sin problemas. De hecho, hay un tutorial para eso en algún lugar ... – Rayne

+3

Me pregunto cuándo obtendremos el primer diseñador de GUI que saca Clojure. Debido a la homoiconicidad, ¡el código generado no debería ser malo! – progo

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.

+1

¿Puede proporcionar un enlace o un ejemplo? Me interesaría pero no tengo idea de cómo comenzar. –

+1

Carl, segundo eso. Un buen tutorial sobre cómo escribir complementos de Eclipse usando clojure sería bastante agradable. –

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 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.

Existen algunos inconvenientes en este enfoque, que espero analizar con más detalle en el Grupo Clojure de Google. 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, requiriendo que uses estado mutable, etc.

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

4

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

No creo que hay un oficial, pero personalmente me gustaría aprovechar el hecho de que estoy usando uno de los idiomas más poderoso en el mundo y simplemente imaginar lo que sería el código de interfaz gráfica de usuario perfecta como:

(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 diferiría pero esto debería ser una esperanza, lo anterior le da una idea.

+0

Parece genial SwingBuilder dsl traducido a Clojure. – Marko

+0

@ dev-er-dev Eso es muy posible, nunca he usado groovy, pero las grandes mentes hacen cosas similares :) – tomjen

+1

@Ralph, ahh, el punto es probablemente "moo". –

8

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

de DSM ejemplo re-escriben de forma lispy 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))) 
1

Yo sé que usted está insinuando de soluciones de escritorio clásicos, pero 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. Simplemente diciendo que la aplicación de escritorio no es la única forma :)

13

Todavía nadie lo sugirió, por lo que hará lo siguiente: 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 a hiccup, ClojureScript y cualquiera de los miles de millones de librerías de JS que necesite. Si desea un comportamiento coherente del navegador y la "aplicación de escritorio parece", puede bundle chrome with your app.

Esto parece ser cómo se distribuye Light Table.

+0

esto es genial, pero determinar el puerto correcto puede ser complicado en todas las máquinas cliente – scape

5

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

Inicié mi GUI con subibaja y luego probé con 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 la manera de seguir adelante.

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

Trabajos de ligaduras, trabajo de oyentes, la mayor parte del trabajo con componentes, de lo contrario, simplemente use una de las macros para crear un constructor para ese caso particular y 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.

+0

¿Ha resuelto JavaFX los problemas de no parecer muy original aún? Una pregunta seria, porque cuando la revisé por primera vez, fue hace mucho tiempo, y parecía menos correcta que Swing. – Trejkaz

1

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 utilizar, asegúrese de que está utilizando una versión reciente de Java (1,8 90+) y agregar una dependencia al repositorio GitHub añadiendo lo siguiente a su project.clj:

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

I lo he probado, y funciona de la caja.

Cuestiones relacionadas