我有一个表现非常不稳定的JavaFx程序。
如果我在文本字段上按Enter键,JVM会崩溃。这是从this stackoverflow问题获得的简单UI程序。这个无辜的计划出了什么问题?
我正在运行Lubuntu 12.10
和JDK 1.7.0_09-b05
。
import com.sun.glass.events.KeyEvent;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.event.*;
import javafx.geometry.Pos;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;
public class MissingDataDemo extends Application {
private static final String[] SAMPLE_TEXT = "Lorem ipsum MISSING dolor sit amet MISSING consectetur adipisicing elit sed do eiusmod tempor incididunt MISSING ut labore et dolore magna aliqua"
.split(" ");
@Override
public void start(Stage primaryStage) {
VBox textContainer = new VBox(10);
textContainer
.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;");
primaryStage.setScene(new Scene(textContainer, 300, 600));
primaryStage.show();
TextLoader textLoader = new TextLoader(SAMPLE_TEXT, textContainer);
textLoader.loadText();
}
public static void main(String[] args) {
launch(args);
}
}
class TextLoader {
private final String[] lines;
private final Pane container;
TextLoader(final String[] lines, final Pane container) {
this.lines = lines;
this.container = container;
}
public void loadText() {
for (String nextText : lines) {
final Label nextLabel = new Label();
if ("MISSING".equals(nextText)) {
nextLabel.setStyle("-fx-background-color: palegreen;");
MissingTextPrompt prompt = new MissingTextPrompt(container
.getScene().getWindow());
nextText = prompt.getResult();
}
nextLabel.setText(nextText);
container.getChildren().add(nextLabel);
}
}
class MissingTextPrompt {
private final String result;
MissingTextPrompt(Window owner) {
final Stage dialog = new Stage();
dialog.setTitle("Enter Missing Text");
dialog.initOwner(owner);
dialog.initStyle(StageStyle.UTILITY);
dialog.initModality(Modality.WINDOW_MODAL);
dialog.setX(owner.getX() + owner.getWidth());
dialog.setY(owner.getY());
final TextField textField = new TextField();
final Button submitButton = new Button("Submit");
submitButton.setDefaultButton(true);
submitButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
dialog.close();
}
});
textField.setMinHeight(TextField.USE_PREF_SIZE);
final VBox layout = new VBox(10);
layout.setAlignment(Pos.CENTER_RIGHT);
layout.setStyle("-fx-background-color: azure; -fx-padding: 10;");
layout.getChildren().setAll(textField, submitButton);
dialog.setScene(new Scene(layout));
dialog.showAndWait();
result = textField.getText();
}
private String getResult() {
return result;
}
}
}
转储的某些部分 -
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0xb6cfa39f, pid=14093, tid=1803479872
#
# JRE version: 7.0_09-b05
# Java VM: Java HotSpot(TM) Server VM (23.5-b02 mixed mode linux-x86 )
# Problematic frame:
# V [libjvm.so+0x42539f] jni_invoke_nonstatic(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*)+0x2f
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
#
完整转储可用here。
修改1:
使用最新版本的Oracle Java 1.7.0_25-b15
运行它也会崩溃。
编辑2:
使用OpenJDK 7u9-2.3.4-0ubuntu1.12.10.1
运行它不会崩溃,但会出现以下错误 -
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:403)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:47)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:115)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.NullPointerException
at com.sun.glass.ui.gtk.GtkApplication.enterNestedEventLoopImpl(Native Method)
at com.sun.glass.ui.gtk.GtkApplication._enterNestedEventLoop(GtkApplication.java:137)
at com.sun.glass.ui.Application.enterNestedEventLoop(Application.java:383)
at com.sun.glass.ui.EventLoop.enter(EventLoop.java:83)
at com.sun.javafx.tk.quantum.QuantumToolkit.enterNestedEventLoop(QuantumToolkit.java:520)
at javafx.stage.Stage.showAndWait(Stage.java:397)
at com.mango.proengin.ui.user.TextLoader$MissingTextPrompt.<init>(MissingDataDemo.java:96)
at com.mango.proengin.ui.user.TextLoader.loadText(MissingDataDemo.java:52)
at com.mango.proengin.ui.user.MissingDataDemo.start(MissingDataDemo.java:28)
at com.sun.javafx.application.LauncherImpl$5.run(LauncherImpl.java:319)
at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:206)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:173)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication$3$1.run(GtkApplication.java:82)
... 1 more
答案 0 :(得分:2)
在本机UI代码中看起来像是一个潜在的线程错误 - 在Windows 7 x64上运行最新的JDK,它运行时没有问题(目前无权访问Linux机器进行测试。)
在UI代码被调用平台线程之前,我已经看到了类似的奇怪行为,尽管我可以看出这里没有发生。话虽如此,虽然你不应该(因为它无论如何都在平台线程上)我有时会发现在Platform.runLater()
中包装有问题的代码可以解决问题 - 或者至少工作围绕它:
submitButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
Platform.runLater(new Runnable() {
@Override
public void run() {
dialog.close();
}
});
}
});
这可能只是以GTK碰巧喜欢的方式改变线程,虽然它并不理想。无论哪种方式,都值得尽可能地简化示例(尽管你仍然可靠地得到错误)并报告错误。