如果Mac OS上全屏显示,则JavaFX Alert#showAndWait会永久挂起

问题描述

(靠近底部的tl标记

上下文

我在典型的全屏(POS样式)JFX应用程序中使用JavaFX Alert来显示挥杆内容窗格,以在阻止窗口中向用户提供自定义的触摸优化输入。

我希望警报为全屏显示,以符合pos样式。在Mac上,全屏窗口在其自己的“空间”中打开;类似于新的桌面空间,但仅适用于一个应用程序。

我正在使用运行Mac OS 10.12的hackintosh。此问题似乎是极端 Macintosh全屏空白。

值得注意的是,复制需要要求系统偏好设置>停靠>偏爱选项卡... =手动。这将导致Mac OS将警报作为单独的弹出窗口而不是同一Application Stage窗口中的选项卡打开。 (或者,您可以成为客人,也可以手动拖动该选项卡并全屏显示。)之所以这样做,是因为警报对在选项卡中显示挥杆内容表现不佳。

主场景窗口的全屏状态不影响行为,仅影响警报状态。

SDK:JDK 13.0.4,JavaFX 11.0.2

showAndWait()

正在使用Alert.showAndWait()显示警报,

显示对话框并等待用户响应(换句话说, 弹出一个阻止对话框,用户输入返回值)。
...
方法必须在JavaFX Application线程上调用
...
必须从传递给的Runnable的run方法调用... Platform.runLater。

如下所示,满足了最后一个要求。我还检查了一下以确保它在JFX Application线程上被调用

预期

showAndWait();挂起,直到用户在“警报”窗口上单击“确定”。之后,关闭窗口,自定义对话框返回从用户那里收集的值。焦点返回到“ JFX Application Stage”窗口。

实际

实际实现:
如果是窗口,则按预期方式返回并关闭,并且焦点返回到包含“应用程序场景”窗口的空间。如果全屏显示,Mac的全屏显示空间立即消失,没有动画,返回桌面,似乎表明警报窗口突然关闭了,好像已经关闭了一样,但是内容仍然比桌面上的所有其他内容呈现空间。应用程序线程挂起。 UI挂起。鼠标沙滩球。 Debugger shows this chungus stack of the parked Application thread.

简化的测试版本:
如果出现窗口,则按预期关闭。如果是全屏,则返回到窗口,停止渲染,但保持打开状态。应用程序线程不会停驻,但是应用程序仍然无响应(“无响应”,沙滩撞球,停放,只是对任何交互都不了解。)

漫步

I also encountered this at one point,我无法复制,但它仅进一步暗示这与Glass Windows有关,导致我最好的猜测是这是量子工具套件的问题,或者Mac Glass Windows在他们试图关闭时是否有空格(并重新渲染?)。

(最佳TL; DR说明)

以某种方式,由警报关闭导致的全屏空间之间的切换会中断警报的用户确认事件,该事件将释放线程,从而导致应用程序线程永远停留在showAndWait()中。我认为,确认后整个程序挂起的原因与警报UI不再可用有关。 JavaFX现在正在尝试将控制权返回给已挂起的应用程序线程。

可以理解,警报窗口可能没有经过这种方式的测试;这是可以理解的。一个全屏弹出式输入窗口,其中包含Mac的全屏空间。

我可能只需要考虑另一种选择,或者满足于没有全屏显示

强制性代码转储

对话框类:

package swing;

import javafx.application.Platform;
import javafx.embed.swing.SwingNode;
import javafx.scene.control.Alert;

import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

/**
 * Absofuckinlutely not done.
 *
 * Todo P1: DIALOG DOES NOT RETURN WHEN USER CLICKS OK WHILST IN FULLSCREEN!
 * Todo There's literally 0 javadoc. oh well!
 * @author Gordie
 * @version -
 * @since -
 */
public class numericInput extends Alert {

    private static int value;
    //#region swing
    private JTextField outputField;
    private JButton btn1;
    private JButton btn2;
    private JButton btn3;
    private JButton btn4;
    private JButton btn5;
    private JButton btn6;
    private JButton btn7;
    private JButton btn8;
    private JButton btn9;
    private JButton btnCancle;
    private JButton btn0;
    private JButton btnEnter;
    private JPanel panel;
    //#endregion swing

    public numericInput(String text) {
        super(AlertType.@R_704_4045@ION,text);
        addListener(btn0,0);
        addListener(btn1,1);
        addListener(btn2,2);
        addListener(btn3,3);
        addListener(btn4,4);
        addListener(btn5,5);
        addListener(btn6,6);
        addListener(btn7,7);
        addListener(btn8,8);
        addListener(btn9,9);

        btnCancle.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                panel.setVisible(false);
                value = -1;
            }
        });

        btnEnter.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                panel.setVisible(false);
            }
        });


        //#region REDACTED
        /*
            displaying a Swing jdialog for a JavaFX  application was too much of a
            pain in the arse that wasn't really working out for us.
            Instead of re-creating the entire dialog in JFX,i'm just displaying the swing panel in a JFX stage as a node using jfx.embed
         */

        //panel.setVisible(true);
        //getContentPane().add(panel);
        //pack();
        //setTitle(title);
        //setVisible(true);
        //#endregion

        // Show
        setResizable(true);
        SwingNode sNode = new SwingNode();                                                                              // Create JFX compatible node to contain Swing content,sNode.setContent(panel);                                                                                        // and add dialog pane to it.
        getDialogPane().setContent(sNode);                                                                              // Add the content node to the pane of the JFX dialog window this class extends.
        getDialogPane().autosize();
        Platform.runLater(() -> {
            showAndWait();
            close();
        });
    }

    //#region listener
    private void append(int s){
        outputField.setText(outputField.getText() + s);
    }

    private void addListener(JButton button,int number){
        button.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                append(number);
            }
        });
    }
    //#endregion

    public static numericInput New(String text){
        return new numericInput(text);
    }

    public int value(){
        return value;
    }
}

剥离测试应用程序:
(不太像真实的实现那样复制)

package swing;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class test extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Scene scene = new Scene(new Pane(),100,100);
        primaryStage.setScene(scene);
        primaryStage.setFullScreen(true);
        primaryStage.show();
        int i = numericInput.New("test").value();
    }
}

提示形式:

<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="swing.numericInput">
  <grid id="27dc6" binding="panel" layout-manager="GridLayoutManager" row-count="5" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
    <margin top="0" left="0" bottom="0" right="0"/>
    <constraints>
      <xy x="20" y="20" width="500" height="400"/>
    </constraints>
    <properties/>
    <border type="none"/>
    <children>
      <component id="e6243" class="javax.swing.JTextField" binding="outputField">
        <constraints>
          <grid row="0" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
            <preferred-size width="150" height="-1"/>
          </grid>
        </constraints>
        <properties>
          <editable value="false"/>
        </properties>
      </component>
      <component id="6d99d" class="javax.swing.JButton" binding="btn1">
        <constraints>
          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
        </constraints>
        <properties>
          <text value="1"/>
        </properties>
      </component>
      <component id="68db2" class="javax.swing.JButton" binding="btn4">
        <constraints>
          <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
        </constraints>
        <properties>
          <text value="4"/>
        </properties>
      </component>
      <component id="7f847" class="javax.swing.JButton" binding="btn7">
        <constraints>
          <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
        </constraints>
        <properties>
          <text value="7"/>
        </properties>
      </component>
      <component id="bbd8" class="javax.swing.JButton" binding="btn2">
        <constraints>
          <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
        </constraints>
        <properties>
          <text value="2"/>
        </properties>
      </component>
      <component id="4ab8f" class="javax.swing.JButton" binding="btn5">
        <constraints>
          <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
        </constraints>
        <properties>
          <text value="5"/>
        </properties>
      </component>
      <component id="ce17e" class="javax.swing.JButton" binding="btn8">
        <constraints>
          <grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
        </constraints>
        <properties>
          <text value="8"/>
        </properties>
      </component>
      <component id="890ed" class="javax.swing.JButton" binding="btn3">
        <constraints>
          <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
        </constraints>
        <properties>
          <text value="3"/>
        </properties>
      </component>
      <component id="f1bdb" class="javax.swing.JButton" binding="btn6">
        <constraints>
          <grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
        </constraints>
        <properties>
          <text value="6"/>
        </properties>
      </component>
      <component id="beed0" class="javax.swing.JButton" binding="btn9">
        <constraints>
          <grid row="3" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
        </constraints>
        <properties>
          <text value="9"/>
        </properties>
      </component>
      <component id="60bed" class="javax.swing.JButton" binding="btn0">
        <constraints>
          <grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
        </constraints>
        <properties>
          <text value="0"/>
        </properties>
      </component>
      <component id="2d5d5" class="javax.swing.JButton" binding="btnCancle">
        <constraints>
          <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
        </constraints>
        <properties>
          <text value="Delete"/>
        </properties>
      </component>
      <component id="960c7" class="javax.swing.JButton" binding="btnEnter">
        <constraints>
          <grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
        </constraints>
        <properties>
          <text value="Enter"/>
        </properties>
      </component>
    </children>
  </grid>
</form>

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)