JPopoupMenu由窗口标题覆盖

时间:2015-02-21 18:55:41

标签: java

我正在编写主菜单+网络流量监控器。我的系统运行Linux Cinnamon Mint。

问题是应用程序的标题总是出现在菜单上。

当我点击图标化窗口时,JFrame打开,JPopoupMenu出现在它上面。 当鼠标指针位于面板内部时,标题会悬停在图标化窗口上方,但是当我将其移动到菜单上时它不会消失。

http://i.imgur.com/UIdbiG1.jpg

未捕获鼠标指针,但它位于左侧图片中的面板内(在图标化窗口上方)和右侧菜单上方。

如果我这样做,但没有显示菜单(JFrame的窗口与菜单大小相同),标题仅在鼠标指针位于面板内时出现。

http://i.imgur.com/LjGru1g.jpg

我尝试过'popupMenu.setInvoker(Component)'的不同组件,但在少数情况下问题消失,菜单失去焦点。

先感谢您的帮助。

这是我拼凑在一起的SSCCE(Main.java),因此您可以测试代码:

// To run: javac Main.java; java Main

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GraphicsEnvironment;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.WindowConstants;

/**
 *
 * @author Manuel Iglesias Alonso glesialo@gmail.com
 */
public class Main extends JFrame {

    private final MainMenu mainMenu;
    private boolean menuPopupEnabled;

    public Main(ImageIcon icon, File rootMenuDirectory) {
        super();
        menuPopupEnabled = false;
        setIconImage(icon.getImage());
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowDeiconified(WindowEvent e) {
                super.windowDeiconified(e);
                if (menuPopupEnabled) {
                    mainMenu.popup(MouseInfo.getPointerInfo().getLocation());
                }
            }
        });
        mainMenu = new MainMenu(this, rootMenuDirectory);
        pack(); // Before setPreferredSize: smaller window size.
        setPreferredSize(new Dimension(0, 0)); // Window is always hidden behind menu, the smaller the better.
        setVisible(true);
    }

    private class MainMenu {

        private final int panelHeight = 25;
        private final int iconizedWindowWidthPanelHeightRatio = 5; // Iconized window's width / Iconized window' height
        private final JFrame frame;
        private final File rootMenuDirectory;
        private final Rectangle graphicsBounds;
        private PopupMenuInFrame popupMenu;

        private class PopupMenuInFrame extends JPopupMenu {

            @Override
            protected void firePopupMenuWillBecomeInvisible() {
                super.firePopupMenuWillBecomeInvisible();
                frame.setExtendedState(JFrame.ICONIFIED);
            }

        }

        /**
         *
         * @param rootMenuDirectory Directory where menu files are to be found.
         */
        public MainMenu(JFrame frame, File rootMenuDirectory) {
            this.frame = frame;
            this.rootMenuDirectory = rootMenuDirectory;
            graphicsBounds = frame.getGraphicsConfiguration().getBounds();
        }

        private void newMenu() {
            popupMenu = new PopupMenuInFrame();
            JMenuItem menuItem = new JMenuItem("1st popup menu item");
            menuItem.setToolTipText("1st ToolTip");
            popupMenu.add(menuItem);
            menuItem = new JMenuItem("2nd popup menu item");
            menuItem.setToolTipText("2nd popup menu item ToolTip");
            popupMenu.add(menuItem);
            menuItem = new JMenuItem("3rd A popup menu item");
            menuItem.setToolTipText("menu item ToolTip");
            popupMenu.add(menuItem);
            menuItem = new JMenuItem("4th popup menu item");
            menuItem.setToolTipText("4th popup menu item menu item ToolTip");
            popupMenu.add(menuItem);
            menuItem = new JMenuItem("5th popup menu item");
            menuItem.setToolTipText("ToolTip");
            popupMenu.add(menuItem);
            menuItem = new JMenuItem("6th popup menu item");
            menuItem.setToolTipText("popup menu item menu item ToolTip");
            popupMenu.add(menuItem);
        }

        public void popup(Point mousePointerPosition) {
            Point menuPosition;

            newMenu();
            popupMenu.setInvoker(frame.getContentPane());
            menuPosition = new Point(mousePointerPosition.x, mousePointerPosition.y);
            if (mousePointerPosition.x < iconizedWindowWidthPanelHeightRatio * panelHeight) { //If pointer near leftmost border (within width of iconized window). 
                if (mousePointerPosition.y < (panelHeight + 1)
                        || mousePointerPosition.y > (graphicsBounds.height - panelHeight - 1)) { //If pointer inside a top or bottom panel
                    menuPosition.x = 1; // Position: near left border.
                }
            }
            if (mousePointerPosition.y < (panelHeight + 1)) { //If pointer inside a top panel (within panel's height + 1)
                menuPosition.y = panelHeight + 1; //Menu's top edge just below the panel's lower edge.
            } else {
                if (mousePointerPosition.y > (graphicsBounds.height - panelHeight - 1)) { //If pointer inside a bottom panel (within panel's height + 1)
                    menuPosition.y = graphicsBounds.height - popupMenu.getPreferredSize().height - panelHeight - 1; //Menu's lower edge just above the panel's upper edge.
                }
            }
            frame.setLocation(menuPosition.x + 5, menuPosition.y + 5); // + 5 to make sure window is hidden behind popupMenu.
            popupMenu.setLocation(menuPosition.x, menuPosition.y);
            popupMenu.setVisible(true);
        }

    }

    public static void main(String[] args) {
        final ImageIcon icon;
        final File rootMenuDirectory;

        icon = new ImageIcon();
        rootMenuDirectory = new File("");
        Main frame = new Main(icon, rootMenuDirectory);
        frame.setTitle("Test title");
        try {
            Thread.sleep(500);
        } catch (Exception e) {
        }
        if (!GraphicsEnvironment.isHeadless()) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    frame.setExtendedState(JFrame.ICONIFIED); // Start iconified. If setExtendedState used out of run(), window's events are blocked.
                    frame.menuPopupEnabled = true; // Menu can pop from now on.  
                }
            });
        } else {
            System.exit(1);
        }
    }

}

PS:我已经修改了SSCCE向菜单项添加工具提示。还有一个问题:有时(在向上和向下移动鼠标指针时,菜单项上方)工具提示似乎不完整: http://i.imgur.com/YAw4WYz.jpg

没人帮忙? : - (

我差不多完成了申请。我添加了一个额外的菜单项'MainMenu:About',因此该项目是该死的vindow标题所涵盖的唯一部分(菜单操作后标题消失:子菜单,工具提示......)。 oracle的教程示例(如果我添加工具提示)也会出现工具提示不完整的问题,因此它与我的代码无关。

这是运行菜单的图片(当它位于面板的最左侧时,它将移动到图标化窗口上方:第一个启动应用程序): http://i.imgur.com/eIM2mKy.jpg

应用程序向窗口管理器发送“粘性”提示,窗口出现在所有工作区中。

0 个答案:

没有答案