Cách tốt nhất để làm GUI trong Clojure là gì?


Câu trả lời:


121

Tôi sẽ khiêm tốn đề nghị Seesaw .

Đây là một hướng dẫn dựa trên REPL giả định không có kiến ​​thức về Java hoặc Swing.


Seesaw rất giống những gì @tomjen gợi ý. Đây là "Xin chào, thế giới":

(use 'seesaw.core)

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

và đây là ví dụ của @Abhijith và @ dsm, được dịch theo nghĩa đen:

(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
Làm cho vui? Họ nói rằng điều đó là không thể!
Michael Bylstra

9
Không cần phải khiêm tốn - bạn có thể rất tự hào về điều này! +1!
mydoghasworms

7
-1: Có lỗi trong mã của bạn. Nó nói "Xin chào, Seesaw" thay vì "Xin chào, Thế giới". </ Trò đùa>
Thomas Eding

1
Có thật không? Lung lay? Điều này không giới hạn nhà phát triển đối với chức năng mà Swing cung cấp, chỉ ở mức độ trừu tượng cao hơn, nếu có? Liệu Clojure bằng cách nào đó làm cho các ứng dụng trông bớt lỗi thời hơn, hoặc bằng cách nào đó nó cải thiện tất cả các lĩnh vực mà Swing yếu? Tôi đang nói về các ràng buộc và MVC và tất cả những thứ "mới", mà bây giờ Swing cung cấp. Có phải nó được sửa bằng cách nào đó bởi các tính năng ngôn ngữ của Clojure?
Zelphir Kaltstahl

1
Anh ấy chọn cách thực hiện một sự trừu tượng hóa tập trung vào Swing. Không có gì sai với điều đó ...
Kenogu Labz 10/07/2016


16

Nếu bạn muốn lập trình GUI, tôi sẽ trỏ đến Bộ chuyển đổi nhiệt độ hoặc đàn kiến .

Nhiều thứ trong Swing được thực hiện bằng cách phân lớp phụ, đặc biệt nếu bạn đang tạo các thành phần tùy chỉnh. Cho rằng có hai chức năng / macro cần thiết: proxylớp gen .

Bây giờ tôi hiểu bạn đang đi đâu với cách Lispy hơn. Tôi không nghĩ có gì như vậy chưa. Tôi thực sự khuyên bạn không nên cố gắng xây dựng một khung xây dựng GUI hoành tráng a-la CLIM , nhưng để làm một cái gì đó Lispy hơn: bắt đầu viết ứng dụng Swing của bạn và trừu tượng hóa các mẫu chung của bạn bằng macro. Khi làm điều đó, bạn có thể kết thúc bằng một ngôn ngữ để viết loại GUI của bạn hoặc có thể một số nội dung rất chung chung có thể được chia sẻ và phát triển.

Một điều bạn mất khi viết GUI trong Clojure là việc sử dụng các công cụ như Matisse. Đó có thể là một điểm mạnh để viết một số phần trong Java (GUI) và một số phần trong Clojure (logic). Điều này thực sự có ý nghĩa như trong logic, bạn sẽ có thể xây dựng một ngôn ngữ cho loại logic của mình bằng cách sử dụng macro và tôi nghĩ rằng có nhiều thứ để đạt được điều đó hơn là với GUI. Rõ ràng, nó phụ thuộc vào ứng dụng của bạn.


2
Đừng lo lắng về việc mất Mattisse. Bạn có thể sử dụng Miglayout.com , đủ mạnh để bạn có thể thực hiện các bố cục bằng tay.
tomjen

Bạn có thể sử dụng Matisse với Clojure, vì mã được tạo ra chỉ là mã Java có thể được Clojure truy cập liền mạch. Thực sự có một hướng dẫn cho điều đó ở đâu đó ...
Rayne

3
Tôi tự hỏi khi chúng ta có được trình thiết kế GUI đầu ra clojure đầu tiên. Do tính đồng nhất, mã được tạo thậm chí không nên xấu!
nperson325681

15

Chưa có ai đề xuất nó, vì vậy tôi sẽ: Trình duyệt như nền tảng UI. Bạn có thể viết ứng dụng của mình trong Clojure, bao gồm máy chủ HTTP và sau đó phát triển giao diện người dùng bằng cách sử dụng bất kỳ thứ gì từ HTML đến nấc cục , ClojureScript và bất kỳ hàng tỷ lời nói dối nào bạn cần. Nếu bạn muốn hành vi nhất quán của trình duyệt và "ứng dụng máy tính để bàn", bạn có thể đóng gói chrome với ứng dụng của mình .

Đây dường như là cách Light Table được phân phối.


Điều này thật tuyệt, nhưng việc xác định cổng thích hợp có thể khó khăn trên mọi máy khách
scape

14

Từ trang này :

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

Và, tất nhiên, sẽ đáng để xem phần khả năng tương tác trên trang web của clojure.


3
Vâng, tôi biết bạn có thể quay lại sử dụng Swing trực tiếp, nhưng tôi đã hỏi liệu có cách nào hiệu quả hơn không.
Marko

Cũng lưu ý rằng trong các phiên bản gần đây hơn của việc đóng cửa, bạn cần thêm một. ở phía trước của hàm gọi thành viên trong khối việc cần làm.
Jeroen Dirks

8

Có một trình bao bọc cho MigLayout trong đóng góp clojure. Bạn cũng có thể xem qua ý chính này . Về cơ bản, tôi đang đưa ra bất kỳ mã nào tôi đang viết khi tôi đang học swing / Miglayout.

ví dụ của dsm được viết lại theo cách lispy bằng cách sử dụng 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

Tôi thà đi clojurefx, nó hơi sớm, nhưng nó hoạt động và tiết kiệm thời gian của bạn.

Tôi bắt đầu GUI của mình với trò chơi bập bênh và sau đó thử một thành phần khác trong clojurefx.

Tôi đã hoàn thành cả hai, và tôi tin rằng tôi sẽ cấu trúc lại cái bập bênh thành clojurefx.

Xét cho cùng, JavaFX là con đường để đi tiếp.

Nó cảm thấy nhẹ hơn bập bênh. Hoặc ít nhất, viết nó ..

Ràng buộc làm việc, người nghe làm việc, hầu hết các công việc thành phần, nếu không, chỉ cần sử dụng một trong các macro để tạo một hàm tạo cho trường hợp cụ thể đó và công việc được thực hiện. Hoặc, nếu bạn cảm thấy khó khăn, hãy viết một số phương thức bằng Java và yêu cầu trợ giúp để cải thiện clojurefx.

Anh chàng đã viết clojurefx hiện đang bận rộn, nhưng bạn có thể rẽ nhánh dự án và thực hiện một số sửa chữa.


JavaFX đã giải quyết các vấn đề không trông rất tự nhiên chưa? Câu hỏi nghiêm túc, bởi vì khi tôi lần đầu tiên kiểm tra nó, nó đã có từ lâu và nó trông không chính xác hơn so với Swing.
Trejkaz

4

Đây là một ví dụ gói đu rất cơ bản khác:

; 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

Tôi tự hỏi cùng một câu hỏi đến việc viết một GUI trong Clojure với Swing và đã đưa ra các thư viện Signe

Nó cho phép bạn sử dụng đại diện cho mô hình miền của mình dưới dạng một cấu trúc dữ liệu Clojure duy nhất được bọc bên trong một nguyên tử.

Xem các ví dụ ở đây .


2

Tôi đã phát triển một applet Java trong đó mọi thứ được viết bằng Clojure ngoại trừ mã applet, được viết bằng Java. Applet gọi các cuộc gọi lại của mã Clojure về init, paint, v.v. từ các hook của java cho các phương thức được xác định bởi mô hình applet. Vì vậy, mã cuối cùng là 99,999 phần trăm Clojure và hầu như bạn không phải suy nghĩ về phần Java nhỏ bé.

Có một số nhược điểm đối với phương pháp này, mà tôi hy vọng sẽ thảo luận chi tiết hơn về Nhóm Google Clojure. Tôi nghĩ rằng các nhà phát triển Clojure nên bao gồm một cách xây dựng các ứng dụng bản địa. Hiện tại bạn có thể làm bất cứ thứ gì GUI bạn thích từ REPL, nhưng nếu bạn muốn có một ứng dụng GUI có thể phân phối được, thì cần phải viết một số Java để gọi mã Clojure. Ngoài ra, có vẻ như kiến ​​trúc của một loại Applet Java buộc bạn bên ngoài các thực tiễn tốt nhất thành ngữ hơn của Clojure, yêu cầu bạn sử dụng trạng thái có thể thay đổi, v.v.

Nhưng ngoài ra, tôi không ở rất xa với Clojure và đó có thể là trường hợp có thể và tôi chưa khám phá ra cách làm điều đó một cách chính xác.



2

Vì vậy, tôi đã không thấy Fn-Fx trong danh sách này, từ Timothy Baldridge (halgiri). Đây là một thư viện Clojure cung cấp một sự trừu tượng hóa chức năng trên JavaFX.

Nó có thể được tìm thấy trên Github tại https://github.com/halgari/fn-fx .

Để sử dụng, hãy đảm bảo bạn đang sử dụng một phiên bản Java gần đây (1.8 90+) và thêm một phụ thuộc vào repo github bằng cách thêm phần sau vào dự án của bạn.clj:

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

Tôi đã thử nó, và nó hoạt động ra khỏi hộp.


1

Clojure và SWT là cách tiếp cận tốt nhất để thực hiện GUI (s). Về cơ bản, SWT là một cách tiếp cận kiểu cắm và phát để phát triển phần mềm.


1
Bạn có thể cung cấp một liên kết hoặc một ví dụ? Tôi sẽ quan tâm nhưng không biết làm thế nào để bắt đầu.
Carl Smotricz

1
Carl, thứ hai đó. Một hướng dẫn tốt về cách viết các trình cắm thêm Eclipse bằng clojure sẽ khá hay.
Egon Willighagen

1

Tôi không nghĩ có một bản chính thức, nhưng cá nhân tôi sẽ tận dụng sự thật rằng tôi đang sử dụng một trong những ngôn ngữ mạnh nhất trên thế giới và chỉ cần tưởng tượng mã gui hoàn hảo sẽ trông như thế nào:

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

Ý tưởng của bạn sẽ khác nhau nhưng điều này hy vọng những điều trên cung cấp cho bạn một số ý tưởng.


Có vẻ như Groovy SwingBuilder đã dịch sang Clojure.
Marko

@ dev-er-dev Điều đó rất có thể, tôi chưa bao giờ sử dụng Groovy, nhưng những bộ óc vĩ đại cũng làm điều tương tự :)
tomjen

1

Tôi biết rằng bạn đang gợi ý cho các giải pháp máy tính để bàn cổ điển, nhưng web phù hợp khá tốt với clojure. Tôi đã viết một ứng dụng âm thanh hoàn chỉnh trong đó mọi thứ được nối lên để nếu bạn thêm nhạc vào thư mục âm thanh, nó sẽ được phản ánh trong giao diện người dùng web. Chỉ cần nói rằng ứng dụng Desktop không phải là cách duy nhất :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.