Plaform.exit() 崩溃 Java

Plaform.exit() crashes Java

这是一个简单的 JavaFX 程序。单击按钮后,它会正常编译和运行。

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;

public class Window extends Application
{
    @Override
    public void start(Stage primary)
    {
        primary.setTitle("Window");
        Button b = new Button("Clickez-vous moi!");
        VBox vb = new VBox();
        vb.getChildren().add(b);
        primary.setScene(new Scene(vb, 400,400));
        b.setOnAction( e -> Platform.exit());
        primary.show();
    }
}

}

这是我收到的错误消息。

Java has been detached already, but someone is still trying to use it at -[GlassViewDelegate dealloc]:/Users/jenkins/workspace/OpenJFX-mac/modules/javafx.graphics/src/main/native-glass/mac/GlassViewDelegate.m:198
0   libglass.dylib                      0x000000012a1dbf92 -[GlassViewDelegate dealloc] + 290
1   libglass.dylib                      0x000000012a1e1c9c -[GlassView3D dealloc] + 252
2   libobjc.A.dylib                     0x00007fff645894ea _ZN19AutoreleasePoolPage12releaseUntilEPP11objc_object + 134
3   libobjc.A.dylib                     0x00007fff6456f440 objc_autoreleasePoolPop + 175
4   CoreFoundation                      0x00007fff2e45f66e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
5   CoreFoundation                      0x00007fff2e45f594 __CFRunLoopDoObservers + 457
6   CoreFoundation                      0x00007fff2e40272b __CFRunLoopRun + 1219
7   CoreFoundation                      0x00007fff2e401fe3 CFRunLoopRunSpecific + 499
8   libjli.dylib                        0x000000010735b619 CreateExecutionEnvironment + 399
9   libjli.dylib                        0x000000010735775e JLI_Launch + 1354
10  java                                0x000000010734dca5 main + 375
11  libdyld.dylib                       0x00007fff658dc2e5 start + 1
MAC:Wed Dec 04:13:10:426> 

我是运行最新版本的MACOSX Catalina。

使用 System.exit() 而不是 Platform.exit()

b.setOnAction(e -> System.exit(0));

使用

stage.setOnCloseRequest((event) -> {
    Platform.exit();
});

并在 button.onAction() 方法中调用 .close() ,如下所示:

button.setOnAction((event) -> {
    stage.close();
});

两种事件类型的旧式匿名内部class实现如下:

button.setOnAction(new EventHandler<ActionEvent>() { // note event handler class (ACTION)
    @Override
    public void handle(ActionEvent event) {
        stage.close();
    }
});

stage.setOnCloseRequest(new EventHandler<WindowEvent>() { // note event handler class (WINDOW)
    @Override
    public void handle(WindowEvent event) {
        Platform.exit();
    }
});

奇怪的是,我可以在 windows 上 运行 你的代码,它会在点击按钮后发出构建成功的消息。所以我可能在胡说八道。

然而,在 OS 级别的事件处理之间存在差异,因此值得花时间按 CTRL C; CTRL V 一些代码。

编辑...

我还注意到您在应用程序中缺少 main 方法 class 这让我觉得有点奇怪。

我很确定我在过去的某个时候曾尝试生成 2 个不同的 Application 实例,但由于各种 javaFX 原因无法这样做,所以如果您成功实现了,则可能是您调用了platform.close() 例程来自错误的 primaryStage

寻找像

这样的东西
public static void main(String[] args) {
    Application.launch(args); // this directly references the class it's housed in since it expects to be in xxxx extends Application{} classes
}

public static void main(String[] args) {
    LauncherImpl.launchApplication(someClass.class, args); // this can be used to launch any class as long as it extends Application.class.
}

最后,确保你没有做一些愚蠢的事情,比如

Window x = new Window(); // pretty sure you can't actually do this but fk knows.... can't be bothered to check.
x.start();

从您代码中的某处调用。

申请=/=申请Windows.

如果你想创建一个多window应用程序,你需要做的就是:

public class ProperMultiWindowApp extends Application {

public static void main(String[] args) {
    Application.launch(args);
}

@Override
public void start(Stage primary) {
    primary.setTitle("Window");
    Button b = new Button("Clickez-vous moi!");
    VBox vb = new VBox();
    vb.getChildren().add(b);
    primary.setScene(new Scene(vb, 400, 400));
    
    b.setOnAction(e -> primary.close());

    Stage secondary = new Stage();
    secondary.setScene(new Scene(new HBox(new Label("here be content zeh 2nd"))));

    Stage tertiary = new Stage();
    tertiary.setScene(new Scene(new HBox(new Label("here be content le 3rd"))));

    primary.show();
    secondary.show();
    tertiary.show();

    primary.setOnCloseRequest(e -> Platform.exit());

}

@Override
public void stop() throws Exception {
    System.out.println("proof that this is stopping"); // this should be called during Platform.exit();
    super.stop();
}

}

请注意,对于使用 JavaFX 的标准 JavaSE,启动应用程序的 class 是 javaFX JVM 认为主要的 class。

如果这一切都失败了,那要么是一个错误,要么与您的 mac 有关。...因为它是 mac.

如果是这种情况,我衷心建议您反复bash那件事碰石头,以确保应用程序有效关闭。