Scala适合的GUI框架是什么?

74

我所指的“合适”是:

  • 成熟且被广泛使用
  • 具有良好渲染效果的丰富小部件集
  • 符合惯用的Scala语言风格
  • 拥有一个所见即所得但灵活的GUI构建器
  • 独立的API文档(如果是包装器,则不应该让我参考另一种语言中的父项目)

没有特定顺序。

哪些GUI工具包满足这些条件?


1
不考虑基于Java的框架是没有帮助的。有Scala Swing,它部分封装了Swing并且与Scala一起提供。可能还有一些小型项目试图构建Scala封装以支持类似JavaFX 2.0或SWT的内容。我认为其他(甚至)Java框架将不能满足您的要求。 - ziggystar
我认为目前没有适用于Scala的GUI构建器。您可以将由NetBeans生成的Java代码复制并粘贴到IntelliJ中,以便自动转换为Scala,但是如果随后想更改布局,则会很麻烦,并且您只能使用Java Swing,因此它不是惯用的方法,但不幸的是目前还没有其他选择。 - Luigi Plinge
1
我要建议你的是我现在为GUI所做的。使用HTML(5)和JavaScript(AngularJS很好)开发您的GUI,然后您可以在应用程序中开发一个非常小的服务器来公开一些类似于REST的服务供GUI使用。您可以在系统的默认浏览器中打开应用程序页面(localhost:your-server-port),或者您可以在JFrame中嵌入一个浏览器组件。我提出这个解决方案的理由是HTML是最独立于平台且最丰富的GUI库。甚至Oracle正式声明Swing不会被长期维护。 - ehsun7b
5个回答

40
Scala有自己的Swing库。它将在底层使用标准的Swing库,但它具有一些不错的附加功能,最重要的是,因为它是为Scala而设计的,所以可以比标准的Swing库更加简洁地使用:
import swing._

object HelloWorld extends SimpleSwingApplication {
  def top = new MainFrame {
    title = "Hello, World!"
    contents = new Button {
      text = "Click Me!"
    }
  }
}

看看设置小部件属性有多么简单易懂?

除了更好的语法和小的补充(比如SimpleSwingApplication类),我认为优缺点与普通Swing基本相同。

这是Scala Swing概述


那不是看起来有很多缩进吗?有什么办法可以避免回飞效应吗? - Chetan Bhasin

26
ScalaFX是JavaFX 2的成熟封装,与Scala Swing在某些方面表面上相似,但具有一些使其脱颖而出的功能:
  • 与本地图形库耦合 - 这意味着可以访问硬件加速和其他好处,但需要安装JavaFX运行时。它包含在大多数主要的Java 8发行版中。这也意味着它在兼容的系统上渲染非常好。

  • 属性绑定 - 这对我来说是致命的特点。假设我有三个元素:ABCAB可调整大小,并且C的高度始终是AB高度之和。在Swing中,这将涉及编写一组自定义事件侦听器来执行此工作。ScalaFX绑定允许您通过使用属性绑定操作符简单地表达这一点:C.height <== A.height + B.height。除此之外,还具有其他功能,使其非常符合Scala惯用语法。

  • JavaFX Scene Builder(截至撰写本文为止处于beta阶段)是一个所见即所得的GUI编辑器(虽然我没有尝试过)。

  • 文档是其薄弱环节。作为一个封装,它经常回头参考JavaFX文档。


18

我使用Java Swing。以下是它与你的要求相比的情况:

  • 成熟且被广泛使用:是的,非常多。

  • 丰富的小部件集和良好的渲染效果:这是有争议的。当考虑到可以轻松地用其他库(例如SwingX)补充Java Swing时,在这方面至少比Scala Swing做得更好,尽管可能不如某些其他Java工具包(但我无法对此发表意见)。

  • 符合惯用Scala的:并没有你想象中的那么差。一些辅助函数使它更好:

  • implicit class And[A](a: A) {
      def and(f: A => Unit): A = {
        f(a); a
      }
    }
    

    这样你就能做到

    val button = (new JButton("Press me!")
        and (_ setForeground Color.red)
        and (_ setFont new Font(null, Font.PLAIN, 12)))
    
    val win = (new JFrame("Hello!")
      and (_ add button)
      and (_ pack())
      and (_ setDefaultCloseOperation JFrame.EXIT_ON_CLOSE)
      and (_ setVisible(true)))
    

    就事件和状态而言,这在我看来仍然是所有GUI框架中的一个糙点 - 监听器存在问题,事件流也存在问题。我成功地使用了reactive-coreredo-signals(我的自己的未记录文档)来增强Swing的事件,以便更轻松地组织状态。

    您可以通过一些辅助函数来改善定义监听器的冗长性如下:

      def actionListener(f: => Unit) = new ActionListener {
        def actionPerformed(e: ActionEvent) { f }
      }
    

      def later(thing: => Unit) {
        SwingUtilities.invokeLater(new Runnable {
          def run() {
            thing
          }
        })
      }
    

    就个人而言,我希望Scala Swing采取这种方式。编写现有Java类的包装器需要O(n)程序员时间,并且对于作者没有选择编写包装器的类,您将得不到任何东西。创建通用语法糖会让您更快地走得更远。

  • 拥有WYSIWYG-ish但灵活的GUI构建器:我使用IntelliJ IDEA表单创建一个抽象类,然后用Scala类进行子类化。组织成本仅为1个额外的文件,而且我不编写任何Java代码。

  • 独立的API文档:是的。


8

现在过了一段时间,值得注意的是ScalaJS也是值得考虑的选项。

根据您的要求:

  • 成熟且广泛使用-HTML/CSS/JS是,而ScalaJS不是(但它出人意料地好)。所以,您可能会遇到特定于ScalaJS的问题,但底层技术非常强大。
  • 丰富的小部件集,渲染效果良好-是的。
  • 符合惯用法的Scala-No:您最终会使用很多jquery,它们大多数是动态类型。ScalaTags 对使它更好起了很大的作用。
  • 拥有WYSIWYG但灵活的GUI构建器-是的,有很多。
  • 独立的API文档(如果是包装器,则不应使我参考另一种语言的父项目)-是的。

缺点是它将GUI从JVM中移出并放入浏览器中,因此无法使用所有那些Java库。


2
如果你选择这个方向(你应该选择,scala.js 真的很棒!),这里有一个非常好的教程:http://lihaoyi.github.io/hands-on-scala-js/。Lihaoyi 的库也非常可靠 - scalatags、autowire、upickle、utest - 你应该去看看它们。 - kornfridge

-25

我建议使用.Net,因为它已经成熟并被广泛使用。

但是...

我假设你需要使用Scala。对于这个,我会坚持使用Java,因为它有更好的工具支持,比如IDEA或NetBeans。当然,你可以混合使用Java和Scala。所以你的GUI可以用Java来完成,调用Scala后端。同时,你也可以看看JGoodies,他们有很多不错的东西来构建Swing界面。目前还没有Scala GUI应用程序的工具支持(对于非GUI应用程序,它仍然落后于Java)。


JGoodies Binding是一种非常好的功能性UI描述方式。它的ValueModel概念与Lenses非常相似。我希望有人能编写一个Scala包装器或实现。 - Felix Leipold
1
你能从Java调用.Net吗? - vy32
好的...但是这怎么回答问题呢? - Emrys Myrooin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接