Odpowiedzi:
Pokornie zasugeruję Seesaw .
Oto samouczek oparty na REPL, który nie zakłada znajomości języka Java ani Swing.
Huśtawka jest bardzo podobna do tego, co sugeruje @tomjen. Oto „Witaj świecie”:
(use 'seesaw.core)
(-> (frame :title "Hello"
:content "Hello, Seesaw"
:on-close :exit)
pack!
show!)
a oto przykład @Abhijith i @ dsm, przetłumaczony całkiem dosłownie:
(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 niedawno opublikował serię postów na blogu na temat tworzenia GUI z clojure (i swing). Zacznij tutaj: http://stuartsierra.com/2010/01/02/first-steps-with-clojure-swing
Jeśli chcesz zaprogramować GUI, wskazałbym na konwerter temperatury lub kolonię mrówek .
Wiele rzeczy w Swing jest wykonywanych przez podklasy, szczególnie jeśli tworzysz komponenty niestandardowe. W tym celu istnieją dwie podstawowe funkcje / makra: proxy i klasa gen .
Teraz rozumiem, dokąd zmierzasz w bardziej zawzięty sposób. Chyba jeszcze nie ma czegoś takiego. Zdecydowanie odradzałbym próbę budowania wspaniałego frameworka do budowania GUI a-la CLIM , ale zrobienie czegoś bardziej Lispy: zacznij pisać swoją aplikację Swing i wyodrębnij swoje typowe wzorce za pomocą makr. Robiąc to, możesz skończyć z językiem do pisania swojego rodzaju GUI lub może bardzo ogólnych rzeczy, które można udostępniać i rozwijać.
Jedną rzeczą, którą tracisz podczas pisania GUI w Clojure, jest użycie narzędzi takich jak Matisse. Może to być mocna wskazówka, aby napisać niektóre części w Javie (GUI), a niektóre w Clojure (logika). Co właściwie ma sens, ponieważ w logice będziesz w stanie zbudować język dla swojego rodzaju logiki za pomocą makr i myślę, że można tam zyskać więcej niż z GUI. Oczywiście zależy to od aplikacji.
Nikt jeszcze tego nie zasugerował, więc ja: Przeglądarka jako platforma interfejsu użytkownika. Można napisać aplikację w Clojure, w tym serwera HTTP, a następnie rozwijać UI za pomocą czegokolwiek od HTML do czkawki , ClojureScript i każdy z miliardów JS bibliotekami potrzebujesz. Jeśli chcesz, aby przeglądarka działała w sposób spójny i wyglądała jak aplikacja komputerowa, możesz dodać Chrome do swojej aplikacji .
Wydaje się, że tak jest dystrybuowany Light Table .
Z tej strony :
(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");
I, oczywiście, byłoby warte patrząc na interoperacyjności odcinku stronie Clojure jest.
W Clojure contrib jest opakowanie dla MigLayout. Możesz również spojrzeć na to sedno . Zasadniczo wprowadzam dowolny kod, który piszę, ucząc się swingu / miglayout.
Przykład dsm ponownie napisany w lispy sposób przy użyciu 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)))
Na liście mailingowej rozmawiano o kilku wdrożeniach Cells (a la Kenny Tilton's Cells ). To całkiem fajny sposób na programowanie GUI.
Wolałbym raczej wybrać clojurefx, jest trochę przedwczesny, ale działa i oszczędza czas.
Uruchomiłem GUI z huśtawką, a następnie wypróbowałem inny składnik w clojurefx.
Skończyłem oba i jestem przekonany, że mam zamiar przerobić huśtawkę na clojurefx.
W końcu JavaFX to droga do przodu.
Wydaje się lżejszy niż huśtawka. A przynajmniej pisząc to ...
Wiązania działają, słuchacze działają, większość komponentów działa, w przeciwnym razie wystarczy użyć jednego z makr, aby utworzyć konstruktor dla tego konkretnego przypadku i wykonanego zadania. Lub, jeśli okaże się to trudne, napisz kilka metod w Javie i poproś o pomoc w ulepszaniu clojurefx.
Facet, który napisał clojurefx, jest w tej chwili zajęty, ale możesz rozwidlić projekt i wprowadzić kilka poprawek.
Oto kolejny bardzo podstawowy przykład zawijania huśtawki:
; 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)))
Pracowałem nad apletem Java, w którym wszystko jest napisane w Clojure z wyjątkiem kodu apletu, który jest napisany w Javie. Aplet wywołuje wywołania zwrotne init, paint, itp. Kodu Clojure z punktów zaczepienia Java dla metod zdefiniowanych przez model apletu. Tak więc kod kończy się na 99,999 procentach Clojure i nie musisz w większości myśleć o małym kawałku Java.
Takie podejście ma pewne wady, które mam nadzieję omówić bardziej szczegółowo w Clojure Google Group. Myślę, że programiści Clojure powinni uwzględnić natywny sposób budowania aplikacji. Obecnie w REPL możesz robić wszystko, co lubisz z GUI, ale jeśli chcesz dostarczać aplikację GUI, konieczne jest napisanie trochę Java, aby wywołać kod Clojure. Wygląda też na to, że architektura apletu języka Java zmusza Cię do wyjścia poza bardziej idiomatyczne najlepsze praktyki Clojure, wymagając użycia mutowalnego stanu itp.
Ale też nie jestem jeszcze zbyt daleko z Clojure i może się zdarzyć, że jest to możliwe, a po prostu jeszcze nie odkryłem, jak to zrobić poprawnie.
Moje preferowane środowisko Clojure UI używa IO.js (Node for ES6) + Electron (Container) + Quiescent (Wrapper ReactJS) .
Więc nie widziałem Fn-Fx na tej liście, od Timothy'ego Baldridge'a (halgiri). Jest to biblioteka Clojure zapewniająca funkcjonalną abstrakcję w stosunku do JavaFX.
Można go znaleźć na Github pod adresem https://github.com/halgari/fn-fx .
Aby użyć, upewnij się, że używasz najnowszej wersji Java (1.8 90+) i dodaj zależność do repozytorium github, dodając następujący plik do projektu.clj:
:plugins [[lein-git-deps "0.0.1-SNAPSHOT"]]
:git-dependencies [["https://github.com/halgari/fn-fx.git"]]
Wypróbowałem to i działa po wyjęciu z pudełka.
Clojure i SWT to najlepsze podejście do tworzenia graficznych interfejsów użytkownika. Zasadniczo SWT to podejście typu plug and play do tworzenia oprogramowania.
Wydaje mi się, że nie ma oficjalnego, ale osobiście skorzystałbym z faktu, że używam jednego z najpotężniejszych języków na świecie i po prostu wyobrażam sobie, jak wyglądałby idealny kod gui:
(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})])
Twój pomysł byłby inny, ale mam nadzieję, że powyższe daje ci pewien pomysł.
Wiem, że sugerujesz klasyczne rozwiązania dla komputerów stacjonarnych, ale sieć całkiem dobrze pasuje do clojure. Napisałem kompletną aplikację audio, w której wszystko jest podłączone, więc jeśli dodasz muzykę do folderu audio, zostanie to odzwierciedlone w interfejsie internetowym. Tylko mówię, że aplikacja desktopowa nie jest jedynym sposobem :)