web-dev-qa-db-de.com

Was ist der beste Weg, um GUIs in Clojure zu erstellen?

Was ist der beste Weg, um GUIs in Clojure zu erstellen?

Gibt es ein Beispiel für einen funktionalen Swing oder SWT Wrapper? Oder eine Integration in JavaFX deklarative GUI-Beschreibung, die mit Hilfe von Makrologie leicht in s-Ausdrücke umgewandelt werden kann?

Irgendwelche Tutorials?

145
Marko

Ich werde demütig vorschlagen Wippe .

Hier ist ein REPL-basiertes Tutorial das keine Java oder Swing-Kenntnisse voraussetzt.


Wippe ähnelt sehr dem, was @tomjen vorschlägt. Hier ist "Hallo Welt":

(use 'seesaw.core)

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

und hier ist das Beispiel von @Abhijith und @ dsm, wörtlich übersetzt:

(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!)
116
Dave Ray

Stuart Sierra veröffentlichte kürzlich eine Reihe von Blog-Posts zur GUI-Entwicklung mit clojure (und swing). Beginnen Sie hier: http://stuartsierra.com/2010/01/02/first-steps-with-clojure-swing

32
steglig

Wenn Sie GUI-Programmierung machen möchten, würde ich auf Temperature Converter oder die Ameisenkolonie verweisen.

Viele Dinge in Swing werden durch Unterklassen erledigt, insbesondere wenn Sie benutzerdefinierte Komponenten erstellen. Dafür gibt es zwei wesentliche Funktionen/Makros: Proxy und Gen-Klasse .

Jetzt verstehe ich, wohin du mit dem Lispyschen Weg gehst. Ich glaube nicht, dass es so etwas noch gibt. Ich würde dringend davon abraten, ein grandioses GUI-Framework a-la CLIM zu erstellen, aber etwas mehr Lispy: Schreiben Sie Ihre Swing-Anwendung und Abstract Verwenden Sie Makros, um gängige Muster zu erstellen. Wenn Sie dies tun, haben Sie möglicherweise eine Sprache, mit der Sie Ihre GUIs schreiben können, oder einige sehr allgemeine Dinge, die gemeinsam genutzt und erweitert werden können.

Eine Sache, die Sie verlieren, wenn Sie die GUIs in Clojure schreiben, ist die Verwendung von Tools wie Matisse. Dies kann ein starker Hinweis darauf sein, einige Teile in Java (die GUI) und einige Teile in Clojure (die Logik) zu schreiben Eine Sprache für Ihre Art von Logik, die Makros verwendet, und ich denke, dass es dort mehr zu gewinnen gibt als mit der GUI. Offensichtlich hängt es von Ihrer Anwendung ab.

16
pupeno

Von diesem Seite :

(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");

Und natürlich lohnt es sich, den Abschnitt Interoperabilität auf der Website von clojure zu lesen.

14
dsm

Niemand hat es bisher vorgeschlagen, also werde ich: Browser als UI-Plattform. Sie können Ihre App in Clojure schreiben, einschließlich eines HTTP-Servers, und dann die Benutzeroberfläche mithilfe von HTML, Schluckauf , ClojureScript und den Milliarden von JS-Bibliotheken entwickeln, die Sie benötigen. Wenn Sie ein konsistentes Browserverhalten und ein einheitliches Erscheinungsbild der Desktop-App wünschen, können Sie Bundle chrome mit Ihrer App .

Dies scheint zu sein, wie Leuchttisch verteilt ist.

14

Es gibt einen Wrapper für MigLayout in Clojure Contrib. Sie können sich auch this Gist ansehen. Ich setze im Grunde genommen den Code ein, den ich schreibe, während ich Swing/Miglayout lerne.

das Beispiel von dsm wurde mit contrib.swing-utils lispy umgeschrieben

(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)))
8
Abhijith

Es gab auf der Mailingliste einige Cells (a la Kenny Tiltons Cells ) Implementierungen. Es ist eine ziemlich nette Art, GUI-Programmierung zu machen.

6
Joe W.

Ich würde mich lieber für clojurefx entscheiden, es ist ein bisschen verfrüht, aber es funktioniert und spart Ihnen Zeit.

Ich startete meine GUI mit Wippe und versuchte dann eine andere Komponente in Clojurefx.

Ich habe beide abgeschlossen und bin überzeugt, dass ich die Wippe zu clojurefx umgestalten werde.

Schließlich ist JavaFX der richtige Weg, um voranzukommen.

Es fühlt sich leichter an als Wippe. Oder zumindest, es zu schreiben ..

Bindungen funktionieren, Listener funktionieren, die meisten Komponenten funktionieren, ansonsten verwenden Sie einfach eines der Makros, um einen Konstruktor für diesen speziellen Fall zu erstellen und die Aufgabe zu erledigen. Wenn Sie Schwierigkeiten haben, schreiben Sie einige Methoden in Java) und bitten Sie um Hilfe, um clojurefx zu verbessern.

Der Typ, der clojurefx geschrieben hat, ist im Moment beschäftigt, aber Sie können das Projekt verzweigen und einige Korrekturen vornehmen.

5

Hier ist ein weiteres sehr einfaches Beispiel für Swing Wrapping:

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

Ich stellte mir die gleiche Frage wie beim Schreiben einer GUI in Clojure mit Swing und fand die Bibliothek signe

Hiermit können Sie Ihr Domain-Modell als einzelne Clojure-Datenstruktur in einem Atom darstellen.

Siehe die Beispiele hier .

3
Rulle

Ich habe ein Java Applet entwickelt, in dem alles in Clojure geschrieben ist, außer dem Applet-Code, der in Java geschrieben ist. Das Applet ruft die Rückrufe des Clojure-Codes von init, Paint usw. von Java auf Hooks für die Methoden, die vom Applet-Modell definiert werden, sodass der Code 99,999 Prozent Clojure ergibt und Sie sich zum größten Teil keine Gedanken über das winzige Java piece machen müssen.

Dieser Ansatz weist einige Nachteile auf, auf die ich in der Clojure Google-Gruppe näher eingehen möchte. Ich denke, die Clojure-Entwickler sollten eine native Methode zum Erstellen von Anwendungen einbeziehen. Gegenwärtig können Sie mit der REPL beliebige GUI-Funktionen ausführen. Wenn Sie jedoch eine lieferbare GUI-Anwendung benötigen, müssen Sie Java) schreiben, um den Clojure-Code aufzurufen Architektur eines Java Applets zwingt Sie dazu, sich von den idiomatischeren Best Practices von Clojure zu entfernen, und erfordert die Verwendung eines veränderlichen Status usw.

Aber auch, ich bin noch nicht weit mit Clojure zusammen und es könnte sein, dass es möglich ist und ich habe nur noch nicht herausgefunden, wie man es richtig macht.

2
Robert Levy

Also habe ich Fn-Fx von Timothy Baldridge (halgiri) auf dieser Liste nicht gesehen. Dies ist eine Clojure-Bibliothek, die eine funktionale Abstraktion über JavaFX bietet.

Es kann auf Github unter https://github.com/halgari/fn-fx gefunden werden.

Stellen Sie zur Verwendung sicher, dass Sie eine aktuelle Version von Java (1.8 90+) verwenden, und fügen Sie dem Github-Repo eine Abhängigkeit hinzu, indem Sie Ihrem project.clj Folgendes hinzufügen:

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

Ich habe es versucht, und es funktioniert sofort.

2
Bill Barnhill

Clojure und SWT ist der beste Ansatz für GUI (s). Grundsätzlich ist SWT ein Plug-and-Play-Ansatz für die Entwicklung von Software.

1
Berlin Brown

Ich glaube nicht, dass es eine offizielle gibt, aber ich persönlich würde die Tatsache ausnutzen, dass ich eine der mächtigsten Sprachen der Welt verwende und mir vorstellen, wie der perfekte GUI-Code aussehen würde:

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

Ihre Idee würde sich unterscheiden, aber dies sollte Ihnen hoffentlich eine Idee geben.

1
tomjen

Meine bevorzugte Clojure-UI-Umgebung verwendet IO.js (Node for ES6) + Electron (Container) + Quiescent (ReactJS-Wrapper) .

1
T.W.R. Cole

Ich weiß, dass Sie für klassische Desktop-Lösungen andeuten, aber das Web passt recht gut zu Clojure. Ich habe eine vollständige Audioanwendung geschrieben, in der alles so angeschlossen ist, dass Musik, die Sie dem Audioordner hinzufügen, in der Web-Benutzeroberfläche wiedergegeben wird. Nur zu sagen, dass Desktop-Anwendung nicht der einzige Weg ist :)

1