Java 使用某个左下角坐标显示JPOppMenu
假设我想用Java制作一个按钮,这样当你点击它时,一个按钮就会出现。它出现的相关代码是Java 使用某个左下角坐标显示JPOppMenu,java,swing,jpopupmenu,Java,Swing,Jpopupmenu,假设我想用Java制作一个按钮,这样当你点击它时,一个按钮就会出现。它出现的相关代码是menu.show(button,button.getWidth()/2,button.getHeight()/2),使JPopupMenu显示在按钮的左上角,如下所示: 但是,我希望它的左下角位于按钮的中心,有点像iTunes(左下角下有一个按钮,大小与左边的+按钮相同): 我试图通过获取JPOppMenu的高度并将其添加到弹出菜单显示的y坐标中来实现这一点,但我发现JPOppMenu在可见之前的高度为0
menu.show(button,button.getWidth()/2,button.getHeight()/2)代码>,使JPopupMenu显示在按钮的左上角,如下所示:
但是,我希望它的左下角位于按钮的中心,有点像iTunes(左下角下有一个按钮,大小与左边的+
按钮相同):
我试图通过获取JPOppMenu的高度并将其添加到弹出菜单显示的y坐标中来实现这一点,但我发现JPOppMenu在可见之前的高度为0,这对我没有帮助,因为我试图告诉计算机在何处使其可见。此外,在偏移量中硬编码是不可能的,因为弹出窗口中的项目数不一定相同
我怎样才能使高度未知的JPopupMenu显示出来,使其左下角的坐标与给定的坐标匹配?这实际上比我想象的要容易得多,在大多数情况下应该可以工作。我使用了你的pastebin代码,并对其进行了一些处理。在框架上调用setVisible(true)
后,我可以调用菜单.getPreferredSize()
。只需将其打印到标准输出,我就得到了java.awt.Dimension[width=31,height=62]
。这可以在调用ActionListener之前完成,这样您就可以利用高度
如果您在菜单中使用边框,您可能需要考虑到这一点,但上述操作应该有效。基本上,这会创建一个弹出菜单,并使用将其注册到组件。这意味着我不再需要监视鼠标事件或决定何时显示弹出窗口
然后我覆盖并计算我希望弹出窗口出现的位置
基本上,我得到了,得到了它的首选尺寸,并计算了一个适当的偏移量,这样左下角现在就出现在组件的中心
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);
}
}
}
使用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;
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);
}
}
}
这个答案只是用来备份我关于弹出窗口可见性和getPreferredSize()的评论
请注意,弹出窗口的首选高度可能为零……如果它没有菜单项,这将是一个合乎逻辑的结论
同样,程序员的答案应该被接受
导入java.awt.gridbag约束;
导入java.awt.GridBagLayout;
导入java.awt.Insets;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JMenuItem;
导入javax.swing.jpopmenu;
导入javax.swing.SwingUtilities;
公共类ButtonPoop扩展JFrame{
私人按钮;
公共按钮pup(){
setLayout(新的GridBagLayout());
按钮=新的JButton(“单击Meh~/o/”);
addActionListener(新建ActionListener()){
已执行的公共无效操作(操作事件e){
JPopupMenu popup=新的JPopupMenu();
添加(新项目(“A”);
添加(新项目(“B”);
添加(新项目(“C”);
//你想要这个
int height=popup.getPreferredSize().height;
弹出显示(
button,button.getWidth()/2,
-高度+(button.getHeight()/2));
}
});
GridBagConstraints gbc=新的GridBagConstraints();
gbc.插图=新插图(5,5,5,5);
添加(按钮,gbc);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
包装();
setLocationRelativeTo(空);
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
新按钮pup().setVisible(true);
}
});
}
}
旁白:我通常不会再提那些死气沉沉的问题,但这一次我在寻找一个类似的东西,这是谷歌的第一个热门话题。这本可以作为评论而不是回答发布的,不幸的是,这仍然会导致高度为0,直到它至少显示一次。我尝试将其作为注释发布,但不允许。抱歉。Thunderforge我认为pack()可能仍然有效,但在布局管理器执行此操作之前,您可能无法请求高度。尝试通过在SwingUtilities.invokeLater()中获取EventQueue末尾的高度。您可能也必须首先验证()。JPopupMenus不在JPanel中(它们只是浮动组件),因此不涉及布局管理器。完整的代码在,您可以使用它来测试并查看是否可以发现修复。用于生成顶级示例的测试用例的代码在,我认为您误解了这个问题。我希望它是这样的,当你点击一个按钮(或者,点击某个点)时,jpopmpmenu就会出现在该点的左下角(如iTunes菜单所示)。您的屏幕截图显示了JPOppMenu的左下角