Swing/TrayIconPopupMenu のバックアップの現在との差分(No.3)
TITLE:TrayIconでJPopupMenuを使用する
Posted by aterai at 2011-01-31
TrayIconでJPopupMenuを使用する
TrayIconをクリックしてJPopupMenuを表示します。- category: swing folder: TrayIconPopupMenu title: TrayIconでJPopupMenuを使用する tags: [TrayIcon, JPopupMenu, JDialog, LookAndFeel, JCheckBoxMenuItem, JRadioButtonMenuItem] author: aterai pubdate: 2011-01-31T15:26:03+09:00 description: TrayIconをクリックしてJPopupMenuを表示します。 image:
概要
TrayIcon
をクリックしてJPopupMenu
を表示します。
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
#spanend
#spanadd
SystemTray tray = SystemTray.getSystemTray();
#spanend
#spanadd
Image image = new ImageIcon(getClass().getResource("16x16.png")).getImage();
#spanend
#spanadd
TrayIcon icon = new TrayIcon(image, "TRAY", null);
#spanend
#spanadd
JPopupMenu popup = new JPopupMenu();
#spanend
#spanadd
JDialog tmp = new JDialog();
#spanend
#spanadd
tmp.setUndecorated(true);
#spanend
#spanadd
popup.addPopupMenuListener(new PopupMenuListener() {
#spanend
@Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
/* not needed */
}
#spandel
**サンプルコード [#q69216fd]
#spanend
#spandel
#code{{
#spanend
#spandel
final SystemTray tray = SystemTray.getSystemTray();
#spanend
#spandel
final Image image = new ImageIcon(getClass().getResource("16x16.png")).getImage();
#spanend
#spandel
final TrayIcon icon = new TrayIcon(image, "TRAY", null);
#spanend
#spandel
final JPopupMenu popup = new JPopupMenu();
#spanend
#spandel
final JDialog dummy = new JDialog();
#spanend
#spandel
dummy.setUndecorated(true);
#spanend
#spandel
popup.addPopupMenuListener(new PopupMenuListener() {
#spanend
@Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
@Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
dummy.setVisible(false);
tmp.setVisible(false);
}
#spanadd
#spanend
@Override public void popupMenuCanceled(PopupMenuEvent e) {
dummy.setVisible(false);
tmp.setVisible(false);
}
});
#spanadd
#spanend
icon.addMouseListener(new MouseAdapter() {
private void showJPopupMenu(MouseEvent e) {
if(e.isPopupTrigger()) {
if (e.isPopupTrigger()) {
Point p = adjustPopupLocation(popup, e.getX(), e.getY());
dummy.setLocation(p);
dummy.setVisible(true);
popup.show(dummy, 0, 0);
tmp.setLocation(p);
tmp.setVisible(true);
popup.show(tmp, 0, 0);
}
}
#spanadd
#spanend
@Override public void mouseReleased(MouseEvent e) {
showJPopupMenu(e);
}
#spanadd
#spanend
@Override public void mousePressed(MouseEvent e) {
showJPopupMenu(e);
}
});
View in GitHub: Java, Kotlin解説
Java 6 では、TrayIconにはjava.awt.PopupMenuしか使用できないので、setUndecorated(true)かつ、サイズが0x0のJDialogを適当な位置(TrayIconのクリックでJPopupMenuが開いたように見える場所)に配置し、これを親にしてjavax.swing.JPopupMenuを表示しています。解説
JDK 1.6.0
のTrayIcon
はjava.awt.PopupMenu
のみ設定可能でjavax.swing.JPopupMenu
は使用不可になっています。そのため上記のサンプルでは、装飾なし(setUndecorated(true)
)でサイズが0x0
のJDialog
を適当な位置(TrayIcon
のクリックでJPopupMenu
が開いたように見える場所)に配置し、これを親にしてjavax.swing.JPopupMenu
を表示しています。
- - PopupMenuではなく、JPopupMenuが使用できるので、以下のようなことが可能になります。
- JCheckBoxMenuItem、JRadioButtonMenuItemの使用
- LookAndFeelの変更
-
PopupMenu
ではなくJPopupMenu
が使用できるので以下が可能-
JCheckBoxMenuItem
、JRadioButtonMenuItem
の使用 -
LookAndFeel
の変更
-
- このサンプルでは、
JPopupMenu#adjustPopupLocationToFitScreen(...)
メソッドを改変してSystemTray
の位置によってJPopupMenu
が画面外にはみ出さないように調整
- - このサンプルでは、JPopupMenu#adjustPopupLocationToFitScreen(...)メソッドを改変して、SystemTrayの位置によってJPopupMenuが画面外にはみ出さないように調整しています。
#spandel
//Copied from JPopupMenu.java
#spanend
#spandel
private static Point adjustPopupLocation(JPopupMenu popup, int xposition, int yposition) {
#spanend
#spanadd
// Copied from JPopupMenu.java: JPopupMenu#adjustPopupLocationToFitScreen(...)
#spanend
#spanadd
private static Point adjustPopupLocation(
#spanend
JPopupMenu popup, int xposition, int yposition) {
Point p = new Point(xposition, yposition);
if (GraphicsEnvironment.isHeadless()) return p;
#spandel
#spanend
if (GraphicsEnvironment.isHeadless()) {
return p;
}
Rectangle screenBounds;
GraphicsConfiguration gc = null;
// Try to find GraphicsConfiguration, that includes mouse pointer position
for (GraphicsDevice gd: GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
for (GraphicsDevice gd : ge.getScreenDevices()) {
if (gd.getType() == GraphicsDevice.TYPE_RASTER_SCREEN) {
GraphicsConfiguration dgc = gd.getDefaultConfiguration();
if (dgc.getBounds().contains(p)) {
gc = dgc;
break;
}
}
}
// If not found and popup have invoker, ask invoker about his gc
if (gc == null && popup.getInvoker() != null) {
gc = popup.getInvoker().getGraphicsConfiguration();
}
if (gc != null) {
// If we have GraphicsConfiguration use it to get
// screen bounds
screenBounds = gc.getBounds();
} else {
// If we don't have GraphicsConfiguration use primary screen
screenBounds = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
}
Dimension size = popup.getPreferredSize();
// Use long variables to prevent overflow
long pw = (long) p.x + (long) size.width;
long ph = (long) p.y + (long) size.height;
if (pw > screenBounds.x + screenBounds.width) p.x -= size.width;
if (ph > screenBounds.y + screenBounds.height) p.y -= size.height;
if (pw > screenBounds.x + screenBounds.width) {
p.x -= size.width;
}
if (ph > screenBounds.y + screenBounds.height) {
p.y -= size.height;
}
// Change is made to the desired (X,Y) values, when the
// Change is made to the desired (X, Y) values, when the
// PopupMenu is too tall OR too wide for the screen
if (p.x < screenBounds.x) p.x = screenBounds.x;
if (p.y < screenBounds.y) p.y = screenBounds.y;
#spandel
#spanend
p.x = Math.max(p.x, screenBounds.x);
p.y = Math.max(p.y, screenBounds.y);
return p;
}
参考リンク
- How to Use the System Tray (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Other Swing Features)
- Bug ID: 6285881 JTrayIcon: support Swing JPopupMenus for tray icons
- JTrayIcon update | Java.net
- Bug ID: 6453521 TrayIcon should support transparency
参考リンク
- Alexander Potochkin's Blog: JTrayIcon update
- How to Use the System Tray (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Other Swing Features)
- Bug ID: 6285881 JTrayIcon: support Swing JPopupMenus for tray icons
- Bug ID: 6453521 TrayIcon should support transparency