当前位置: 首页 > 知识库问答 >
问题:

使JPopupMenu以某个左下坐标显示

姚棋
2023-03-14

假设我想以这样的方式在Java中制作一个按钮,这样当你点击它时,就会出现一个JPopupMenu。它出现的相关html" target="_blank">代码是menu.show(button,button.getwidth()/2,button.getheight()/2);,它使JPopupMenu的左上角显示在按钮的中心,如下所示:

不过,我希望它的左下角位于按钮的中心,有点像iTunes的做法(左下角下方有一个按钮,大小与左侧的+按钮相同):

我试图通过获取JPopupMenu的高度并将其添加到弹出菜单正在显示的y坐标来实现这一点,但我发现JPopupMenu在可见之前的高度为0,这对我没有帮助,因为我试图告诉计算机在哪里使其可见。另外,在偏移量中硬编码是不可能的,因为弹出窗口中的项目数量不一定相同。

我如何使它,使我的JPopupMenu与未知的高度可以显示,使它的左下坐标匹配一个给定的坐标?

共有1个答案

谷森
2023-03-14

基本上,这会创建一个弹出菜单,并使用JComponent#SetComponentPopupMenu将其注册到组件中。这意味着我不再需要监视鼠标事件或决定何时显示弹出窗口。

然后重写JComponent#GetPopupLocation并计算我希望弹出窗口出现的位置。

基本上,我得到JComponent#GetComponentPopupMenu,得到它的首选大小,并计算一个适当的偏移量,以便左下角现在出现在组件的中心...

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestPopup02 {

    public static void main(String[] args) {
        new TestPopup02();
    }

    public TestPopup02() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            JPopupMenu menu = new JPopupMenu();
            menu.add(new JMenuItem("Edit Playlist"));
            menu.addSeparator();
            menu.add(new JMenuItem("Check for Available Downloads..."));
            menu.addSeparator();
            menu.add(new JMenuItem("Export..."));
            menu.add(new JMenuItem("Burn Playlist to Disc"));
            menu.add(new JMenuItem("Copy To Play Order"));
            menu.addSeparator();
            menu.add(new JMenuItem("Delete"));
            setComponentPopupMenu(menu);
        }

        @Override
        public Point getPopupLocation(MouseEvent event) {
            // Get the registered popup menu...
            JPopupMenu popup = getComponentPopupMenu();
            // Get the super point, just in case...
            Point pos = super.getPopupLocation(event);
            if (popup != null) {
                // Create a new "point" location
                pos = new Point();
                // get the preferred size of the menu...
                Dimension size = popup.getPreferredSize();
                // Adjust the x position so that the left side of the popup
                // appears at the center of  the component
                pos.x = (getWidth() / 2);
                // Adjust the y position so that the y postion (top corner)
                // is positioned so that the bottom of the popup
                // appears in the center
                pos.y = (getHeight() / 2) - size.height;
            }
            return pos;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            // Simply draws a cross in the center of the window, so you 
            // know where the center is...
            int width = getWidth() - 1;
            int height = getHeight() - 1;
            g.drawLine(width / 2, 0, width / 2, height);
            g.drawLine(0, height / 2, width, height / 2);
        }

    }
}

你不可能找到一个完全满足你需要的解决方案。任何开发人员所能开发的最伟大的技能之一就是有能力接受一个想法并根据需要塑造它。

前面的例子包含了您所需要的一切,您只需要能够实现从概念到解决方案的飞跃。

GetPopupLocation是组件弹出API的一部分,因此重写方法或调用方法可能都不是您所需要的(除非您有一个用于任务的专用按钮,这可能不是一件坏事),因此您需要使解决方案适应您的需要...

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestPopup02 {

    public static void main(String[] args) {
        new TestPopup02();
    }

    public TestPopup02() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JButton button;
        private JPopupMenu popup;

        public TestPane() {
            popup = new JPopupMenu();
            popup.add(new JMenuItem("Edit Playlist"));
            popup.addSeparator();
            popup.add(new JMenuItem("Check for Available Downloads..."));
            popup.addSeparator();
            popup.add(new JMenuItem("Export..."));
            popup.add(new JMenuItem("Burn Playlist to Disc"));
            popup.add(new JMenuItem("Copy To Play Order"));
            popup.addSeparator();
            popup.add(new JMenuItem("Delete"));

            setLayout(new GridBagLayout());
            button = new JButton("+");
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    popup.pack();
                    Point pos = new Point();
                    // get the preferred size of the menu...
                    Dimension size = popup.getPreferredSize();
                    // Adjust the x position so that the left side of the popup
                    // appears at the center of  the component
                    pos.x = (button.getWidth() / 2);
                    // Adjust the y position so that the y postion (top corner)
                    // is positioned so that the bottom of the popup
                    // appears in the center
                    pos.y = (button.getHeight() / 2) - size.height;
                    popup.show(button, pos.x, pos.y);
                }
            });
            add(button);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            // Simply draws a cross in the center of the window, so you 
            // know where the center is...
            int width = getWidth() - 1;
            int height = getHeight() - 1;
            g.drawLine(width / 2, 0, width / 2, height);
            g.drawLine(0, height / 2, width, height / 2);
        }
    }
}
 类似资料:
  • 问题内容: 我从http://www.movable-type.co.uk/scripts/latlong.html实现了“轴承”公式。但这似乎非常不准确- 我怀疑我的实现中存在一些错误。您能帮我找到它吗?我的代码如下: 问题答案: 您将括号放在错误的位置。 您正在将度数添加到以弧度为单位的值,这将不起作用。将为您完成从弧度到度的转换, 然后 在获得度值后进行归一化。 你有: 但是您需要: 也请记

  • 我在几个设备和浏览器上测试了一个网页(PC、平板、iPad、android手机),一切看起来都不错。 我发现的唯一问题是当我使用Android手机测试网页时,使用IE作为浏览器。 网页以某种方式被推到屏幕左侧,导航链接没有正确对齐。只有在android手机上使用Internet Explorer查看时才会出现这种情况。 知道为什么会发生这种情况以及如何解决吗? 以下是网页:http://www.n

  • 根据坐标系,如果只给定矩形的中心坐标以及宽度和高度,您将如何确定矩形的左上角坐标? 例如,矩形的中心坐标是(40,40),矩形的宽度为90,高度为60。

  • 我正在使用PDFBOX和itextSharp dll并处理pdf。这样我就可以得到矩形内文本的文本坐标。矩形坐标是使用itextsharp.dll.基本上我从itextsharp.dll获得矩形坐标,其中itextSharp使用坐标系统作为左下。我从PDFBOX获得pdf页面文本,其中PDFBOX使用坐标系统作为左上角。我需要帮助将坐标从左下转换为左上角 更新我的问题 如果你不理解我的问题,如果没

  • 问题内容: 我发现(0,0)映射到屏幕的左上角有点不直观。在Java Swing中使用左手坐标系是否有历史原因? 虽然将其映射到右手系统并不难,但我很好奇,知道使用左手系统是否有任何隐藏的好处。 问题答案: 根据这篇文章,这仅仅是因为这是电视机一直使用的方式(BTW并没有改变)。因此,这个早期的设计决策似乎今天仍然会产生影响。 早期的家用计算机通常连接到电视,因此自然会使用此坐标系。我猜想很多显示

  • 我试图在父div内获得可拖动div的左上角的坐标。我可以在父div中获取鼠标的坐标,这是通过一个标签完成的。我想知道是否有任何类似的标记,例如来获取div的坐标 我使用标签,但它不起作用。