001/******************************************************************************* 002 003 File: QuitJMenuItem.java 004 Author: Steve Roy <steve@sillybit.com> 005 006 Part of MRJ Adapter, a unified API for easy integration of Mac OS specific 007 functionality within your cross-platform Java application. 008 009 This library is open source and can be modified and/or distributed under 010 the terms of the Artistic License. 011 <http://mrjadapter.dev.java.net/license.html> 012 013 Change History: 014 01/31/03 Created this file - Steve 015 016*******************************************************************************/ 017 018package jahuwaldt.swing; 019 020import javax.swing.JMenuItem; 021import javax.swing.KeyStroke; 022import java.awt.Toolkit; 023import java.awt.event.ActionListener; 024import java.awt.event.KeyEvent; 025import static java.util.Objects.nonNull; 026 027/** 028 * This is the Swing implementation of the Quit menu item. 029 * <p> 030 * On Mac OS, this menu item is always automatically included in the menu 031 * bar of the application. On other platforms, it never is. You can find out 032 * at runtime if the menu item is automatically included with the 033 * <code>isAutomaticallyPresent()</code> method and then add it yourself if 034 * it isn't. This will make your code cross-platform while letting the 035 * application do the right thing for the current platform. 036 * <p> 037 * In the case where the Quit menu item is automatically included, this menu 038 * item is really just a placeholder for the actual native menu item, passing 039 * off operations to and from the native menu item where possible. Of course, 040 * when this is the case, not all methods of this class will be functional. 041 * However, there is no harm in calling dysfunctional methods, other than 042 * your user interface not matching your requests. 043 * <p> 044 * The methods that work on all platforms are the following. 045 * <ul> 046 * <li>addActionListener</li> 047 * <li>removeActionListener</li> 048 * <li>setAction (only making the action the listener will actually work on 049 * all platforms)</li> 050 * </ul> 051 * 052 * MRJ Adapter 1.2, Modified by Joseph A. Huwaldt 053 * @version December 24, 2023 054 */ 055public class QuitJMenuItem extends JMenuItem { 056 057 /** 058 * Construct a Quit menu item. This method is package private so only the 059 * <code>Application</code> class can create a Quit menu item. 060 * 061 * @param application the application instance using this item 062 */ 063 @SuppressWarnings("OverridableMethodCallInConstructor") 064 QuitJMenuItem(MDIApplication application) { 065 this(application, "Exit"); 066 } 067 068 /** 069 * Construct a Quit menu item. This method is package private so only the 070 * <code>Application</code> class can create a Quit menu item. 071 * 072 * @param application the application instance using this item 073 * @param quitLabel The label for the Exit menu on non-MacOS platforms. 074 */ 075 @SuppressWarnings("OverridableMethodCallInConstructor") 076 QuitJMenuItem(MDIApplication application, String exitLabel) { 077 super(AppUtilities.isWindows() ? exitLabel : "Quit"); 078 if (AppUtilities.isWindows()) 079 setAccelerator(KeyStroke.getKeyStroke("alt F4")); 080 else 081 setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 082 Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx())); 083 String appName = application.getName(); 084 if (MacOSUtilities.isMacOS() && nonNull(appName)) 085 setText("Quit " + appName); 086 } 087 088 /** 089 * Get whether this menu item is automatically present in the menu bar of the current 090 * underlying platform. 091 * 092 * @return whether this menu item is automatically present 093 */ 094 public static boolean isAutomaticallyPresent() { 095 return MacOSUtilities.isMacOS(); 096 } 097}