Apa cara terbaik untuk melakukan GUI di Clojure?

150

Apa cara terbaik untuk melakukan GUI di Clojure ?

Apakah ada contoh dari beberapa fungsional swing atau SWT wrapper? Atau beberapa integrasi dengan deskripsi GUI deklaratif JavaFX yang dapat dengan mudah dibungkus dengan ekspresi s menggunakan beberapa makrologi?

Ada tutorial?

Marko
sumber

Jawaban:

121

Dengan rendah hati saya akan menyarankan Jungkat-jungkit .

Berikut adalah tutorial berbasis REPL yang mengasumsikan tidak ada pengetahuan Java atau Swing.


Seesaw sangat mirip dengan yang disarankan @tomjen. Inilah "Halo, Dunia":

(use 'seesaw.core)

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

dan inilah contoh @Abhijith dan @ dsm, diterjemahkan secara harfiah:

(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
sumber
2
membuat Swing menyenangkan? Mereka bilang itu tidak mungkin!
Michael Bylstra
9
Tidak perlu rendah hati - Anda bisa sangat bangga dengan yang ini! +1!
mydoghasworms
7
-1: Ada bug dalam kode Anda. Itu mengatakan "Halo, Jungkat-jungkit" bukan "Halo, Dunia". </Joke>
Thomas Eding
1
Betulkah? Ayunan? Bukankah ini membatasi pengembang untuk fungsionalitas yang ditawarkan Swing, hanya pada tingkat abstraksi yang lebih tinggi, jika ada? Apakah Clojure entah bagaimana membuat aplikasi terlihat kurang usang, atau apakah entah bagaimana meningkatkan semua area di mana Swing lemah? Saya berbicara tentang binding dan MVC dan semua hal "baru" itu, yang kini ditawarkan Swing. Apakah itu entah bagaimana diperbaiki oleh fitur bahasa Clojure?
Zelphir Kaltstahl
1
Dia memilih untuk membuat abstraksi terfokus pada Swing secara spesifik. Tidak ada yang salah dengan itu ...
Kenogu Labz
16

Jika Anda ingin melakukan pemrograman GUI saya akan menunjuk ke Konverter Suhu atau koloni semut .

Banyak hal di Swing dilakukan dengan subklasifikasi, terutama jika Anda membuat komponen kustom. Untuk itu ada dua fungsi penting / makro: proxy dan gen-class .

Sekarang saya mengerti ke mana Anda akan pergi dengan cara yang lebih Lispy. Saya kira belum ada yang seperti itu. Saya akan sangat menyarankan untuk tidak mencoba membangun kerangka kerja pembangunan GUI yang megah a-la CLIM , tetapi untuk melakukan sesuatu yang lebih Lispy: mulai menulis aplikasi Swing Anda dan abstraksi pola umum Anda dengan makro. Ketika melakukan itu, Anda mungkin berakhir dengan bahasa untuk menulis GUI jenis Anda, atau mungkin beberapa hal yang sangat umum yang dapat dibagikan dan tumbuh.

Satu hal yang hilang ketika menulis GUI di Clojure adalah penggunaan alat seperti Matisse. Itu bisa menjadi titik kuat untuk menulis beberapa bagian di Jawa (GUI) dan beberapa bagian di Clojure (logika). Yang sebenarnya masuk akal karena dalam logika Anda akan dapat membangun bahasa untuk jenis logika Anda menggunakan makro dan saya pikir ada lebih banyak untuk mendapatkan di sana daripada dengan GUI. Jelas, itu tergantung pada aplikasi Anda.

pupeno
sumber
2
Jangan khawatir kehilangan Mattisse. Anda dapat menggunakan miglayout.com , yang cukup kuat sehingga Anda dapat melakukan tata letak dengan tangan.
tomjen
Anda dapat menggunakan Matisse dengan Clojure, karena kode yang dihasilkan hanyalah kode Java yang dapat diakses secara mulus oleh Clojure. Sebenarnya ada tutorial untuk suatu tempat ...
Rayne
3
Saya bertanya-tanya kapan kita mendapatkan desainer GUI clojure-outputing pertama. Karena homoiconicity, kode yang dihasilkan seharusnya tidak buruk!
nperson325681
15

Tidak ada yang menyarankannya, jadi saya akan: Browser sebagai platform UI. Anda dapat menulis aplikasi Anda di Clojure, termasuk server HTTP dan kemudian mengembangkan UI menggunakan apa saja dari HTML ke cegukan , ClojureScript dan salah satu dari miliaran perpustakaan JS yang Anda butuhkan. Jika Anda ingin perilaku browser yang konsisten dan "tampilan aplikasi desktop" merasa "Anda dapat menggabungkan Chrome dengan aplikasi Anda .

Ini sepertinya bagaimana Light Table didistribusikan.

Matthew Gilliard
sumber
ini hebat, tetapi menentukan port yang tepat mungkin rumit pada setiap mesin klien
scape
14

Dari halaman ini :

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

Dan, tentu saja, ada baiknya melihat bagian interoperabilitas dari situs web clojure.

dsm
sumber
3
Ya, saya tahu Anda bisa kembali menggunakan Swing secara langsung, tetapi saya bertanya apakah ada cara yang lebih lispy untuk melakukannya.
Marko
Perhatikan juga bahwa dalam versi penutupan yang lebih baru Anda perlu menambahkan. di depan panggilan fungsi anggota di blok todo.
Jeroen Dirks
8

Ada pembungkus untuk MigLayout di clojure contrib. Anda juga bisa melihat intinya . Saya pada dasarnya memasang kode apa pun yang saya tulis saat saya belajar swing / miglayout.

Contoh dsm ditulis ulang dengan cara lispy menggunakan 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
sumber
6

Saya lebih suka pergi untuk clojurefx, ini agak terlalu dini, tetapi berhasil dan menghemat waktu Anda.

Saya memulai GUI saya dengan jungkat-jungkit dan kemudian mencoba komponen lain di clojurefx.

Saya telah menyelesaikan keduanya, dan saya yakin bahwa saya akan memperbaiki yang jungkat-jungkit menjadi clojurefx.

Bagaimanapun, JavaFX adalah cara untuk maju.

Rasanya lebih ringan dari jungkat-jungkit. Atau setidaknya, menulisnya ..

Binding bekerja, pendengar bekerja, sebagian besar komponen bekerja, jika tidak, cukup gunakan salah satu makro untuk membuat konstruktor untuk kasus tertentu dan pekerjaan yang dilakukan. Atau, jika Anda merasa kesulitan, tulis beberapa metode di Jawa dan minta bantuan untuk meningkatkan clojurefx.

Orang yang menulis clojurefx sedang sibuk saat ini, tetapi Anda dapat melakukan fork proyek dan melakukan beberapa perbaikan.

Efrain Bergillos
sumber
Sudahkah JavaFX memecahkan masalah tidak terlihat sangat asli? Pertanyaan serius, karena ketika saya pertama kali memeriksanya, itu sudah lama sekali, dan itu terlihat kurang benar daripada Swing.
Trejkaz
4

Berikut ini contoh pembungkus ayunan yang sangat mendasar:

; 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
sumber
3

Saya bertanya pada diri sendiri pertanyaan yang sama menulis GUI di Clojure dengan Swing dan datang dengan perpustakaan Signe

Ini memungkinkan Anda menggunakan mewakili model domain Anda sebagai struktur data Clojure tunggal yang dibungkus atom.

Lihat contoh di sini .

Rulle
sumber
2

Saya telah mengembangkan applet Java di mana semuanya ditulis dalam Clojure kecuali kode applet, yang ditulis dalam Java. Applet memanggil callback kode Clojure tentang init, paint, dll dari hook java untuk metode-metode yang didefinisikan oleh model applet. Jadi kode akhirnya menjadi 99,999 persen Clojure dan Anda tidak perlu memikirkan tentang potongan Java kecil sama sekali untuk sebagian besar.

Ada beberapa kelemahan dari pendekatan ini, yang saya harap dapat didiskusikan lebih terinci di Clojure Google Group. Saya pikir pengembang Clojure harus memasukkan cara asli untuk membangun aplikasi. Saat ini Anda dapat melakukan hal-hal GUI apa pun yang Anda suka dari REPL, tetapi jika Anda menginginkan aplikasi GUI yang dapat dikirim, Anda perlu menulis beberapa Java untuk memanggil kode Clojure. Selain itu, sepertinya arsitektur Java Applet memberi Anda kekuatan di luar praktik terbaik Clojure yang lebih idiomatis, yang mengharuskan Anda menggunakan keadaan bisa berubah, dll.

Tetapi juga, saya belum terlalu jauh dengan Clojure dan mungkin itu adalah hal yang mungkin dan saya belum menemukan cara melakukannya dengan benar.


sumber
2

Lingkungan UI Clojure pilihan saya menggunakan IO.js (Node untuk ES6) + Electron (Container) + Quiescent (wrapper ReactJS) .

TWR Cole
sumber
1
Ini mungkin rumit, tetapi saya masih ingin bertanya: Dapatkah Anda memberikan contoh tentang cara memulai dengan potongan-potongan ini? Atau jelaskan bagian mana dari suatu aplikasi yang akan ditangani oleh kerangka / pustaka mana yang Anda sebutkan?
Zelphir Kaltstahl
2

Jadi saya tidak melihat Fn-Fx dalam daftar ini, dari Timothy Baldridge (halgiri). Ini adalah perpustakaan Clojure yang menyediakan abstraksi fungsional atas JavaFX.

Itu dapat ditemukan di Github di https://github.com/halgari/fn-fx .

Untuk menggunakan, pastikan Anda menggunakan versi terbaru Java (1,8 90+) dan tambahkan dependensi ke repo github dengan menambahkan yang berikut ke project.clj Anda:

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

Saya sudah mencobanya, dan berhasil di luar kotak.

Bill Barnhill
sumber
1

Clojure dan SWT adalah pendekatan terbaik untuk melakukan GUI. Pada dasarnya, SWT adalah pendekatan gaya plug and play untuk mengembangkan perangkat lunak.

Berlin Brown
sumber
1
Bisakah Anda memberikan tautan atau contoh? Saya tertarik tetapi tidak tahu bagaimana memulainya.
Carl Smotricz
1
Carl, yang kedua. Tutorial yang baik tentang cara menulis plugin Eclipse menggunakan clojure akan lebih baik.
Egon Willighagen
1

Saya tidak berpikir ada yang resmi, tetapi secara pribadi saya akan mengambil keuntungan dari kenyataan bahwa saya menggunakan salah satu bahasa yang paling kuat di dunia dan bayangkan seperti apa bentuk kode gui yang sempurna:

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

Ide Anda akan berbeda tetapi semoga ini di atas memberi Anda beberapa ide.

Tomjen
sumber
Sepertinya ds SwingBuilder asyik diterjemahkan ke Clojure.
Marko
@ dev-er-dev Itu sangat mungkin, saya tidak pernah menggunakan asyik, tetapi orang-orang hebat melakukan hal yang sama :)
tomjen
1

Saya tahu Anda mengisyaratkan solusi desktop klasik, tetapi web sangat cocok dengan clojure. Saya telah menulis aplikasi audio lengkap di mana semuanya terhubung sehingga jika Anda menambahkan musik ke folder audio itu tercermin di UI web. Hanya mengatakan bahwa aplikasi Desktop bukan satu-satunya jalan :)

Anders Rune Jensen
sumber