Jaki jest najlepszy sposób tworzenia GUI w Clojure?

150

Jaki jest najlepszy sposób tworzenia GUI w Clojure ?

Czy istnieje przykład funkcjonalnego opakowania Swing lub SWT ? A może integracja z deklaratywnym opisem GUI JavaFX, który można łatwo zawinąć do wyrażeń s przy użyciu makrologii?

Jakieś tutoriale?

Marko
źródło

Odpowiedzi:

121

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!)
Dave Ray
źródło
2
sprawia, że ​​Swing jest fajny? Powiedzieli, że to niemożliwe!
Michael Bylstra
9
Nie musisz być pokorny - możesz być z tego bardzo dumny! +1!
mydoghasworms
7
-1: W twoim kodzie jest błąd. Zamiast „Hello, World” jest napisane „Hello, Seesaw”. </Joke>
Thomas Eding,
1
Naprawdę? Huśtawka? Czy to nie ogranicza programisty do funkcjonalności oferowanej przez Swing, tylko na wyższym poziomie abstrakcji, jeśli w ogóle? Czy Clojure w jakiś sposób sprawia, że ​​aplikacje wyglądają na mniej przestarzałe, czy też w jakiś sposób poprawia wszystkie obszary, w których Swing jest słaby? Mówię o wiązaniach, MVC i wszystkich tych „nowych” rzeczach, które Swing oferuje teraz jako takie. Czy jest to w jakiś sposób naprawione przez funkcje językowe Clojure?
Zelphir Kaltstahl
1
Postanowił skupić się na abstrakcji konkretnie na Swing. Nie ma w tym nic złego ...
Kenogu Labz,
16

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.

pupeno
źródło
2
Nie martw się o utratę Mattisse. Możesz skorzystać z miglayout.com , który jest na tyle potężny, że możesz tworzyć układy ręcznie.
tomjen
Możesz używać Matisse z Clojure, ponieważ wygenerowany kod to tylko kod Java, do którego Clojure może bezproblemowo uzyskać dostęp. Właściwie jest gdzieś poradnik ...
Rayne
3
Zastanawiam się, kiedy otrzymamy pierwszego projektanta graficznego interfejsu użytkownika wyświetlającego clojure. Ze względu na homoikoniczność wygenerowany kod nie powinien być nawet zły!
nperson325681
15

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 .

Matthew Gilliard
źródło
to świetnie, ale określenie właściwego portu może być trudne na każdym komputerze klienckim
scape
14

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.

dsm
źródło
3
Tak, wiem, że możesz wrócić do bezpośredniego używania Swinga, ale zapytałem, czy jest na to bardziej sepleniwy sposób.
Marko,
Pamiętaj również, że w nowszych wersjach zamknięcia musisz dodać rozszerzenie. przed wywołaniami funkcji składowej w bloku zadań do wykonania.
Jeroen Dirks
8

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)))
Abhijith
źródło
6

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.

Efrain Bergillos
źródło
Czy JavaFX rozwiązał problem niezbyt natywnego wyglądu? Poważne pytanie, ponieważ kiedy pierwszy raz to sprawdzałem, było to dawno temu i wyglądało mniej poprawnie niż Swing.
Trejkaz,
4

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)))
Jeroen Dirks
źródło
3

Zadałem sobie to samo pytanie, pisząc GUI w Clojure z Swingiem i wymyśliłem sygnaturę biblioteczną

Pozwala reprezentować model domeny jako pojedynczą strukturę danych Clojure zawiniętą w atom.

Zobacz przykłady tutaj .

Rulle
źródło
2

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.


źródło
2

Moje preferowane środowisko Clojure UI używa IO.js (Node for ES6) + Electron (Container) + Quiescent (Wrapper ReactJS) .

TWR Cole
źródło
1
Może to być skomplikowane, ale nadal chcę zapytać: czy możesz podać przykład, jak zacząć z tymi elementami? Albo opisz, która część aplikacji będzie obsługiwana przez który z wymienionych frameworków / bibliotek?
Zelphir Kaltstahl,
2

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.

Bill Barnhill
źródło
1

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.

Berlin Brown
źródło
1
Czy możesz podać link lub przykład? Byłbym zainteresowany, ale nie mam pojęcia, jak zacząć.
Carl Smotricz
1
Carl, po drugie. Dobry tutorial jak pisać wtyczki Eclipse za pomocą clojure byłby całkiem niezły.
Egon Willighagen
1

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

tomjen
źródło
Wygląda na to, że groovy SwingBuilder dsl został przetłumaczony na Clojure.
Marko
@ dev-er-dev To bardzo możliwe, nigdy nie używałem groovy, ale wielkie umysły robią to samo :)
tomjen
1

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

Anders Rune Jensen
źródło