วิธีที่ดีที่สุดในการทำ GUIs ใน Clojure คืออะไร


150

วิธีที่ดีที่สุดในการทำ GUIs ในClojureคืออะไร

มีตัวอย่างของฟังก์ชั่นSwingหรือSWT wrapper หรือไม่? หรือการบูรณาการบางอย่างกับคำอธิบาย GUI ที่ประกาศJavaFXซึ่งสามารถห่อไปที่s-expressionsได้อย่างง่ายดายโดยใช้ macrology บางอย่าง?

บทเรียนใด ๆ

คำตอบ:


121

ฉันจะแนะนำเจียมกระดานหก

ต่อไปนี้เป็นบทช่วยสอนที่ใช้ REPLซึ่งไม่มีความรู้เกี่ยวกับ Java หรือ Swing


กระดานหกมีอะไรมากมายที่ @Tomjen แนะนำ นี่คือ "สวัสดีโลก":

(use 'seesaw.core)

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

และนี่คือตัวอย่างของ @Abhijith และ @ dsm แปลว่าสวยจริงๆ:

(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!)

2
ทำให้ความสนุกสวิง? พวกเขาบอกว่ามันเป็นไปไม่ได้!
Michael Bylstra

9
ไม่จำเป็นที่จะต้องถ่อมตน - คุณสามารถภูมิใจในสิ่งนี้ได้! +1!
mydoghasworms

7
-1: มีข้อผิดพลาดในรหัสของคุณ มันบอกว่า "Hello, Seesaw" แทนที่จะเป็น "Hello, World" </Joke>
Thomas Eding

1
จริงๆ? แกว่ง? สิ่งนี้ไม่ได้ จำกัด นักพัฒนาซอฟต์แวร์สำหรับฟังก์ชั่นสวิงที่เสนอ แต่ในระดับที่สูงกว่าของนามธรรมถ้ามี Clojure ทำให้แอพพลิเคชั่นดูล้าสมัยน้อยลงหรือปรับปรุงพื้นที่ทั้งหมดที่ Swing อ่อนแอหรือไม่? ฉันกำลังพูดถึงการผูกและ MVC และสิ่งที่ "ใหม่" ที่สวิงเสนอให้ในตอนนี้ แก้ไขโดยคุณสมบัติภาษาของ Clojure หรือไม่?
Zelphir Kaltstahl

1
เขาเลือกที่จะทำให้สิ่งที่เป็นนามธรรมที่มุ่งเน้นเฉพาะสวิง ไม่มีอะไรผิดปกติกับเรื่องนี้ ...
Kenogu Labz


16

หากคุณต้องการที่จะทำโปรแกรม GUI ฉันชี้ไปที่อุณหภูมิแปลงหรือมดอาณานิคม

มีหลายสิ่งใน Swing ที่ทำโดยการแบ่งคลาสย่อยโดยเฉพาะถ้าคุณกำลังสร้างส่วนประกอบที่กำหนดเอง สำหรับว่ามีสองฟังก์ชั่นที่จำเป็น / มาโคร: พร็อกซี่และGEN-ระดับ

ตอนนี้ฉันเข้าใจแล้วว่าคุณกำลังจะไปไหนด้วยความมีชีวิตชีวามากขึ้น ฉันไม่คิดว่าจะมีอะไรแบบนั้น ฉันขอแนะนำอย่างยิ่งต่อการพยายามสร้าง a-la CLIMกรอบงานสร้าง GUI ที่ยิ่งใหญ่แต่เพื่อทำสิ่งที่มากกว่านั้น: เริ่มเขียนโปรแกรม Swing ของคุณและสรุปรูปแบบทั่วไปของคุณด้วยมาโคร เมื่อทำเช่นนั้นคุณอาจพบภาษาเพื่อเขียน GUIs ของคุณหรืออาจเป็นเรื่องทั่วไปที่สามารถแบ่งปันและเติบโตได้

สิ่งหนึ่งที่คุณแพ้เมื่อเขียน GUI ใน Clojure คือการใช้เครื่องมือเช่น Matisse นั่นอาจเป็นการชี้ที่แข็งแกร่งในการเขียนบางส่วนใน Java (GUI) และบางส่วนใน Clojure (ตรรกะ) ซึ่งจริง ๆ แล้วสมเหตุสมผลในตรรกะคุณจะสามารถสร้างภาษาสำหรับชนิดของตรรกะของคุณโดยใช้แมโครและฉันคิดว่ามีมากกว่าที่จะได้รับกับ GUI เห็นได้ชัดว่ามันขึ้นอยู่กับใบสมัครของคุณ


2
ไม่ต้องกังวลกับการสูญเสีย Mattisse คุณสามารถใช้miglayout.comซึ่งมีพลังมากพอที่จะทำเลย์เอาต์ได้ด้วยมือ
tomjen

คุณสามารถใช้ Matisse กับ Clojure ได้เพราะรหัสที่สร้างขึ้นเป็นเพียงโค้ด Java ที่ Clojure สามารถเข้าถึงได้อย่างราบรื่น มีจริงการสอนสำหรับบางที่ ...
เรน

3
ฉันสงสัยว่าเมื่อไหร่ที่เราได้ผู้ออกแบบ GUI ส่งออก clojure-output ครั้งแรก เนื่องจาก homoiconicity รหัสที่สร้างขึ้นจึงไม่ควรจะแย่!
nperson325681

15

ยังไม่มีใครแนะนำดังนั้นฉันจะ: เบราว์เซอร์เป็นแพลตฟอร์ม UI คุณสามารถเขียนแอพของคุณใน Clojure รวมถึงเซิร์ฟเวอร์ HTTP จากนั้นพัฒนา UI โดยใช้ทุกอย่างจาก HTML เป็นhiccup , ClojureScript และหนึ่งในพันของ JS libaries ที่คุณต้องการ หากคุณต้องการพฤติกรรมเบราว์เซอร์ที่สอดคล้องกันและ "แอปบนเดสก์ท็อป look'n'feel" คุณสามารถรวมChrome ด้วยแอปของคุณได้ได้

นี่น่าจะเป็นวิธีกระจายLight Table


นี่เป็นสิ่งที่ดี แต่การกำหนดพอร์ตที่เหมาะสมอาจเป็นเรื่องยากสำหรับเครื่องไคลเอนต์ทุกเครื่อง
scape

14

จากหน้านี้:

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

และแน่นอนว่ามันจะคุ้มค่าที่จะดูในส่วนการทำงานร่วมกันของเว็บไซต์ Clojure


3
ใช่ฉันรู้ว่าคุณสามารถกลับไปใช้ Swing โดยตรงได้ แต่ฉันถูกถามว่ามีวิธีที่เงียบกว่านี้หรือไม่
Marko

นอกจากนี้โปรดทราบว่าในการปิดเวอร์ชันล่าสุดคุณต้องเพิ่ม ด้านหน้าของฟังก์ชันสมาชิกเรียกใน todo block
Jeroen Dirks

8

มี wrapper สำหรับ MigLayout ใน contjure contjure คุณยังสามารถดูส่วนสำคัญนี้ ฉันมักจะวางโค้ดอะไรก็ตามที่ฉันกำลังเขียนเพราะฉันกำลังเรียนรู้การแกว่ง / การเลย์เอาต์

ตัวอย่างของ dsm เขียนขึ้นใหม่ในแบบ lispy โดยใช้ 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)))


6

ฉันอยากจะไปหา clojurefx มันเร็วเกินไป แต่มันใช้งานได้และช่วยคุณประหยัดเวลา

ฉันเริ่ม GUI ของฉันด้วยกระดานหกแล้วลองส่วนประกอบอื่นใน clojurefx

ฉันได้ทำทั้งสองอย่างเสร็จแล้วและฉันเชื่อว่าฉันจะต้องจัดทำแผ่นกระดานหกอีกครั้งเพื่อปิดบัง

ท้ายที่สุดแล้ว JavaFX คือวิธีการที่จะก้าวไปข้างหน้า

รู้สึกเบากว่ากระดานหก หรืออย่างน้อยก็เขียนมัน ..

การเชื่อมโยงงานผู้ฟังทำงานส่วนประกอบส่วนใหญ่ไม่เช่นนั้นเพียงใช้มาโครตัวใดตัวหนึ่งในการสร้างตัวสร้างสำหรับกรณีและงานเฉพาะนั้น หรือถ้าคุณพบว่ามันยากเขียนวิธีการบางอย่างใน Java และขอความช่วยเหลือในการปรับปรุง clojurefx

คนที่เขียน clojurefx ไม่ว่างในขณะนี้ แต่คุณสามารถแยกโครงการและทำการแก้ไขบางอย่าง


JavaFX แก้ไขปัญหาที่ยังไม่ได้ดูพื้นเมืองมาก ๆ หรือยัง คำถามที่จริงจังเพราะเมื่อฉันตรวจสอบครั้งแรกมันเป็นเวลานานที่ผ่านมาและมันดูถูกต้องน้อยกว่าสวิง
Trejkaz

4

นี่คืออีกหนึ่งตัวอย่างการตัดแบบสวิงที่ธรรมดามาก:

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

3

ผมถามตัวเองคำถามเดียวกันในการเขียน GUI ใน Clojure กับสวิงและมาพร้อมกับห้องสมุดSigne

ช่วยให้คุณใช้เป็นตัวแทนของแบบจำลองโดเมนของคุณเป็นโครงสร้างข้อมูล Clojure เดียวที่อยู่ภายในอะตอม

ดูตัวอย่างที่นี่


2

ฉันพัฒนาแอปเพล็ต Java ที่ทุกอย่างเขียนใน Clojure ยกเว้นรหัสแอปเพล็ตซึ่งเขียนด้วย Java แอปเพล็ตเรียกใช้การเรียกกลับของรหัส Clojure ของ init, paint และอื่น ๆ จาก hooks ของ java สำหรับวิธีการที่กำหนดโดยรูปแบบแอปเพล็ต ดังนั้นโค้ดก็คือ Clojure 99.999 เปอร์เซ็นต์และคุณไม่ต้องคิดถึงชิ้น Java ตัวเล็ก ๆ เลยส่วนใหญ่

มีข้อเสียบางอย่างสำหรับวิธีการนี้ซึ่งฉันหวังว่าจะพูดคุยรายละเอียดเพิ่มเติมเกี่ยวกับกลุ่ม Google Clojure ฉันคิดว่าผู้พัฒนา Clojure ควรรวมวิธีการสร้างแอปพลิเคชันด้วยวิธีดั้งเดิม ในปัจจุบันคุณสามารถทำสิ่งใดก็ตามที่ GUI ที่คุณต้องการจาก REPL แต่ถ้าคุณต้องการแอปพลิเคชัน GUI ที่ส่งมอบได้คุณจำเป็นต้องเขียน Java บางตัวเพื่อเรียกรหัส Clojure นอกจากนี้ดูเหมือนว่าสถาปัตยกรรมของ Java Applet จะบังคับให้คุณออกนอกแนวทางปฏิบัติที่ดีที่สุดของ Clojure ที่ต้องการให้คุณใช้สถานะที่ไม่แน่นอน ฯลฯ

แต่ฉันก็ยังไม่ได้อยู่ใกล้กับ Clojure มากนักและอาจเป็นไปได้ว่ามันเป็นไปได้และฉันก็ยังไม่ได้ค้นพบวิธีการทำอย่างถูกต้องเลย


2

ฉันแนะนำ Clojure UI ใช้สภาพแวดล้อมIO.js (Node สำหรับ ES6) + อิเลคตรอน (คอนเทนเนอร์) + Quiescent (ReactJS เสื้อคลุม)


1
อาจซับซ้อน แต่ฉันยังคงต้องการถาม: คุณสามารถให้ตัวอย่างเกี่ยวกับวิธีเริ่มต้นกับชิ้นส่วนเหล่านี้ได้หรือไม่ หรืออธิบายว่าส่วนใดของแอปพลิเคชันที่จัดการโดยเฟรมเวิร์ก / ไลบรารีเหล่านั้นที่คุณกล่าวถึง?
Zelphir Kaltstahl

2

ดังนั้นฉันไม่เห็น Fn-Fx ในรายการนี้จาก Timothy Baldridge (halgiri) นี่คือไลบรารี Clojure ที่ให้บริการนามธรรมที่เหนือกว่า JavaFX

มันสามารถพบได้บน Github ที่https://github.com/halgari/fn-fx

วิธีใช้ตรวจสอบให้แน่ใจว่าคุณใช้ Java เวอร์ชันล่าสุด (1.8 90+) และเพิ่มการพึ่งพา gitub repo ด้วยการเพิ่มสิ่งต่อไปนี้ใน project.clj ของคุณ:

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

ฉันลองแล้วมันใช้งานได้ดี


1

Clojure และ SWT เป็นวิธีที่ดีที่สุดสำหรับการทำ GUI โดยพื้นฐานแล้ว SWT เป็นแนวทางแบบพลักแอนด์เพลย์สำหรับการพัฒนาซอฟต์แวร์


1
คุณสามารถให้ลิงค์หรือตัวอย่างได้หรือไม่? ฉันจะสนใจ แต่ไม่รู้ว่าจะเริ่มอย่างไร
Carl Smotricz

1
คาร์ลที่สองที่ บทแนะนำที่ดีเกี่ยวกับวิธีเขียนปลั๊กอิน Eclipse โดยใช้ Clojure นั้นค่อนข้างดี
Egon Willighagen

1

ฉันไม่คิดว่าจะมีอย่างเป็นทางการ แต่โดยส่วนตัวฉันจะใช้ประโยชน์จากความจริงที่ว่าฉันใช้ภาษาที่ทรงพลังที่สุดในโลกและลองจินตนาการว่ารหัส 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})])

ความคิดของคุณจะแตกต่างกันไป แต่สิ่งนี้น่าจะช่วยให้คุณมีความคิดได้บ้าง


ดูเหมือนว่า groovy SwingBuilder dsl แปลเป็น Clojure
Marko

@ dev-ER-dev ที่เป็นไปได้มากผมไม่เคยใช้แรง แต่จิตใจที่ดีทำสิ่งที่เหมือนกัน :)
tomjen

1

ฉันรู้ว่าคุณกำลังบอกใบ้ให้กับโซลูชันเดสก์ท็อปแบบดั้งเดิม แต่เว็บนั้นเข้ากันได้ดีกับการปิดบัง ฉันได้เขียนแอปพลิเคชั่นเสียงที่สมบูรณ์ซึ่งทุกอย่างถูกเชื่อมโยงดังนั้นถ้าคุณเพิ่มเพลงในโฟลเดอร์เสียงมันจะปรากฏใน UI เว็บ แค่บอกว่าแอปพลิเคชัน Desktop ไม่ใช่วิธีเดียว :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.