我有一个简单的控制台应用程序,有时需要执行图形操作,对于那些我使用JavaFx框架(有一些功能,我需要像css样式的文本)我只是生成一些形状和文本到一个隐藏的场景,然后保存在文件中仅此而已,
我知道要使用JavaFx,我必须将图形操作传递给JavaFx线程,但是当一切都完成后,我必须关闭应用程序(几个小时后),这个JavaFx线程仍然保持打开...我真的不想强行退出System.exit(),因为如果有什么被阻止,我可能想知道/等待(同样,我不想以JavaFx应用程序的形式执行所有内容(因为JavaFx组件不到我主要应用程序的1%)
这段代码非常简单,我在谷歌上搜索时发现,它只适合我使用
Platform.exit();
这似乎不起作用,我也尝试过使用平台参数,比如
Platform.setImplicitExit(false);
这是我的测试应用程序,你可以运行:
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.geometry.Pos;
import javafx.scene.layout.VBox;
public class SOTestFX {
public static void main(String[] args) {
SOTestFX t = new SOTestFX();
t.runFxThread();
}
public void runFxThread(){
//Application.launch(args);
final JFXPanel jfxPanel = new JFXPanel();
Platform.runLater(new Runnable() {
@Override
public void run() {
System.err.println("CREATING IMAGE");
simpleFXoperations();
System.err.println("NOW CALL EXIT");
System.err.println("JAVA FX THREAD SHOULD BE EXITED NOW");
Platform.exit();
}
});
try {
Thread.sleep(3000); // just wait a bit if something should happen, let it happen..
} catch (InterruptedException e) {
e.printStackTrace();
}
//jfxPanel.removeNotify(); // return -> java.lang.NullPointerException
//Platform.exit(); // -> does nothing
System.err.println("i will never die!");
}
public void simpleFXoperations(){
VBox vbox1 = new VBox();
vbox1.setAlignment(Pos.BOTTOM_CENTER);
vbox1.setStyle("-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: white");
System.err.println("simpleFXoperations() _DONE");
}
}
这是一条永不闭合的线
"附加监听器"-线程t@17java.lang.线程。状态:RUNNABLE
锁定自己的同步器:-无
"JavaFX应用程序线程"-线程t@13java.lang.线程。状态:运行在com.sun.glass.ui.gtk.GtkApplication。_runLoop(本地方法)在com.sun.glass.ui.gtk.GtkApplication 3美元1.run(GtkApplication.java:82)在java.lang.Thread.run(Thread.java:722)
锁定自己的同步器:-无
更新:我使用最新的Oracle JDK 7u17 64位LinuxFedora 16 64位。
这是一个棘手的情况,因为(据我所知)JavaFX线程的目的是透明地利用各种硬件管道。我建议您将JavaFX请求放在一个单独的、被引用的项目中;把其他的东西,包括你的主要方法,都放在另一个地方?这对我一直都有用。
基本上,业务逻辑和模型放在一个项目中,视图和控制(通常基于JavaFX)放在另一个项目中。这允许独立终止JavaFX线程。希望这适用于你正在尝试做的事情。
您的主函数不属于JavaFx Application对象,我认为您的程序永远不会进入应用程序线程循环。
看来你应该做:
public class SOTestFX extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
// Do stuff here to show your stage or whatever you want;
// This will be called on the JavaFX thread
}
}
我能够通过调用com.sun.javafx.application.PlatformImpl.tkExit()
紧接在Platform.exit()
之前来解决这个问题。我不太了解JavaFX源代码,但它似乎在工作;YMMV。
更新:在Java 8中执行此操作将产生警告,您可以使用@SuppressWarnings(“restriction”)
关闭警告。这不应该是个问题。
我通过挖掘源代码找到了答案JFXPanel
有一个小片段(来自JavaFX2.2.25)
finishListener = new PlatformImpl.FinishListener() {
public void idle(boolean paramAnonymousBoolean) {
if (!JFXPanel.firstPanelShown) {
return;
}
PlatformImpl.removeListener(JFXPanel.finishListener);
JFXPanel.access$102(null);
if (paramAnonymousBoolean)
Platform.exit();
}
public void exitCalled()
{
}
问题是,如果在应用程序中只使用了一点点JavaFX,那么idle(boolean)
方法永远不会做任何事情(因为firstPanelShowed==false
),这会阻止监听器被删除,从而阻止JavaFX工具包关闭。。。这意味着你必须手动关闭它。
代码非常简单,我搜索了一下,发现我只会用到 这似乎不起作用,我也尝试过使用平台参数,比如 下面是您可以运行的测试应用程序: 锁定得可拥有同步器:-无 更新:我正在Linux Fedora 16 64bit上使用最新的Oracle JDK 7u17 64bit。
我正在用场景构建器创建一个JavaFX应用程序。我在开头加了一段视频。所以我想播放视频之前,我的应用程序启动在全屏模式。问题是当它停止时,我只看到黑色尖叫,什么也没发生,我想这是因为视频是全屏的,它没有自动关闭。 我也有一个bug,在视频开始之前,我的主窗口的一些闪烁。我想这是因为视频放在控制器中,在我的应用程序启动后开始。 公共类主扩展应用程序{ 控制器类:
我们为Azure Portal中托管的Web应用程序安装了应用程序Insights。
我对Java FX应用程序线程有问题。下面是一个伪代码: 问题是睡眠发生在窗口中,该窗口显示在show Menu()中,show LoadingPic()根本没有显示,而在最后窗口中显示的是show Map()。 show LoadingPic中的场景有一个进度条,运行2秒,与Thread.sleep(2000)相同。 因此,似乎javafx应用程序线程块show LoadingPic()和sho
motioncfp.java:
我通过创建固定数量的线程来使用执行器服务来进行HTTP GET数据检索。 当Tomcat停止时,我们会出现以下错误: 严重:web应用程序[/viewer]似乎已启动名为[ThreadExecutor_51616156]的线程,但未能停止该线程。这很可能会造成内存泄漏。 这是真的吗?在没有这些服务错误的情况下,如何正确停止tomcat。