我正在为介绍性编程学生编写一个图像库。 (我从DrRacket的图像库中偷走了这个想法和模式。)
https://github.com/dupontmanualhs/dm-image
它主要是用Swing编写的(那是master
分支),但我正在尝试将其转换为ScalaFX(参见scalafx
分支),并且存在一些问题。理想情况下,学生应该能够做到这样的事情:
scala> import org.dupontmanual.image._
scala> TrainEngine.display()
并显示一个带有火车引擎的对话框。我已尝试使用
中的代码https://github.com/scalafx/ScalaFX-Tutorials
stand-alone-dialog
项目中的,但如果我在System.exit(0)
之后加入dialog.showAndWait()
,则会收到此错误:
Not interrupting system thread Thread[process reaper,10,system]
Exception while removing reference: java.lang.InterruptedException
java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
at com.sun.glass.utils.Disposer.run(Disposer.java:69)
at java.lang.Thread.run(Thread.java:744)
Not interrupting system thread Thread[Prism Font Disposer,10,system]
Exception in runnable
Exception in thread "JavaFX Application Thread"
(请注意,如果我尝试在控制台中从App
运行stand-alone-dialog
,我会收到相同的错误,因此我猜测调用System.exit(0)
不是一个好主意SBT控制台。)
如果我离开System.exit(0)
线,那么事情看起来似乎很好 - 主要是。在我第一次显示对话框后,它不会使对话框成为焦点,因此我必须单击它才能关闭对话框。但真正的问题是,当我:q
退出控制台时,SBT会挂起,我必须Ctrl-C
才能再次输入。 (并且,是的,Ctrl-C
完全退出SBT,而不仅仅是控制台。)
我认为我可能需要做的是专门为ScalaFX创建一个线程。例如,我有一个方法将一个图像堆叠在另一个上面,当我尝试调用该函数时,我得到一个IllegalStateException
,即使它实际上没有显示任何内容,只需创建一个新的{{1}前两个Group
堆叠得恰当。不幸的是,我不确定如何创建一个新线程,并确保所有与图像相关的内容贯穿其中。
我已在Node
中设置fork := true
,但这似乎与控制台没有区别。
==更新==
我在SBT文档中找到build.sbt
和initialCommands
,并尝试在控制台启动和结束后清理所有内容。值为:
cleanupCommands
由此定义:
initialCommands in console := """import org.dupontmanual.image._; org.dupontmanual.image.initialize()"""
cleanupCommands in console := """org.dupontmanual.image.cleanUp()"""
这是运行控制台然后尝试退出的结果:
package object image {
var masterFrame: JFrame = _
def initialize() {
masterFrame = new JFrame()
masterFrame.add(new JFXPanel())
masterFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
}
def cleanUp() {
println("exiting platform")
Platform.exit()
println("disposing of frames")
Frame.getFrames().foreach {
_.dispose()
}
println("frames all disposed")
System.exit(0);
}
,甚至没有退出控制台。您仍然必须使用Ctrl-C,它完全退出SBT。
有些东西还在运行,但我无法弄清楚它是什么。哎呀。
答案 0 :(得分:0)
我认为问题是你会以某种方式需要分叉控制台,所以也许是这个问题:https://github.com/sbt/sbt/issues/1918
以下想法似乎有效:您可以在sbt控制台中嵌入REPL,例如Ammonite。即使sbt run
,fork in run := true
仍无法正常工作。但包装一个胖罐并运行似乎确实有效:
<强> build.sbt 强>
name := "Foo"
version := "0.1.0"
scalaVersion := "2.11.7"
libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-swing" % "1.0.2",
"com.lihaoyi" % "ammonite-repl" % "0.5.1" cross CrossVersion.full
)
<强>项目/ build.properties 强>
sbt.version=0.13.9
<强>项目/ plugins.sbt 强>
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.1")
<强>的src /主/阶/富/ Main.scala 强>
package foo
import scala.swing._
object Main extends App {
def test(): Unit = Swing.onEDT {
new MainFrame {
contents = new Label("App exits if you close window")
} .open()
}
ammonite.repl.Main.run("")
}
然后
$ sbt assembly
...
$ java -jar target/scala-2.11/Foo-assembly-0.1.0.jar
Loading...
Welcome to the Ammonite Repl 0.5.1
(Scala 2.11.7 Java 1.8.0_66)
@ foo.Main.test()
唯一奇怪的是,在应用程序存在之后,shell字符回显被破坏,也许这是Ammonite的一个问题,你可能想尝试使用默认的Scala REPL。