带有崩溃的TextField的Swing / JavaFx混合应用程序

时间:2018-07-17 11:07:53

标签: swing javafx

我遇到一个影响应用程序的问题,出于各种原因,必须使用包含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

在此先感谢任何人可以提供的帮助。

0 个答案:

没有答案
相关问题