Respostas:
Vou sugerir humildemente Gangorra .
Aqui está um tutorial baseado em REPL que não assume nenhum conhecimento sobre Java ou Swing.
Gangorra é muito parecido com o que sugere @tomjen. Aqui está "Olá, Mundo":
(use 'seesaw.core)
(-> (frame :title "Hello"
:content "Hello, Seesaw"
:on-close :exit)
pack!
show!)
e aqui está o exemplo de @Abhijith e @ dsm, traduzido 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!)
Stuart Sierra publicou recentemente uma série de postagens no blog sobre desenvolvimento de GUI com clojure (e swing). Comece aqui: http://stuartsierra.com/2010/01/02/first-steps-with-clojure-swing
Se você quiser fazer a programação da GUI, eu apontaria para o Temperature Converter ou a colônia de formigas .
Muitas coisas no Swing são feitas por subclassificação, principalmente se você estiver criando componentes personalizados. Para isso, existem duas funções / macros essenciais: proxy e gen-class .
Agora eu entendo para onde você está indo da maneira mais Lispy. Eu não acho que exista algo assim ainda. Eu desaconselharia fortemente a tentativa de criar uma estrutura grandiosa de criação de GUI à la CLIM , mas para fazer algo mais Lispy: comece a escrever seu aplicativo Swing e abstraia seus padrões comuns com macros. Ao fazer isso, você pode acabar com um idioma para escrever seu tipo de GUI, ou talvez algo muito genérico que possa ser compartilhado e aumentado.
Uma coisa que você perde ao escrever as GUIs no Clojure é o uso de ferramentas como o Matisse. Isso pode ser um forte argumento para escrever algumas partes em Java (a GUI) e algumas partes em Clojure (a lógica). O que realmente faz sentido, pois na lógica você poderá criar uma linguagem para seu tipo de lógica usando macros e acho que há mais a ganhar lá do que com a GUI. Obviamente, isso depende da sua aplicação.
Ninguém o sugeriu ainda, então vou: Navegador como plataforma de interface do usuário. Você pode escrever seu aplicativo no Clojure, incluindo um servidor HTTP e, em seguida, desenvolver a interface do usuário usando qualquer coisa, desde HTML a soluços , ClojureScript e qualquer um dos bilhões de bibliotecas JS necessárias. Se você quiser um comportamento consistente do navegador e "aparência do aplicativo de desktop", poderá agrupar o chrome no seu aplicativo .
Parece que é assim que a Light Table é distribuída.
Nesta 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");
E, é claro, valeria a pena examinar a seção de interoperabilidade do site da clojure.
Existe um invólucro para o MigLayout no controj clojure. Você também pode dar uma olhada nessa essência . Basicamente, estou colocando o código que estou escrevendo enquanto aprendo swing / miglayout.
O exemplo do dsm reescrito de uma maneira 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)))
Houve uma discussão na lista de discussão sobre algumas implementações do Cells (a Kenell Tilton's Cells ). É uma maneira bastante elegante de fazer a programação da GUI.
Eu prefiro usar o clojurefx, é um pouco prematuro, mas funciona e economiza tempo.
Comecei minha GUI com gangorra e tentei outro componente no clojurefx.
Eu terminei os dois e estou convencido de que vou refatorar a gangorra para clojurefx.
Afinal, JavaFX é o caminho a seguir.
Parece mais leve que gangorra. Ou pelo menos, escrevendo ..
As ligações funcionam, os ouvintes funcionam, a maioria dos componentes funciona; caso contrário, basta usar uma das macros para criar um construtor para esse caso e trabalho específico. Ou, se você achar difícil, escreva alguns métodos em Java e peça ajuda para melhorar o clojurefx.
O cara que escreveu o clojurefx está ocupado no momento, mas você pode bifurcar o projeto e fazer algumas correções.
Aqui está outro exemplo muito básico de empacotamento de giro:
; 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)))
Estou desenvolvendo um applet Java no qual tudo está escrito no Clojure, exceto o código do applet, que está escrito em Java. O applet chama os retornos de chamada do código Clojure, init, paint, etc, dos ganchos do java para os métodos definidos pelo modelo do applet. Portanto, o código acaba sendo 99,999% do Clojure e você não precisa pensar na menor parte do Java na maior parte do tempo.
Existem algumas desvantagens nessa abordagem, que espero discutir com mais detalhes no Clojure Google Group. Eu acho que os desenvolvedores do Clojure devem incluir uma maneira nativa de criar aplicativos. Atualmente, você pode fazer qualquer coisa da GUI do REPL, mas se você quiser um aplicativo de GUI entregável, é necessário escrever um pouco de Java para chamar o código Clojure. Além disso, parece que a arquitetura de um Java Applet o força fora das práticas recomendadas mais idiomáticas do Clojure, exigindo o uso de estado mutável etc.
Mas também não estou muito longe com Clojure e pode ser que seja possível e simplesmente não descobri como fazê-lo corretamente ainda.
Meu ambiente de interface do usuário Clojure preferido usa IO.js (Nó para ES6) + Elétron (Contêiner) + Quiescente (wrapper ReactJS) .
Então eu não vi Fn-Fx nesta lista, de Timothy Baldridge (halgiri). Esta é uma biblioteca Clojure que fornece uma abstração funcional sobre JavaFX.
Pode ser encontrado no Github em https://github.com/halgari/fn-fx .
Para usar, verifique se você está usando uma versão recente do Java (1.8 90+) e adicione uma dependência ao repositório do github adicionando o seguinte ao seu projeto.clj:
:plugins [[lein-git-deps "0.0.1-SNAPSHOT"]]
:git-dependencies [["https://github.com/halgari/fn-fx.git"]]
Eu tentei, e funciona fora da caixa.
Clojure e SWT são a melhor abordagem para fazer GUI (s). Essencialmente, o SWT é uma abordagem de estilo plug and play para o desenvolvimento de software.
Eu não acho que exista um oficial, mas pessoalmente eu aproveitaria o fato de estar usando uma das línguas mais poderosas do mundo e apenas imagino como seria o código da GUI perfeito:
(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})])
Sua idéia seria diferente, mas espero que o acima tenha uma idéia.
Sei que você está sugerindo soluções clássicas de desktop, mas a web se encaixa muito bem com o clojure. Eu escrevi um aplicativo de áudio completo, onde tudo está conectado, de modo que, se você adicionar música à pasta de áudio, ela será refletida na interface da web. Apenas dizendo que o aplicativo de desktop não é o único caminho :)