基本的に、これはポップアップ メニューを作成し、 を使用してコンポーネントに登録します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);
}
}
}
Mac出力で更新
ボタンの例
ニーズを正確に満たすソリューションが見つかる可能性はほとんどありません。開発者が開発できる最大のスキルの 1 つは、アイデアを取り入れて必要な形で形にする能力です。
前の例には、必要なものがすべて含まれています。必要なのは、コンセプトからソリューションへと飛躍できることだけです。
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);
}
}
}