在Clojure中进行GUI的最佳方法是什么?
-
04-07-2019 - |
题
在 Clojure 中执行GUI的最佳方法是什么?
是否有一些功能性的 Swing 或 SWT 包装器? 或者与 JavaFX 声明性GUI描述集成,可以很容易地包装到 s-expressions 使用了一些宏观学?
任何教程?
解决方案
我会谦虚地建议跷跷板。
这是一个基于REPL的教程,假设没有Java或Swing知识。
跷跷板很像@tomjen所说的。这是“Hello,World”:
(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!)
其他提示
如果您想进行GUI编程,我会指向 Temperature Converter 或蚂蚁群体。
Swing中的许多内容都是通过子类化完成的,特别是在创建自定义组件时。为此,有两个基本功能/宏:代理和 gen-class 。
现在我明白你在哪里采用更多的Lispy方式。我认为还没有那样的东西。我强烈建议不要试图建立一个宏伟的GUI构建框架a-la CLIM ,但要做点什么更多Lispy:开始编写Swing应用程序并使用宏抽象出常见的模式。在这样做的时候,你最终可能会使用一种语言来编写你的GUI,或者一些可以共享和发展的非常通用的东西。
在Clojure中编写GUI时丢失的一件事是使用像Matisse这样的工具。这可以强烈指向在Java(GUI)和Clojure(逻辑)中编写一些部分。这实际上是有意义的,因为在逻辑上你将能够使用宏为你的逻辑构建一种语言,我认为除了GUI之外还有更多的东西可以获得。显然,这取决于你的申请。
从这个页面:
(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网站的互操作性部分。
还没人建议,所以我会:浏览器作为UI平台。您可以在Clojure中编写您的应用程序,包括HTTP服务器,然后使用从HTML到打嗝,ClojureScript和任何您需要的数十亿个JS库。如果您想要一致的浏览器行为和“桌面应用程序外观”感觉“您可以将chrome与您的应用捆绑在一起。
这似乎是 Light Table 的分发方式。
clojure contrib中有一个MigLayout包装器。您还可以查看这个要点。我基本上都在编写我正在编写的代码,因为我正在学习swing / miglayout。
dsm的示例使用contrib.swing-utils
以lispy方式重写(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)))
在邮件列表上发言关于几个单元格( la Kenny Tilton's Cells )实施。这是一种非常巧妙的GUI编程方式。
我宁愿选择clojurefx,它有点为时过早,但确实有效并节省您的时间。
我用跷跷板开始我的GUI,然后在clojurefx中尝试了另一个组件。
我已经完成了两次,我确信我要将跷跷板重构为clojurefx。
毕竟,JavaFX是前进的方式。
感觉比跷跷板轻。或至少,写它..
绑定工作,侦听器工作,大部分组件工作,否则,只需使用其中一个宏为特定案例和工作完成创建构造函数。或者,如果您觉得困难,请在Java中编写一些方法并寻求帮助以改进clojurefx。
编写clojurefx的人现在很忙,但你可以分叉项目并做一些修复。
这是另一个非常基本的摇摆包装示例:
; 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)))
我一直在开发一个Java applet,其中所有内容都是用Clojure编写的,除了用Java编写的applet代码。 applet调用Clojure代码对java的钩子中的init,paint等的回调,用于applet模型定义的那些方法。所以代码最终得到了99.999%的Clojure,你根本不需要考虑这个小小的Java部分。
这种方法有一些缺点,我希望在Clojure Google Group上更详细地讨论。我认为Clojure开发人员应该包含一种构建应用程序的本地方式。目前,您可以从REPL中执行任何您喜欢的GUI操作,但如果您需要可交付的GUI应用程序,则需要编写一些Java来调用Clojure代码。此外,似乎Java Applet的体系结构强迫您不在Clojure的更惯用的最佳实践中,要求您使用可变状态等。
但是,我与Clojure的关系并不是很远,可能就是这样,我还没有发现如何正确地做到这一点。
所以我没有在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"]]
我试过了,开箱即用。
Clojure和SWT是进行GUI的最佳方法。从本质上讲,SWT是一种用于开发软件的即插即用方式。
我认为没有官方的,但我个人会利用这样一个事实:我正在使用世界上最强大的语言之一,想象一下完美的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。我已经编写了一个完整的音频应用程序,其中包含所有内容,以便在音频文件夹中添加音乐时,它会反映在Web UI中。只是说桌面应用程序不是唯一的方法:)
我首选的Clojure UI环境使用 IO.js(ES6节点) + 电子(容器) + 静止( ReactJS包装器)。