Clojure GUI编程很难

14

我正在编写一个使用Swing GUI的实用程序。我试图使用Martin Fowler的Presentation Model来促进测试。我的应用将自动使用java.util.prefs.Preferences存储几个用户偏好设置(即:主窗口位置和大小)。我花费了整个周末的时间尝试创建Clojure模拟Preferences API(使用EasyMock),以便可以测试我的Presenter代码,但无法使其正常工作。对于一个长期使用OO编程风格的程序员来说,使用非OO编程风格的Clojure GUI编程确实很困难。我感觉如果我能发现/开发这些事情的模式(模拟,面向可视化“类”的“接口”等),我就可以在整个应用程序中继续使用相同的模式。

我还使用Scala开发了相同的应用程序,以比较编程模式,并发现它更加直观,即使我试图以相当严格的函数式风格使用Scala(当然不包括调用Java类如Swing API - 这在Clojure版本中也会有相同的可变性问题,但当然也是单线程的)。

在我的Scala代码中,我创建了一个名为MainFrame的类,它扩展了JFrame并实现了特质MainViewMainView将所有JFrame调用公开为抽象方法,我可以在模拟对象中实现这些方法:

trait LabelMethods {
  def setText(text: String)
  //...
}

trait PreferencesMethods {
  def getInt(key: String, default: Int): Int
  def putInt(key: String, value: Int)
  //...
}

trait MainView {
  val someLabel: LabelMethods
  def addComponentListener(listener: ComponentListener)
  def getLocation: Point
  def setVisible(visible: Boolean)
  // ...
}

class MainFrame extends JFrame with MainView {
  val someLabel = new JLabel with LabelMethods
  // ...
}

class MainPresenter(mainView: MainView) {
  //...
  mainView.addComponentListener(new ComponentAdaptor {
    def componentMoved(ev: ComponentEvent) {
      val location = mainView.getLocation
      PreferencesRepository.putInt("MainWindowPositionX", location.x)
      PreferencesRepository.putInt("MainWindowPositionY", location.y)
  }
  mainView.someLabel.setText("Hello")
  mainView.setVisible(true)
}

class Main {
  def main(args: Array[String]) {
    val mainView = new MainFrame
    new MainPresenter(mainView)
  }
}

class TestMainPresenter {
  @Test def testWindowPosition {
    val mockPreferences = EasyMock.mock(classOf[PreferencesMethods])
    //... setup preferences expectation, etc.
    PreferencesRepository.setInstance(mockPreferences)

    val mockView = EasyMock.createMock(classOf[MainView])
    //... setup view expectations, etc.
    val presenter = new MainPresenter(mockView)
    //...
  }
}
我正在使用一种伪单例(包括setInstance,以便模拟可以替换“真实”版本)来处理首选项,因此没有显示详细信息。我知道蛋糕模式(cake pattern),但在这种情况下,我发现我自己的方法更容易使用。
我一直在尝试在Clojure中编写类似的代码。 有哪些开源项目提供了这种类型的好示例? 我已经阅读了几本Clojure书籍(Programming Clojure、The Joy of Clojure、Practical Clojure),但没有看到这些问题的解决方案。 我也研究了Rich Hickey的ants.clj,但他在那个示例中对Swing的使用非常基本。
1个回答

1

请查看这两个在 Clojure 领域非常流行的选项:

  • CLJFX 如果你可以接受从 Swing 转移到 JavaFX。
  • Seesaw 如果你更愿意继续使用 Swing。

编辑:最新信息:https://tonsky.me/blog/skija/


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