我遇到一个影响应用程序的问题,出于各种原因,必须使用包含JavaFx面板的Swing JFrame编写该应用程序。我可以根据https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/swing-fx-interoperability.htm中的代码将代码简化为一个简单的示例。
我的示例打开了一个包含按钮的应用程序,该按钮可以打开一个具有文本字段的简单对话框。如果我在对话框的文本字段中键入内容,一切都很好,但是如果我开始键入,然后单击对话框外部的任何内容(例如文本编辑器),当我返回到文本字段并键入更多内容时,如果行为异常并开始引发异常。这似乎是EDT或Application线程上未发生任何事情的地方,我很确定这是在对话框的show()方法下的,尽管我看不出有什么问题。据我所知,我遵循了正确的模式。
我在Windows 10上使用JDK 1.8.0_171和IntelliJ Idea。
代码如下:
应用程序:
public class HybridApplication
{
private static JFrame frame;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> initAndShowGUI());
}
private static void initAndShowGUI() {
frame = new JFrame("Swing and JavaFX");
final JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel);
frame.setSize(300, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Platform.runLater(() -> initFX(fxPanel));
}
private static void initFX(JFXPanel fxPanel) {
Scene scene = createScene();
fxPanel.setScene(scene);
}
private static Scene createScene() {
HBox hBox = new HBox();
hBox.setSpacing(20);
Scene scene = new Scene(hBox);
TextField text = new TextField();
text.setPrefWidth(200);
text.setPrefHeight(40);
HybridDialog dialog = new HybridDialog();
Button button = new Button("Test");
button.setOnAction(event -> dialog.show());
hBox.getChildren().add(button);
hBox.getChildren().add(text);
return scene;
}
}
对话框:
public class HybridDialog
{
private JFrame frame;
public HybridDialog()
{
SwingUtilities.invokeLater(() -> initAndShowGUI());
}
private void initAndShowGUI()
{
frame = new JFrame("Dialog");
final JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel);
frame.setSize(300, 200);
frame.setVisible(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Platform.runLater(() -> initFX(fxPanel));
}
private void initFX(JFXPanel fxPanel) {
Scene scene = createScene();
fxPanel.setScene(scene);
}
private static Scene createScene() {
TextField text = new TextField();
text.setPrefWidth(200);
text.setPrefHeight(40);
HBox hBox = new HBox();
hBox.getChildren().add(text);
Scene scene = new Scene(hBox);
return scene;
}
public void show() {
SwingUtilities.invokeLater(() -> frame.setVisible(true));
}
}
奇怪的行为是,当我继续键入内容时,例如说要编辑键入的内容,文本字段开始在光标之后添加文本块,并且我很快会收到以下异常:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at com.sun.javafx.text.PrismTextLayout.layout(PrismTextLayout.java:1273)
at com.sun.javafx.text.PrismTextLayout.ensureLayout(PrismTextLayout.java:223)
at com.sun.javafx.text.PrismTextLayout.getBounds(PrismTextLayout.java:246)
at javafx.scene.text.Text.getLogicalBounds(Text.java:358)
at javafx.scene.text.Text.getYRendering(Text.java:1069)
at javafx.scene.text.Text.access$4400(Text.java:95)
at javafx.scene.text.Text$TextAttribute$11.computeValue(Text.java:1785)
at javafx.scene.text.Text$TextAttribute$11.computeValue(Text.java:1777)
at javafx.beans.binding.ObjectBinding.get(ObjectBinding.java:153)
at javafx.beans.binding.ObjectExpression.getValue(ObjectExpression.java:50)
at javafx.beans.property.ObjectPropertyBase.get(ObjectPropertyBase.java:132)
at com.sun.javafx.scene.control.skin.TextFieldSkin.lambda$new$198(TextFieldSkin.java:233)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:137)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:105)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.access$000(ObjectPropertyBase.java:51)
at javafx.beans.property.ObjectPropertyBase$Listener.invalidated(ObjectPropertyBase.java:233)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:137)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.binding.ObjectBinding.invalidate(ObjectBinding.java:172)
at javafx.scene.text.Text.impl_geomChanged(Text.java:769)
at javafx.scene.text.Text.needsTextLayout(Text.java:194)
at javafx.scene.text.Text.needsFullTextLayout(Text.java:189)
at javafx.scene.text.Text.access$200(Text.java:95)
at javafx.scene.text.Text$2.invalidated(Text.java:389)
at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:109)
at javafx.beans.property.StringPropertyBase.access$000(StringPropertyBase.java:49)
at javafx.beans.property.StringPropertyBase$Listener.invalidated(StringPropertyBase.java:230)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:137)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.binding.StringBinding.invalidate(StringBinding.java:171)
at com.sun.javafx.binding.BindingHelperObserver.invalidated(BindingHelperObserver.java:51)
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:349)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.scene.control.TextInputControl$TextProperty.fireValueChangedEvent(TextInputControl.java:1389)
at javafx.scene.control.TextInputControl$TextProperty.markInvalid(TextInputControl.java:1393)
at javafx.scene.control.TextInputControl$TextProperty.controlContentHasChanged(TextInputControl.java:1332)
at javafx.scene.control.TextInputControl$TextProperty.access$1600(TextInputControl.java:1300)
at javafx.scene.control.TextInputControl.lambda$new$162(TextInputControl.java:139)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:137)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.scene.control.TextField$TextFieldContent.insert(TextField.java:87)
at javafx.scene.control.TextInputControl.replaceText(TextInputControl.java:1204)
at javafx.scene.control.TextInputControl.updateContent(TextInputControl.java:556)
at javafx.scene.control.TextInputControl.replaceText(TextInputControl.java:548)
at com.sun.javafx.scene.control.skin.TextFieldSkin.replaceText(TextFieldSkin.java:576)
at com.sun.javafx.scene.control.behavior.TextFieldBehavior.replaceText(TextFieldBehavior.java:202)
at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.defaultKeyTyped(TextInputControlBehavior.java:238)
at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.callAction(TextInputControlBehavior.java:139)
at com.sun.javafx.scene.control.behavior.BehaviorBase.callActionForEvent(BehaviorBase.java:218)
at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.callActionForEvent(TextInputControlBehavior.java:127)
at com.sun.javafx.scene.control.behavior.BehaviorBase.lambda$new$74(BehaviorBase.java:135)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$KeyHandler.process(Scene.java:3964)
at javafx.scene.Scene$KeyHandler.access$1800(Scene.java:3910)
at javafx.scene.Scene.impl_processKeyEvent(Scene.java:2040)
at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2501)
at com.sun.javafx.tk.quantum.EmbeddedScene.lambda$null$299(EmbeddedScene.java:310)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.EmbeddedScene.lambda$keyEvent$300(EmbeddedScene.java:296)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
如果我继续输入,则以下行会在IDE中显示,就像锁定在循环中一样:
线程“ JavaFX Application Thread”中的异常java.lang.ArrayIndexOutOfBoundsException
在此先感谢任何人可以提供的帮助。