gpt4 book ai didi

scala - 如何让 ScalaFX 在 SBT 控制台中发挥​​出色?

转载 作者:行者123 更新时间:2023-12-04 12:58:33 24 4
gpt4 key购买 nike

我正在编写一个图像库,供入门编程学生使用。 (我从 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,我会得到同样的错误,所以我猜在 SBT 控制台中调用 System.exit(0) 不是一个好主意。)

如果我离开 System.exit(0)排队,然后事情似乎工作正常 - 大多数情况下。在我第一次显示对话框后,它不会使对话框成为焦点,因此我必须单击它以关闭对话框。但真正的问题是当我 :q要退出控制台,SBT 挂起,我必须 Ctrl-C能够再次打字。 (而且,是的, Ctrl-C 完全退出 SBT,而不仅仅是控制台。)

我想我可能需要做的是专门为 ScalaFX 的东西创建一个线程。例如,我有一种方法可以将一个图像叠加在另一个图像上,我得到了 IllegalStateException当我尝试调用该函数时,即使它实际上没有显示任何内容,也只是创建了一个新的 Group与前两个 Node适当堆叠。不幸的是,我不确定如何创建一个新线程并确保与图像相关的所有内容都通过它。

我已经设置了 fork := truebuild.sbt ,但这似乎与控制台没有区别。

== 更新 ==

我找到了 initialCommandscleanupCommands在 SBT 文档中,并在控制台启动和结束时尝试在所有内容之后进行清理。这些值是:
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);
}

这是运行控制台然后尝试退出的结果:
> console
[info] Compiling 1 Scala source to /home/sysadmin/dm-workspace/dm-image/target/scala-2.10/classes...
[info] Starting scala interpreter...
[info]
import org.dupontmanual.image._
Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51).
Type in expressions to have them evaluated.
Type :help for more information.

scala> Hacker.display()

scala> :q
exiting platform
disposing of frames
frames all disposed
Not interrupting system thread Thread[XToolkt-Shutdown-Thread,5,system]
Not interrupting system thread Thread[AWT-XAWT,6,system]
Not interrupting system thread Thread[Prism Font Disposer,10,system]
Not interrupting system thread Thread[Java2D Disposer,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)

Exception: sbt.TrapExitSecurityException thrown from the UncaughtExceptionHandler in thread "run-main-0"

这甚至没有退出控制台。您仍然必须使用 Ctrl-C,它会完全退出 SBT。

有些东西仍在运行,但我无法弄清楚它是什么。咕噜噜。

最佳答案

我认为问题在于您需要以某种方式 fork 控制台,所以也许是这个问题:https://github.com/sbt/sbt/issues/1918

以下想法似乎有效:您嵌入 REPL,例如 Ammonite,而不是 sbt 控制台。还在 sbt run不起作用,即使使用 fork in run := true .但是打包一个 fat jar 子并运行似乎确实有效:

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/foo/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。

关于scala - 如何让 ScalaFX 在 SBT 控制台中发挥​​出色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22306147/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com