Java 在 Clojure 中执行 GUI 的最佳方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/233171/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:49:19  来源:igfitidea点击:

What is the best way to do GUIs in Clojure?

javauser-interfacelispclojure

提问by Marko

What is the best way to do GUIs in Clojure?

Clojure 中执行 GUI 的最佳方法是什么?

Is there an example of some functional Swingor SWTwrapper? Or some integration with JavaFXdeclarative GUI description which could be easily wrapped to s-expressionsusing some macrology?

是否有一些功能性SwingSWT包装器的示例?或者与JavaFX声明式 GUI 描述的一些集成,可以使用一些宏观轻松包装到s 表达式

Any tutorials?

有教程吗?

采纳答案by Dave Ray

I will humbly suggest Seesaw.

我会虚心推荐跷跷板

Here's a REPL-based tutorialthat assumes no Java or Swing knowledge.

这是一个基于 REPL 的教程,假定没有 Java 或 Swing 知识。



Seesaw's a lot like what @tomjen suggests. Here's "Hello, World":

跷跷板很像@tomjen 的建议。这是“你好,世界”:

(use 'seesaw.core)

(-> (frame :title "Hello"
       :content "Hello, Seesaw"
       :on-close :exit)
  pack!
  show!)

and here's @Abhijith and @dsm's example, translated pretty literally:

这是@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!)

回答by dsm

From this 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");

And, of course, it would be worth looking at the interoperabilitysection of clojure's website.

而且,当然,值得查看clojure 网站的互操作性部分。

回答by pupeno

If you want to do GUI programming I'd point to Temperature Converteror the ants colony.

如果你想做 GUI 编程,我会指向Temperature Converterantscolony

Many things in Swing are done by sub-classing, particularly if you are creating custom components. For that there are two essential functions/macros: proxyand gen-class.

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

Now I understand where you are going with the more Lispy way. I don't think there's anything like that yet. I would strongly advise against trying to build a grandiose GUI-building framework a-la CLIM, but to do something more Lispy: start writing your Swing application and abstract out your common patterns with macros. When doing that you may end up with a language to write your kind of GUIs, or maybe some very generic stuff that can be shared and grow.

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

One thing you lose when writing the GUIs in Clojure is the use of tools like Matisse. That can be a strong pointing to write some parts in Java (the GUI) and some parts in Clojure (the logic). Which actually makes sense as in the logic you'll be able to build a language for your kind of logic using macros and I think there's more to gain there than with the GUI. Obviously, it depends on your application.

在 Clojure 中编写 GUI 时您失去的一件事是使用了像 Matisse 这样的工具。用 Java(GUI)编写一些部分,用 Clojure(逻辑)编写一些部分,这可能是一个强有力的指示。这实际上是有道理的,因为在逻辑中,您将能够使用宏为您的逻辑构建一种语言,而且我认为在那里获得的比使用 GUI 还多。显然,这取决于您的应用程序。

回答by Berlin Brown

Clojure and SWT is the best approach for doing GUI(s). Essentially, SWT is a plug and play style approach for developing software.

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

回答by Berlin Brown

I've been developing a Java applet in which everything is written in Clojure except the applet code, which is written in Java. The applet invokes the Clojure code's callbacks of init, paint, etc from java's hooks for those methods that are defined by the applet model. So the code ends up being 99.999 percent Clojure and you don't have to think about the tiny Java piece at all for the most part.

我一直在开发一个 Java 小程序,其中除了小程序代码是用 Java 编写的之外,所有内容都是用 Clojure 编写的。小程序从 Java 的钩子中为小程序模型定义的那些方法调用 Clojure 代码的 init、paint 等回调。因此,代码最终是 99.999% 的 Clojure,并且您在大多数情况下根本不必考虑小 Java 部分。

There are some drawbacks to this approach, which I hope to discuss in more detail on the Clojure Google Group. I think the Clojure developers should include a native way of building applications. Presently you can do whatever GUI stuff you like from the REPL, but if you want a deliverable GUI application, it is necessary to write some Java to call the Clojure code. Also, it seems like the architecture of a Java Applet kind of forces you outside of Clojure's more idiomatic best practices, requiring you to use mutable state, etc.

这种方法有一些缺点,我希望在 Clojure Google Group 上更详细地讨论。我认为 Clojure 开发人员应该包括构建应用程序的本机方式。目前,您可以从 REPL 中执行任何您喜欢的 GUI 操作,但是如果您想要一个可交付的 GUI 应用程序,则需要编写一些 Java 来调用 Clojure 代码。此外,似乎 Java Applet 的架构迫使您脱离 Clojure 更惯用的最佳实践,要求您使用可变状态等。

But also, I am not very far along with Clojure yet and it might be the case that it is possible and I just haven't discovered how to do it correctly yet.

而且,我对 Clojure 的了解还不是很远,可能是这样,我只是还没有发现如何正确地做到这一点。

回答by Joe W.

There's been talk on the mailing listabout a few Cells (a la Kenny Tilton's Cells) implementations. It's a pretty neat way to do GUI programming.

邮件列表上已经讨论了一些 Cells(如Kenny Tilton 的 Cells)实现。这是进行 GUI 编程的一种非常巧妙的方式。

回答by Jeroen Dirks

Here is another very basic swing wrapping example:

这是另一个非常基本的摆动包装示例:

; 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)))

回答by tomjen

I don't think there is an official one, but personally I would take advantage of the fact that I am using one of the most powerful language in the world and just imagine what the perfect gui code would look like:

我不认为有官方的,但我个人会利用我使用的是世界上最强大的语言之一这一事实,想象一下完美的 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})])

Your idea would differ but this should hopefully the above gives you some idea.

你的想法会有所不同,但这应该希望以上能给你一些想法。

回答by Abhijith

There is a wrapper for MigLayout in clojure contrib. You can also take a look at this gist. I am basically putting up whatever code I am writing as I am learning swing/miglayout.

在 clojure contrib 中有一个 MigLayout 包装器。你也可以看看这个 gist。在学习 Swing/miglayout 时,我基本上是在写我正在编写的任何代码。

dsm's example re-written in a lispy way using contrib.swing-utils

dsm 的示例使用 contrib.swing-utils 以一种简洁的方式重写

(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)))

回答by Anders Rune Jensen

I know that you are hinting for classical desktop solutions, but web fits quite well with clojure. I've written a complete audio application where everything is hooked up so that if you add music to the audio folder it is reflected in the web UI. Just saying that Desktop application isn't the only way :)

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

回答by steglig

Stuart Sierra recently published a series of blog posts on GUI-development with clojure (and swing). Start off here: http://stuartsierra.com/2010/01/02/first-steps-with-clojure-swing

Stuart Sierra 最近发表了一系列关于使用 clojure(和 Swing)进行 GUI 开发的博客文章。从这里开始:http: //stuartsierra.com/2010/01/02/first-steps-with-clojure-swing