Я пишу библиотеку изображений для студентов, изучающих программирование. (Идею и шаблоны я украл из библиотеки изображений для 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
, когда попытался вызвать эту функцию, хотя на самом деле она ничего не отображает, а просто создает новый Group
с двумя предыдущими Node
, наложенными друг на друга. соответственно. К сожалению, я не знаю, как создать новый поток и убедиться, что все, что связано с изображением, проходит через него.
Я уже установил fork := true
в build.sbt
, но, похоже, это не имеет значения для консоли.
== Обновление ==
Я нашел initialCommands
и cleanupCommands
в документации по 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.
Что-то все еще работает, но я не могу понять, что именно. Гррр.
scalafx.Platform.exit()
вместоSystem.exit(0)
? Первый способ является предпочтительным для завершения работы приложения ScalaFX. - person Mike Allen   schedule 11.03.2014scalafx.application.Platform.exit()
! Извините за путаницу... - person Mike Allen   schedule 11.03.2014:q
в консоли. - person Todd O'Bryan   schedule 11.03.2014System.exit(0)
в коде ScalaFX-Tutorials StandAloneFXDialog, и он просто блокирует консоль sbt. Согласно версии этой функции для JavaFX (которую ScalaFX вызывает под капотом), Примечание: если приложение встроено в браузер, этот метод может не иметь никакого эффекта. Это может быть проблемой. Я посмотрю на это еще... - person Mike Allen   schedule 11.03.2014Platform.exit()
, а в реализации функцииFXUtils.runAndWait(...)
в пакетеstand_alone_dialog
. По сути, он завершает исполняемый поток при очень ограниченном наборе условий, поэтомуPlatform.exit()
не имеет никакого эффекта. Я собираюсь взглянуть на улучшение этого. Я размещу исправленный код на GitHub... - person Mike Allen   schedule 11.03.2014Platform.exit()
ничего не делает. Если вы посмотрите на документацию для класса JavaFX JFXPanel - для встраивания JavaFX/ScalaFX в приложения Swing - есть аккуратный рабочий пример для подражания. Я думаю, поскольку это приложение Swing, вы завершаете приложение, вызывая методdispose()
основного фрейма. Надеюсь это поможет... - person Mike Allen   schedule 12.03.2014Platform.exit()
, а затемSystem.exit(0)
и посмотреть, поможет ли это. Кстати, я с радостью превращу комментарии в ответ, когда выясню, как вам следует завершить работу вашего приложения, но спасибо! Это не должно быть это сложно... :-( - person Mike Allen   schedule 12.03.2014display()
моего классаImage
? Я предполагаю, что мне придется запустить его в новом потоке или процессе (потому что я попытался просто запустить его, не делая этого, и получил ошибку). - person Todd O'Bryan   schedule 12.03.2014exit
я вижу ошибку сейчас, хотя я вижу ее каждый раз, когда яexit
запускаю консоль sbt, даже если не запускаю TrainEngine. - person Oliver Jan Krylow   schedule 22.03.2014