在Clojure中做 GUI 的最佳方法是什么?
是否有一些功能性Swing或SWT包装器的示例?或者与JavaFX声明性 GUI 描述的一些集成,可以使用一些宏观很容易地包装到s 表达式?
有教程吗?
我会谦虚地建议Seesaw。
这是一个基于 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
如果您想做 GUI 编程,我会指向Temperature Converter或ant Colony。
Swing 中的许多事情都是通过子类化完成的,尤其是在创建自定义组件时。为此,有两个基本功能/宏:代理和gen-class。
现在我明白了你用更 Lispy 的方式要去哪里。我认为还没有这样的事情。我强烈建议不要尝试构建一个宏大的 GUI 构建框架 a-la CLIM,而是做一些更 Lispy 的事情:开始编写你的 Swing 应用程序并用宏抽象出你的常见模式。这样做时,您最终可能会使用一种语言来编写您的 GUI,或者可能是一些可以共享和发展的非常通用的东西。
在 Clojure 中编写 GUI 时您会失去一件事,那就是使用像 Matisse 这样的工具。这可能是在 Java 中编写一些部分(GUI)和在 Clojure 中编写一些部分(逻辑)的一个强项。这实际上是有道理的,因为在逻辑中您将能够使用宏为您的逻辑构建一种语言,我认为那里可以获得比 GUI 更多的东西。显然,这取决于您的应用程序。
还没有人建议,所以我会:浏览器作为 UI 平台。您可以在 Clojure 中编写您的应用程序,包括一个 HTTP 服务器,然后使用从 HTML 到 hiccup、ClojureScript 以及您需要的任何数十亿个 JS 库中的任何内容来开发UI。如果您想要一致的浏览器行为和“桌面应用程序外观”,您可以将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 的包装器。你也可以看看这个要点。我基本上是在学习摇摆/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)))
我宁愿去clojurefx,这有点为时过早,但它确实有效并且可以节省你的时间。
我用跷跷板启动了我的 GUI,然后在 clojurefx 中尝试了另一个组件。
我已经完成了两者,并且我确信我将把跷跷板重构为 clojurefx。
毕竟,JavaFX 是前进的道路。
感觉比跷跷板轻。或者至少,写它..
绑定工作,侦听器工作,大部分组件工作,否则,只需使用其中一个宏来为特定情况创建构造函数并完成工作。或者,如果您觉得困难,请用 Java 编写一些方法并寻求帮助以改进 clojurefx。
写 clojurefx 的人现在很忙,但你可以分叉项目并做一些修复。
邮件列表上已经讨论了一些 Cells (类似于 Kenny Tilton 的 Cells)实现。这是进行 GUI 编程的一种非常巧妙的方法。
这是另一个非常基本的摆动包装示例:
; 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 小程序,其中除了用 Java 编写的小程序代码外,所有内容都是用 Clojure 编写的。小程序从 java 的钩子中调用 Clojure 代码的 init、paint 等回调,用于小程序模型定义的那些方法。所以代码最终是 99.999% 的 Clojure,而且您在大多数情况下根本不必考虑微小的 Java 部分。
这种方法有一些缺点,我希望在 Clojure Google Group 上更详细地讨论。我认为 Clojure 开发人员应该包含构建应用程序的本地方式。目前你可以从 REPL 中做任何你喜欢的 GUI 东西,但是如果你想要一个可交付的 GUI 应用程序,就必须编写一些 Java 来调用 Clojure 代码。此外,Java Applet 的架构似乎迫使您脱离 Clojure 更惯用的最佳实践,要求您使用可变状态等。
但是,我与 Clojure 的距离还不是很远,而且可能是这样,但我还没有发现如何正确地做到这一点。
我首选的 Clojure UI 环境使用IO.js (Node for ES6) + Electron (Container) + Quiescent (ReactJS wrapper)。
所以我没有在这个名单上看到来自 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})])
你的想法会有所不同,但这应该希望上面能给你一些想法。
我知道您在暗示经典的桌面解决方案,但 web 非常适合 clojure。我编写了一个完整的音频应用程序,其中所有内容都已连接,因此如果您将音乐添加到音频文件夹,它会反映在 Web UI 中。只是说桌面应用程序不是唯一的方法:)
cljfx被描述为
JavaFX 的声明性、功能性和可扩展包装器,灵感来自 react 和 re-frame 的更好部分
和JavaFx作为
... 一个开源的下一代客户端应用平台,适用于基于 Java 构建的桌面、移动和嵌入式系统。这是许多个人和公司的协作努力,其目标是为开发富客户端应用程序生成一个现代、高效且功能齐全的工具包。
它的创建者使用它来构建显示,以及一个 以各种功能为特色的hackernews 演示,以及通过jpackage为多个操作系统捆绑的一些内容。
通过利用 JavaFX 为桌面、移动和 Web 构建 UI,您可以获得 Clojure REPL 驱动的开发。