在Clojure中制作GUI的最佳方法是什么?


Answers:


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
让Swing有趣吗?他们说不可能!
Michael Bylstra 2013年

9
无需谦虚-您可以为此感到自豪!+1!
mydoghasworms

7
-1:您的代码中有一个错误。它说的是“ Hello,Seesaw”,而不是“ Hello,World”。</ Joke>
托马斯·爱丁

1
真?摇摆?这是否不限制开发人员仅在更高的抽象层次上使用Swing提供的功能?Clojure会以某种方式使应用程序看起来过时吗,还是以某种方式改善了Swing薄弱的所有方面?我正在谈论绑定和MVC以及Swing现在本身提供的所有“新”东西。Clojure的语言功能是否已解决该问题?
Zelphir Kaltstahl'2

1
他选择专门针对Swing进行重点抽象。没什么问题...
Kenogu Labz 2016年


16

如果要进行GUI编程,我将指向“ 温度转换器”“蚁群”

Swing中的许多事情都是通过子类完成的,尤其是在创建自定义组件时。为此,有两个基本功能/宏:proxygen-class

现在,我更了解Lispy的方式了。我认为还没有这样的事情。我强烈建议不要尝试构建宏伟的GUI构建框架a-la CLIM,而要做更多的Lispy:开始编写Swing应用程序并使用宏抽象出常见的模式。这样做时,您可能最终会使用一种语言来编写自己的GUI,或者可能会共享和扩展一些非常通用的东西。

使用Clojure编写GUI时,您失去的一件事就是使用Matisse之类的工具。可以用Java(GUI)和Clojure(逻辑)的某些部分来指出这一点。实际上,这在逻辑上是有意义的,因为您将能够使用宏为某种逻辑构建语言,并且我认为从GUI那里可以获得更多的好处。显然,这取决于您的应用程序。


2
不用担心松开Mattisse。您可以使用miglayout.com,该功能足够强大,可以手动进行布局。
tomjen

您可以将Matisse与Clojure一起使用,因为生成的代码只是Java代码,可以由Clojure无缝访问。实际上某处有一个教程……
Rayne,2009年

3
我想知道我们何时获得第一个输出clojure的GUI设计器。由于同源性,生成的代码甚至应该都不错!
nperson325681 2010年

15

尚无人建议,因此,我将:浏览器作为UI平台。你可以写你的应用程序中的Clojure,包括HTTP服务器,然后使用任何从HTML开发UI 打嗝,ClojureScript任何十亿JS的libaries你的需要。如果您想要一致的浏览器行为和“桌面应用程序外观”,可以将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块中的成员函数调用之前。
Jeroen Dirks,2009年

8

clojure contrib中有一个MigLayout的包装器。您也可以看看这个要点。当我学习swing / miglayout时,我基本上会编写我正在编写的任何代码。

使用contrib.swing-utils以小巧的方式重写了dsm的示例

(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中的另一个组件。

我都完成了,我坚信我将把跷跷板重构为clojurefx。

毕竟,JavaFX是前进的方法。

感觉比跷跷板还轻。或至少写出来。

绑定工作,侦听器工作,大部分组件工作,否则,只需使用宏之一为该特定情况和完成的工作创建一个构造函数。或者,如果发现困难,请用Java编写一些方法并寻求帮助来改进clojurefx。

编写clojurefx的人目前很忙,但是您可以分担该项目并进行一些修复。


JavaFX解决了看起来还不是很原生的问题吗?严重的问题,因为当我第一次检查时,它是很久以前的,它看起来不如Swing正确。
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

我问自己同样的问题,就是用Swing在Clojure中编写GUI,并想到了库签名。

它使您可以将域模型表示为包裹在原子内的单个Clojure数据结构。

请参阅此处的示例。


2

我一直在开发Java applet,其中除applet代码以外,所有其他内容均以Clojure编写。applet从java的钩子中调用Clojure代码对init,paint等的回调,这些回调由applet模型定义的那些方法。因此,代码最终是Clojure的99.999%,并且您基本上不需要考虑所有很小的Java代码。

这种方法有一些缺点,我希望在Clojure Google Group上进行详细讨论。我认为Clojure开发人员应包括一种构建应用程序的本地方法。目前,您可以从REPL中执行任何您喜欢的GUI任务,但是如果您想要可交付的GUI应用程序,则必须编写一些Java来调用Clojure代码。同样,似乎Java Applet的体系结构迫使您超出Clojure的惯用最佳实践,要求您使用可变状态等。

但是,我与Clojure的关系还不是很远,可能是有可能的,而我只是还没有发现如何正确地做。



2

因此,我没有在Timothy Baldridge(halgiri)的名单上看到Fn-Fx。这是一个Clojure库,通过JavaFX提供功能抽象。

可以在Github上的https://github.com/halgari/fn-fx上找到。

要使用,请确保您使用的是Java(1.8 90+)的最新版本,并通过将以下内容添加到project.clj中来向github存储库添加依赖项:

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

我已经尝试过了,它开箱即用。


1

Clojure和SWT是执行GUI的最佳方法。本质上,SWT是一种用于开发软件的即插即用风格的方法。


1
您能否提供链接或示例?我会感兴趣,但不知道如何开始。
卡尔·斯莫特里奇

1
卡尔,第二个。关于如何使用clojure编写Eclipse插件的很好的教程将是非常不错的。
Egon Willighagen,2010年

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

您的想法会有所不同,但是希望以上内容能给您一些想法。


看起来像转换为Clojure的groovy SwingBuilder dsl。
Marko

@ dev-er-dev很有可能,我从未使用过Groovy,但是伟大的思想家都做过类似的事情:)
tomjen

1

我知道您在暗示经典的台式机解决方案,但是Web与Clojure非常吻合。我已经编写了一个完整的音频应用程序,其中的所有内容均已连接,因此,如果将音乐添加到音频文件夹,它将反映在Web UI中。只是说桌面应用程序不是唯一的方法:)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.