java - 切换浏览器选项卡时隐藏小程序的 JDialog

标签 java javascript swing jdialog japplet

我的问题似乎与How to hide JDialog from JApplet when user switch browser tab?密切相关。但它没有提供可行的解决方案。

我开发了一个使用 JWS/JNLP 部署的小程序。首先显示“新游戏”对话框。

private class NewGameDialog extends CustomDialog implements ActionListener {
    ...
    public NewGameDialog () {
       super(topContainer, "NEW GAME", modalityType);

       System.out.println(topContainer + " " + modalityType);
       //prints JApplet and DOCUMENT_MODAL
    ...

CustomDialog 只是扩展 JDialog:

public class CustomDialog extends JDialog implements WindowListener {

    public CustomDialog(Container cont, String title, ModalityType modalityType) {
        super(windowForComponent(cont), title, modalityType);
    }

    public static Window windowForComponent(Component c) {
        if (c instanceof Window) return (Window) c;
        return SwingUtilities.windowForComponent(c);
    }

    ...

这是从 GUI 类调用 JDialog 的方式:

public void requestNewGame () {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            NewGameDialog dialog = new NewGameDialog();
            dialog.setVisible(true);
        }
    });
}

enter image description here

我使用了 How to Use Modality in Dialogs 中描述的不同类型的模态。目标是当用户切换到浏览器中的另一个选项卡时隐藏 JDialog。但似乎没有一个选项不起作用。该对话框保持 float 在所有选项卡上方。

请告诉我如何在用户移动到另一个选项卡时隐藏对话框并在用户返回到我的小程序选项卡后再次显示?

最佳答案

这是基于以下假设:当选项卡更改时,父组件会更改屏幕上的位置。例如

JDialog.getParent().getLocationOnScreen()

经过测试并发现可用于:

  • 火狐19.0
  • Chrome 版本 25.0.1364.97 m

失败:

  • Internet Explorer 8.0.7601.17514

使用 MODELESS 之外的其他 Dialog.ModalityType 值会拒绝访问浏览器选项卡或导致安全异常。

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

public class DialogApplet extends JApplet {

    @Override
    public void init() {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                initGUI();
            }
        };
        SwingUtilities.invokeLater(r);
    }

    public void initGUI() {
        JButton b = new JButton("Show Dialog");
        ActionListener listener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                showDialog();
            }
        };
        b.addActionListener(listener);
        add(b);
    }

    private JDialog d;
    JTextArea output;
    int currentX = -1;
    Timer timer;

    public void showDialog() {
        if (d==null) {
            output = new JTextArea(5,20);
            Window w = SwingUtilities.windowForComponent(this);
            d = new JDialog(w, "Dialog", Dialog.ModalityType.MODELESS);
            //Dialog.ModalityType.TOOLKIT_MODAL);  //security
            //Dialog.ModalityType.DOCUMENT_MODAL);
            //Dialog.ModalityType.APPLICATION_MODAL);
            d.add(output, BorderLayout.CENTER);
            ActionListener al = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent ae) {
                    StringBuilder sb = new StringBuilder();


                    sb.append("parent location: \t" +
                        d.getParent().getLocation() + "\n");
                    sb.append("parent location - screen: \t" +
                        d.getParent().getLocationOnScreen() + "\n");

                    System.out.print(sb.toString());

                    output.setText(sb.toString());
                    if (currentX>-1 && 
                        currentX!=d.getParent().getLocationOnScreen().getX() 
                        ) {
                        System.out.println( "Goodbye world!" );
                        d.setVisible(false);
                        timer.stop();
                    }
                }
            };
            timer = new Timer(1000, al);
            d.pack();
            d.setLocationRelativeTo(d.getParent());
        }
        currentX = (int)d.getParent().getLocationOnScreen().getX();
        timer.start();
        d.setVisible(true);
    }
}

Java 脚本

也许应该向 JS 寻求帮助。技巧似乎在于检测 HTML 窗口焦点/模糊事件。例如。详情请参阅以下问题的答案:

显然,当 JS 检测到选项卡更改时,我们会让它调用小程序中的方法,例如 tabVisible()tabHidden() 来执行适当的操作对话框。

关于java - 切换浏览器选项卡时隐藏小程序的 JDialog,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15183146/

相关文章:

java - 上传到 Playstore 时缺少 Android 图标

javascript - Kendo UI 网格读取操作参数不起作用

java - JTable.clearSelection() 与 Jtable.getSelectionModel.clearSelection() - 何时使用什么?

javascript - MongoDB 文档 : Find number of Repetitions and Sort In Ascending Order

java - java中自动调整组件大小

java - 运行 JAR 文件时右键菜单损坏

java - 使用属性文件中的位置读取文件

java - 无法通过 Netty 从服务器向客户端发送消息

java - 两个完全不同的 JAXB 带注释的类,相同的 @XmlElement 名称。可能的?

javascript - 如何获取用户提供的图片的链接?