Answers:
我会谦虚地建议跷跷板。
这是一个基于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!)
Stuart Sierra最近发表了一系列有关使用clojure(和swing)进行GUI开发的博客文章。从这里开始:http : //stuartsierra.com/2010/01/02/first-steps-with-clojure-swing
Swing中的许多事情都是通过子类完成的,尤其是在创建自定义组件时。为此,有两个基本功能/宏:proxy和gen-class。
现在,我更了解Lispy的方式了。我认为还没有这样的事情。我强烈建议不要尝试构建宏伟的GUI构建框架a-la CLIM,而要做更多的Lispy:开始编写Swing应用程序并使用宏抽象出常见的模式。这样做时,您可能最终会使用一种语言来编写自己的GUI,或者可能会共享和扩展一些非常通用的东西。
使用Clojure编写GUI时,您失去的一件事就是使用Matisse之类的工具。可以用Java(GUI)和Clojure(逻辑)的某些部分来指出这一点。实际上,这在逻辑上是有意义的,因为您将能够使用宏为某种逻辑构建语言,并且我认为从GUI那里可以获得更多的好处。显然,这取决于您的应用程序。
尚无人建议,因此,我将:浏览器作为UI平台。你可以写你的应用程序中的Clojure,包括HTTP服务器,然后使用任何从HTML开发UI 打嗝,ClojureScript任何十亿JS的libaries你的需要。如果您想要一致的浏览器行为和“桌面应用程序外观”,可以将chrome与您的应用程序捆绑在一起。
这似乎就是Light Table的分配方式。
从此页面:
(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网站的互操作性部分。
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)))
在邮件列表上已经讨论了一些Cells(la Kenny Tilton的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,其中除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的关系还不是很远,可能是有可能的,而我只是还没有发现如何正确地做。
我首选的Clojure UI环境使用IO.js(ES6的节点) + Electron(容器) + Quiescent(ReactJS包装器)。
因此,我没有在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})])
您的想法会有所不同,但是希望以上内容能给您一些想法。