在Clojure中执行GUI的最佳方法是什么?
是否有一些功能性Swing或SWT包装器的示例? 或者与JavaFX声明性GUI描述的某些集成,可以使用某些宏观术轻松地包装到s-expressions?
任何教程?
答案 0 :(得分:116)
我会谦卑地建议Seesaw。
假设没有Java或Swing知识的(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!)
答案 1 :(得分:32)
答案 2 :(得分:16)
如果您想进行GUI编程,我会指向Temperature Converter或the ants colony。
Swing中的许多内容都是通过子类化完成的,特别是在创建自定义组件时。为此,有两个基本功能/宏:proxy和gen-class。
现在我明白你在哪里采用更多的Lispy方式。我认为还没有那样的东西。我强烈建议不要尝试构建一个宏大的GUI构建框架a-la CLIM,而是做更多的Lispy:开始编写Swing应用程序并用宏来抽象出你的常见模式。在这样做的时候,你可能会得到一种语言来编写你的GUI,或者可能是一些可以共享和发展的非常通用的东西。
在Clojure中编写GUI时丢失的一件事是使用像Matisse这样的工具。这可以强烈指向在Java(GUI)和Clojure(逻辑)中编写一些部分。这实际上是有意义的,因为在逻辑上你将能够使用宏为你的逻辑构建一种语言,我认为除了GUI之外还有更多的东西可以获得。显然,这取决于你的申请。
答案 3 :(得分:14)
从此page:
(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网站的interoperability部分。
答案 4 :(得分:14)
还没人建议,所以我会:浏览器作为UI平台。您可以在Clojure中编写应用程序,包括HTTP服务器,然后使用从HTML到hiccup,ClojureScript以及您需要的任何数十亿个JS库中的任何内容开发UI。如果您想要一致的浏览器行为和“桌面应用程序外观”,您可以bundle chrome with your app。
这似乎是Light Table的分发方式。
答案 5 :(得分:8)
clojure contrib中有一个MigLayout包装器。你也可以看看http://gist.github.com/261140。我基本上都在编写我正在编写的代码,因为我正在学习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)))
答案 6 :(得分:6)
关于几个Cell(la talk on the mailing list)实现已经Kenny Tilton's Cells了。这是一种非常巧妙的GUI编程方式。
答案 7 :(得分:5)
我宁愿选择clojurefx,它有点为时过早,但确实有效并节省您的时间。
我用跷跷板开始我的GUI,然后在clojurefx中尝试了另一个组件。
我已经完成了两次,我确信我要将跷跷板重构为clojurefx。
毕竟,JavaFX是前进的方式。
感觉比跷跷板轻。或至少,写它..
绑定工作,侦听器工作,大部分组件工作,否则,只需使用其中一个宏为特定案例和工作完成创建构造函数。或者,如果您觉得困难,请在Java中编写一些方法并寻求帮助以改进clojurefx。
编写clojurefx的人现在很忙,但你可以分叉项目并做一些修复。
答案 8 :(得分: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)))
答案 9 :(得分:3)
我问自己在使用Swing在Clojure中编写GUI的同样问题,并提出了这个库:
https://github.com/jonasseglare/signe
它允许您将域模型表示为包含在原子内的单个Clojure数据结构。
请参阅此处的示例:https://github.com/jonasseglare/signe/blob/master/src/signe/examples.clj
答案 10 :(得分:2)
所以我没有在Timothy Baldridge(halgiri)的名单上看到Fn-Fx。这是一个Clojure库,提供了对JavaFX的功能抽象。
可以在https://github.com/halgari/fn-fx的Github上找到。
要使用,请确保使用的是最新版本的Java(1.8 90+),并通过将以下内容添加到project.clj中来向github仓库添加依赖项:
:plugins [[lein-git-deps "0.0.1-SNAPSHOT"]]
:git-dependencies [["https://github.com/halgari/fn-fx.git"]]
我试过了,开箱即用。
答案 11 :(得分:2)
我一直在开发一个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的关系并不是很远,可能就是这样,我还没有发现如何正确地做到这一点。
答案 12 :(得分:1)
我知道您正在暗示经典的桌面解决方案,但网络适合clojure。我已经编写了一个完整的音频应用程序,其中包含所有内容,以便在音频文件夹中添加音乐时,它会反映在Web UI中。只是说桌面应用程序不是唯一的方法:)
答案 13 :(得分:1)
我首选的Clojure UI环境使用IO.js (Node for ES6) + Electron (Container) + Quiescent (ReactJS wrapper)。
答案 14 :(得分: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})])
你的想法会有所不同,但希望上面给你一些想法。
答案 15 :(得分:1)
Clojure和SWT是进行GUI的最佳方法。从本质上讲,SWT是一种用于开发软件的即插即用方式。
答案 16 :(得分:0)
cljfx 被描述为
<块引用>JavaFX 的声明性、功能性和可扩展包装器,其灵感来自于 React 和重新构建的更好部分
和 JavaFx 为
<块引用>... 一个开源的下一代客户端应用程序平台,适用于基于 Java 构建的桌面、移动和嵌入式系统。这是许多个人和公司的共同努力,旨在为开发富客户端应用程序开发一个现代、高效且功能齐全的工具包。
它的创建者使用它来构建 reveal 和一个 hackernews demo,该 jpackage 具有各种功能,并通过 {{3}} 捆绑多个操作系统。
通过利用 JavaFX 为桌面、移动设备和 Web 构建 UI,您可以获得 Clojure REPL 驱动的开发。