简体   繁体   English

如何在所有窗口的顶部显示 JOptionPane

[英]how to show JOptionPane on the top of all windows

I have created a DialogUtil which shows numbers of JOptionPan in different situation.我创建了一个 DialogUtil,它显示了不同情况下 JOptionPan 的数量。 sometimes in my action class call to this method with null parameters as below.有时在我的操作类中使用空参数调用此方法,如下所示。

DialogUtil.showNotExist(null,xml.getName().concat(" is null or"));

In this case JOptionPane does not appears on the top of window.在这种情况下,JOptionPane 不会出现在窗口顶部。

How can I add something to JOptionPane to appears always on the top?如何向 JOptionPane 添加内容以始终显示在顶部?

public static void showNotExist(JPanel panel, String action) {
    JOptionPane.showMessageDialog(panel, new JLabel(action.concat(" doesn't exist."), 2));
}

You can set JOptionPane always on top by using this code:-您可以使用以下代码始终将 JOptionPane 设置在顶部:-

JFrame jf=new JFrame();
jf.setAlwaysOnTop(true);
int response = JOptionPane.showConfirmDialog(jf,"Message", "Title", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);

Have you tried something like this?你有没有尝试过这样的事情?

JOptionPane optionPane = new JOptionPane();
JDialog dialog = optionPane.createDialog("Title");
dialog.setAlwaysOnTop(alwaysOnTop);
dialog.setVisible(true);

There is no guarantee that the operating system will allow your dialog to be always on top, but it will often work.不能保证操作系统会允许您的对话框始终位于最前面,但它通常会起作用。

If you have an existing window or dialog and you want to bring it to the top, but don't want to permanently set alwaysOnTop, this should work while leaving the old value of alwaysOnTop alone:如果您有一个现有的窗口或对话框,并且想要将其置于顶部,但不想永久设置 alwaysOnTop,则这应该可以工作,同时保留 alwaysOnTop 的旧值:

boolean supported = window.isAlwaysOnTopSupported();
boolean old_alwaysOnTop = window.isAlwaysOnTop();
if (supported) {
  window.setAlwaysOnTop(true);
}
window.toFront();
window.requestFocus();
if (supported) {
  window.setAlwaysOnTop(old_alwaysOnTop);
}

Run that code only on the SwingThread.仅在 SwingThread 上运行该代码。

there are two possible issues有两个可能的问题

  • JOptionPane is called out of EDT, then only toolbar (caption that came from Native OS is visible on the screen, RootPane isn't visible) is visible on the screen JOptionPane从EDT调用出来,然后只有工具栏(来自Native OS的标题在屏幕上可见,RootPane不可见)在屏幕上可见

  • there you can to test JOptionPanes features, where JOptionPane.showInternalMessageDialog() makes troubles in all cases that there is another JDialog with setModal(true), real reason I dont know, same should be with ModalityTypes在那里您可以测试 JOptionPanes 功能,其中 JOptionPane.showInternalMessageDialog() 在所有情况下都会遇到麻烦,因为还有另一个带有 setModal(true) 的 JDialog,我不知道真正的原因,ModalityTypes 应该也是如此

  • not possible to showing two JOptionPanes on the screen in the same time无法同时在屏幕上显示两个 JOptionPanes

code代码

import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JRootPane;
import javax.swing.Timer;
//http://stackoverflow.com/questions/8670297/make-java-swing-modal-dialog-behave-like-mac-osx-dialogs
public class ModalDialogDemoFrame extends JFrame {

    private static final long serialVersionUID = 1L;
    private ModalDialogDemoFrame modalDialogDemo;

    public ModalDialogDemoFrame() {
        modalDialogDemo = this;
        setBounds(100, 100, 400, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JButton buttonDialog = new JButton("Open Dialog");
        buttonDialog.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {
                // Create a Modal Dialog with this Frame as Parent.
                ModalDialog modalDialog = new ModalDialog(modalDialogDemo, true);
                modalDialog.setVisible(true);
            }
        });
        getContentPane().add(buttonDialog, BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            public void run() {
                try {
                    ModalDialogDemoFrame window = new ModalDialogDemoFrame();
                    window.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
//http://stackoverflow.com/questions/4577424/distinguish-between-a-single-click-and-a-double-click-in-java/4577475#4577475
class ClickListener extends MouseAdapter implements ActionListener {

    private final static int clickInterval = (Integer) Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");
    private MouseEvent lastEvent;
    private Timer timer;

    public ClickListener() {
        this(clickInterval);
    }

    public ClickListener(int delay) {
        timer = new Timer(delay, this);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() > 2) {
            return;
        }
        lastEvent = e;
        if (timer.isRunning()) {
            timer.stop();
            doubleClick(lastEvent);
        } else {
            timer.restart();
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        timer.stop();
        singleClick(lastEvent);
    }

    public void singleClick(MouseEvent e) {
    }

    public void doubleClick(MouseEvent e) {
    }
}

class ModalDialog extends JDialog {

    private static final long serialVersionUID = 1L;

    public ModalDialog(JFrame parent, boolean modal) {
        Dimension dimensionParentFrame = parent.getSize();
        setSize(new Dimension((parent == null) ? 300 : dimensionParentFrame.width / 2, 75));
        Dimension dimensionDialog = getSize();
        int x = parent.getX() + ((dimensionParentFrame.width - dimensionDialog.width) / 2);
        setLocation(x, parent.getY() + parent.getInsets().top);
        //setUndecorated(true);
        setModal(modal);
        //setUndecorated(true);
        //getRootPane().setWindowDecorationStyle(JRootPane.ERROR_DIALOG);
        setModalityType(ModalityType.APPLICATION_MODAL);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        final JButton buttonClose = new JButton("Close");
        buttonClose.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
//ok
                /*JOptionPane.showMessageDialog(buttonClose,
                "Eggs are not supposed to be green.",
                "Inane warning",
                JOptionPane.WARNING_MESSAGE);*/
//uncomment for un_handled GUI, JOptionPane is behing JFrame I think....
                /*JOptionPane.showInternalMessageDialog(buttonClose,
                "Eggs are not supposed to be green.",
                "Inane warning",
                JOptionPane.WARNING_MESSAGE);*/
//ok
                /*JOptionPane.showConfirmDialog(buttonClose,
                "Eggs are not supposed to be green.",
                "Inane warning",
                JOptionPane.WARNING_MESSAGE);*/
//ok                
                /*JOptionPane.showMessageDialog(null,
                "Eggs are not supposed to be green.",
                "Inane warning",
                JOptionPane.WARNING_MESSAGE);*/
//uncomment for un_handled GUI
//Exception occurred during event dispatching:
//java.lang.RuntimeException: JOptionPane: parentComponent does not have a valid parent                
                /*JOptionPane.showInternalMessageDialog(null,
                "Eggs are not supposed to be green.",
                "Inane warning",
                JOptionPane.WARNING_MESSAGE);*/
//ok                
                JOptionPane.showConfirmDialog(null,
                        "Eggs are not supposed to be green.",
                        "Inane warning",
                        JOptionPane.WARNING_MESSAGE);
                dispose();
            }
        });
        add(buttonClose, BorderLayout.CENTER); // comment for listening
        addMouseListener(new ClickListener() {

            @Override
            public void singleClick(MouseEvent e) {
                System.out.println("single");
            }

            @Override
            public void doubleClick(MouseEvent e) {
                System.out.println("double");
            }
        });
    }
}

I don't know what WebOptionPane or WebPanel are, but if they're based on JOptionPane , then the issue is that you're passing null for that first argument to the showXXX() method.我不知道WebOptionPaneWebPanel是什么,但如果它们基于JOptionPane ,那么问题是您将null作为第一个参数传递给showXXX()方法。 If you want the JOptionPane to be modal -- which forces it to be in front of a specified window -- then you need to specify a window (ie, a JFrame -- for that first argument.如果您希望JOptionPane是模态的——这会强制它位于指定窗口的前面——那么您需要为第一个参数指定一个窗口(即JFrame

public static void showNotExist(JPanel panel, String action) {
    JOptionPane.showMessageDialog(rootPane, new JLabel(action.concat(" doesn't exist."), 2));
}

Try giving the rootpane as the 1st value in the showMessageDialog section尝试将 rootpane 作为 showMessageDialog 部分中的第一个值

If your class has extended JFrame, then just simply set the class property setAlwaysOnTop(true);如果您的类扩展了 JFrame,那么只需简单地设置类属性 setAlwaysOnTop(true); in anywhere in constructors before JOptionPane.showMessageDialog(null,"OKay");在 JOptionPane.showMessageDialog(null,"OKay") 之前的构造函数中的任何位置;

I use it for copying file and check, don't even need a JFrame but JOptionPane.我用它来复制文件和检查,甚至不需要 JFrame 而是 JOptionPane。

PS If you don't want the main JFrame always shows on the top, then you need to create dummy JFrame or reset the property setAlwaysOnTop(false); PS 如果你不想主 JFrame 总是显示在顶部,那么你需要创建虚拟 JFrame 或重置属性 setAlwaysOnTop(false); after the JOptionPane.在 JOptionPane 之后。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM