Swing/TrayIconPopupMenu のバックアップソース(No.5)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- バックアップ を表示
- Swing/TrayIconPopupMenu へ行く。
- 1 (2011-01-31 (月) 15:26:03)
- 2 (2011-01-31 (月) 16:49:00)
- 3 (2011-02-02 (水) 19:07:51)
- 4 (2011-10-25 (火) 18:45:38)
- 5 (2011-10-26 (水) 00:56:41)
- 6 (2011-10-26 (水) 17:46:02)
- 7 (2011-10-27 (木) 10:45:59)
- 8 (2012-01-15 (日) 04:13:15)
- 9 (2012-12-23 (日) 05:36:02)
- 10 (2013-05-26 (日) 05:21:15)
- 11 (2013-08-17 (土) 01:24:19)
- 12 (2013-08-17 (土) 04:59:38)
- 13 (2014-11-01 (土) 00:46:09)
- 14 (2015-02-04 (水) 18:54:29)
- 15 (2016-09-09 (金) 15:08:11)
- 16 (2017-01-06 (金) 13:33:52)
- 17 (2017-04-04 (火) 14:17:08)
- 18 (2017-11-02 (木) 15:34:40)
- 19 (2017-12-12 (火) 13:45:56)
- 20 (2019-12-05 (木) 15:45:36)
- 21 (2021-06-09 (水) 18:08:29)
- 22 (2022-08-20 (土) 22:15:25)
- 23 (2022-10-11 (火) 13:11:52)
- 24 (2024-02-05 (月) 15:50:18)
TITLE:TrayIconでJPopupMenuを使用する #navi(../) RIGHT:Posted by [[aterai]] at 2011-01-31 *TrayIconでJPopupMenuを使用する [#kc07ccfd] TrayIconをクリックしてJPopupMenuを表示します。 //-&jnlp; -&jar; -&zip; //#screenshot #ref(http://lh5.ggpht.com/_9Z4BYR88imo/TUZUBCgOGJI/AAAAAAAAA0A/Ox5g3HoxmoI/s800/TrayIconPopupMenu.png) **サンプルコード [#q69216fd] #code{{ final SystemTray tray = SystemTray.getSystemTray(); final Image image = new ImageIcon(getClass().getResource("16x16.png")).getImage(); final TrayIcon icon = new TrayIcon(image, "TRAY", null); final JPopupMenu popup = new JPopupMenu(); final JDialog dummy = new JDialog(); dummy.setUndecorated(true); popup.addPopupMenuListener(new PopupMenuListener() { @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) {} @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { dummy.setVisible(false); } @Override public void popupMenuCanceled(PopupMenuEvent e) { dummy.setVisible(false); } }); icon.addMouseListener(new MouseAdapter() { private void showJPopupMenu(MouseEvent e) { if(e.isPopupTrigger()) { Point p = adjustPopupLocation(popup, e.getX(), e.getY()); dummy.setLocation(p); dummy.setVisible(true); popup.show(dummy, 0, 0); } } @Override public void mouseReleased(MouseEvent e) { showJPopupMenu(e); } @Override public void mousePressed(MouseEvent e) { showJPopupMenu(e); } }); }} **解説 [#sa6566ea] Java 6 では、TrayIconにはjava.awt.PopupMenuしか使用できないので、setUndecorated(true)かつ、サイズが0x0のJDialogを適当な位置(TrayIconのクリックでJPopupMenuが開いたように見える場所)に配置し、これを親にしてjavax.swing.JPopupMenuを表示しています。 ---- PopupMenuではなく、JPopupMenuが使用できるので、以下のようなことが可能になります。 - JCheckBoxMenuItem、JRadioButtonMenuItemの使用 - LookAndFeelの変更 ---- このサンプルでは、JPopupMenu#adjustPopupLocationToFitScreen(...)メソッドを改変して、SystemTrayの位置によってJPopupMenuが画面外にはみ出さないように調整しています。 #code{{ //Copied from JPopupMenu.java private static Point adjustPopupLocation(JPopupMenu popup, int xposition, int yposition) { Point p = new Point(xposition, yposition); 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()) { 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; // 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; return p; } }} **参考リンク [#y7e86d22] - [http://download.oracle.com/javase/tutorial/uiswing/misc/systemtray.html How to Use the System Tray (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Other Swing Features)] - [http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6285881 Bug ID: 6285881 JTrayIcon: support Swing JPopupMenus for tray icons] - [http://weblogs.java.net/blog/alexfromsun/archive/2008/02/jtrayicon_updat.html JTrayIcon update | Java.net] - [http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6453521 Bug ID: 6453521 TrayIcon should support transparency] **コメント [#kcb0edde] - example.jarとsrc.zipを上げ忘れていたのを修正orz。 -- [[aterai]] &new{2011-02-02 (水) 19:07:51}; - JRE1.6.0u3で2度連続で右クリックするとClassCastExeption起きちゃうんですよね・・・BugParadeでも見つけらんなかったです -- [[sawshun]] &new{2011-10-25 (火) 18:45:38}; #comment