使用某个左下角坐标进行JPopupMenu显示 [英] Make JPopupMenu Display with a Certain Bottom Left Coordinate

查看:88
本文介绍了使用某个左下角坐标进行JPopupMenu显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我想以这样的方式在Java中创建一个按钮,以便当您单击它时,并计算我希望弹出窗口显示的位置。



基本上,我得到 的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;

公共类TestPopup02 {

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

public TestPopup02(){
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
尝试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}赶上(ClassNotFoundException的| InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException前){
}

帧的JFrame =新的JFrame( 测试);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(新的BorderLayout());
frame.add(新TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

公共类TestPane扩展JPanel {

public TestPane(){
JPopupMenu menu = new JPopupMenu();
menu.add(new JMenuItem(编辑播放列表));
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){
//获取注册的弹出菜单...
JPopupMenu popup = getComponentPopupMenu( );
//获取超级点,以防万一...
Point pos = super.getPopupLocation(event);
if(popup!= null){
//创建一个新的点位置
pos = new Point();
//获取菜单的首选大小...
Dimension size = popup.getPreferredSize();
//调整x位置,使弹出窗口
//的左侧出现在组件的中心
pos.x =(getWidth()/ 2);
//调整y位置,使y位置(顶角)
//定位,以便弹出窗口
//的底部出现在
pos中心。 y =(getHeight()/ 2) - size.height;
}
返回pos;
}

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

@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
//只需在窗口中央绘制一个十字,所以你
//知道中心在哪里...
int width = getWidth() - 1;
int height = getHeight() - 1;
g.drawLine(宽度/ 2,0,宽度/ 2,高度);
g.drawLine(0,height / 2,width,height / 2);
}

}
}

使用Mac输出更新





按钮示例



您不可能找到满足您的解决方案需要。任何开发人员可以开发的最好的技能之一就是能够在需要的时候创建并塑造它。



前面的例子包含了你需要的所有东西,你只需要能够实现从概念到解决方案的跨越。



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;

公共类TestPopup02 {

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

public TestPopup02(){
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
尝试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}赶上(ClassNotFoundException的| InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException前){
}

帧的JFrame =新的JFrame( 测试);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(新的BorderLayout());
frame.add(新TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

公共类TestPane扩展JPanel {

私有JButton按钮;
私人JPopupMenu弹出窗口;

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(刻录播放列表到光盘));
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 ();
//获取菜单的首选大小...
Dimension size = popup.getPreferredSize();
//调整x位置,使弹出窗口的左侧
//出现在组件的中心
pos.x =(button.getWidth()/ 2);
//调整y位置以使y位置(顶角)
//定位,以便弹出窗口底部
//出现在
pos.y =(button.getHeight()/ 2) - size.height; $ b $中心b 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);
//只需在窗口中央绘制一个十字,所以你
//知道中心在哪里...
int width = getWidth() - 1;
int height = getHeight() - 1;
g.drawLine(宽度/ 2,0,宽度/ 2,高度);
g.drawLine(0,height / 2,width,height / 2);
}
}
}


Say that I want to make a button in Java in such a way so that when you click on it, a JPopupMenu appears. The relevant code for it appearing is menu.show(button, button.getWidth()/2, button.getHeight()/2);, which makes the JPopupMenu be displayed with its top left corner at the center of the button, as shown below:

However, I would like to have it so that instead the bottom left corner is at the center of the button, somewhat like what iTunes does (there is a button underneath the bottom left corner, which is the same size as the + button to the left of it):

I tried to make this happen by getting the height of the JPopupMenu and adding it to the y coordinate that the popup menu is being displayed at, but I found out that the JPopupMenu has a height of 0 before it is visible, which doesn't help me since I'm trying to tell the computer where to make it visible. Also, hardcoding in an offset isn't possible because the number of items in the popup isn't necessarily going to be the same.

How can I make it so my JPopupMenu with an unknown height can be displayed so that it's bottom left coordinate matches a given coordinate?

解决方案

Basically, this creates a popup menu and registers it with the component using JComponent#setComponentPopupMenu. This means that I no longer need to monitor for mouse events or make decisions about when to show the popup.

I then override JComponent#getPopupLocation and calculate the location where I want the popup to appear.

Basically, I get the JComponent#getComponentPopupMenu, get it's preferred size and calculate an appropriate offset so that the bottom, left corner now appears in the center of the component...

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);
        }

    }
}

Update with Mac output

Button example

It is unlikely that you will ever find a solution that meets precisely your needs. One of the greatest skills any developer can develop is the ability to take an idea and mold it there needs.

The previous example holds every thing you need, you just need to be able to make the leap from concept to solution.

getPopupLocation is part of the component popup API, so either overriding the method or calling it probably isn't quite what you need (unless you have a dedicated button for the task, which may not be a bad thing), so you would need to adapt the solution to your needs...

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);
        }
    }
}

这篇关于使用某个左下角坐标进行JPopupMenu显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆