// MenuDemoWithPopupMenuApplication.java (c) 2006 Kari Laitinen // http://www.naturalprogramming.com // 2006-11-18 File created. // 2006-11-26 Last modification. // This program is a modified version of MenuDemoApplication.java. // This version provides a pop-up menu in addition to the traditional // menus. // The settings of the program can be modified both with a conventional // Settings menu and with a popup settings menu. These two menus are // simply different menus and they are synchronized in the // actionPerformed() method. // At least in a Windows PC, you have to use the RIGHT mouse button to // make the pop-up menu active. // You'll find more notes at the end of this file. import java.awt.* ; import java.awt.event.*; import javax.swing.* ; class MenuDemoFrameWithPopupMenu extends JFrame implements ActionListener, MouseListener { static final int WINDOW_WIDTH = 500 ; static final int WINDOW_HEIGHT = 400 ; JMenuItem file_open_menu_item = new JMenuItem( "Open" ) ; JMenuItem file_save_menu_item = new JMenuItem( "Save" ) ; JMenuItem file_exit_menu_item = new JMenuItem( "Exit" ) ; JMenuItem edit_copy_menu_item = new JMenuItem( "Copy" ) ; JMenuItem edit_paste_menu_item = new JMenuItem( "Paste" ) ; JCheckBoxMenuItem cyan_background_menu_item = new JCheckBoxMenuItem( "Cyan background" ) ; JCheckBoxMenuItem popup_cyan_background_menu_item = new JCheckBoxMenuItem( "Cyan background" ) ; JRadioButtonMenuItem small_text_menu_item = new JRadioButtonMenuItem( "Small" ) ; JRadioButtonMenuItem medium_text_menu_item = new JRadioButtonMenuItem( "Medium" ) ; JRadioButtonMenuItem large_text_menu_item = new JRadioButtonMenuItem( "Large" ) ; ButtonGroup text_size_button_group = new ButtonGroup() ; JRadioButtonMenuItem popup_small_text_menu_item = new JRadioButtonMenuItem( "Small" ) ; JRadioButtonMenuItem popup_medium_text_menu_item = new JRadioButtonMenuItem( "Medium" ) ; JRadioButtonMenuItem popup_large_text_menu_item = new JRadioButtonMenuItem( "Large" ) ; ButtonGroup popup_text_size_button_group = new ButtonGroup() ; JMenuItem about_menu_item = new JMenuItem( "About" ) ; String last_selected_menu_item = "NO SELECTIONS MADE." ; JPopupMenu popup_settings_menu = new JPopupMenu() ; public MenuDemoFrameWithPopupMenu() { getContentPane().setBackground( Color.white ) ; setSize( WINDOW_WIDTH, WINDOW_HEIGHT ) ; setTitle( "GUI APPLICATION WITH MENUS" ) ; file_open_menu_item.setMnemonic( 'O' ) ; file_open_menu_item.addActionListener( this ) ; file_save_menu_item.setMnemonic( 'S' ) ; file_save_menu_item.addActionListener( this ) ; file_exit_menu_item.setMnemonic( 'x' ) ; file_exit_menu_item.addActionListener( this ) ; JMenu file_menu = new JMenu( "File" ) ; file_menu.setMnemonic( 'F' ) ; file_menu.add( file_open_menu_item ) ; file_menu.add( file_save_menu_item ) ; file_menu.add( file_exit_menu_item ) ; edit_copy_menu_item.addActionListener( this ) ; edit_paste_menu_item.addActionListener( this ) ; JMenu edit_menu = new JMenu( "Edit" ) ; edit_menu.add( edit_copy_menu_item ) ; edit_menu.add( edit_paste_menu_item ) ; JMenu settings_menu = new JMenu( "Settings" ) ; cyan_background_menu_item.addActionListener( this ) ; settings_menu.add( cyan_background_menu_item ) ; small_text_menu_item.addActionListener( this ) ; medium_text_menu_item.addActionListener( this ) ; large_text_menu_item.addActionListener( this ) ; medium_text_menu_item.setSelected( true ) ; text_size_button_group.add( small_text_menu_item ) ; text_size_button_group.add( medium_text_menu_item ) ; text_size_button_group.add( large_text_menu_item ) ; JMenu text_size_menu = new JMenu( "Text size" ) ; text_size_menu.add( small_text_menu_item ) ; text_size_menu.add( medium_text_menu_item ) ; text_size_menu.add( large_text_menu_item ) ; settings_menu.add( text_size_menu ) ; JMenu help_menu = new JMenu( "Help" ) ; about_menu_item.addActionListener( this ) ; help_menu.add( about_menu_item ) ; JMenuBar menubar_of_this_window = new JMenuBar() ; menubar_of_this_window.add( file_menu ) ; menubar_of_this_window.add( edit_menu ) ; menubar_of_this_window.add( settings_menu ) ; menubar_of_this_window.add( help_menu ) ; setJMenuBar( menubar_of_this_window ) ; setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ) ; // Let's build the popup menu. popup_cyan_background_menu_item.addActionListener( this ) ; popup_settings_menu.add( popup_cyan_background_menu_item ) ; popup_small_text_menu_item.addActionListener( this ) ; popup_medium_text_menu_item.addActionListener( this ) ; popup_large_text_menu_item.addActionListener( this ) ; popup_medium_text_menu_item.setSelected( true ) ; popup_text_size_button_group.add( popup_small_text_menu_item ) ; popup_text_size_button_group.add( popup_medium_text_menu_item ) ; popup_text_size_button_group.add( popup_large_text_menu_item ) ; JMenu popup_text_size_menu = new JMenu( "Text size" ) ; popup_text_size_menu.add( popup_small_text_menu_item ) ; popup_text_size_menu.add( popup_medium_text_menu_item ) ; popup_text_size_menu.add( popup_large_text_menu_item ) ; popup_settings_menu.add( popup_text_size_menu ) ; addMouseListener(this); } // This program implements the MouseListener interface. // The pop-up menu will be shown when the mouse is pressed and // released. It may not be absolutely necessary to have the // pop-up menu activation in the mousePressed() method. public void mouseClicked( MouseEvent event ) {} public void mouseEntered( MouseEvent event ) {} public void mouseExited( MouseEvent event ) {} public void mousePressed( MouseEvent event ) { if ( event.isPopupTrigger() ) { popup_settings_menu.show( event.getComponent(), event.getX(), event.getY() ) ; } } public void mouseReleased( MouseEvent event ) { if ( event.isPopupTrigger() ) { popup_settings_menu.show( event.getComponent(), event.getX(), event.getY() ) ; } } // The following method reacts to the menu selections. // In most cases the only reaction is that the text that // appears on the screen is changed. // Background color is set to cyan if that selection is made. // Help -> About selection brings a message dialog to the screen. // File -> Exit selection terminates the application. public void actionPerformed( ActionEvent event ) { if ( event.getSource() instanceof JMenuItem ) { JMenuItem selected_menu_item = (JMenuItem) event.getSource() ; // The following long if ... else if ... else if .... construct // ensures the synchronization between the conventional Settings // menu and the popup Settings menu. All possible Settings selections // are tested and, if necessary, the setting is copied from // the conventional menu to the popup menu or vice versa. if ( selected_menu_item == popup_cyan_background_menu_item ) { cyan_background_menu_item.setState( popup_cyan_background_menu_item.getState() ) ; } else if ( selected_menu_item == cyan_background_menu_item ) { popup_cyan_background_menu_item.setState( cyan_background_menu_item.getState() ) ; } else if ( selected_menu_item == popup_small_text_menu_item ) { small_text_menu_item.setSelected( true ) ; } else if ( selected_menu_item == popup_medium_text_menu_item ) { medium_text_menu_item.setSelected( true ) ; } else if ( selected_menu_item == popup_large_text_menu_item ) { large_text_menu_item.setSelected( true ) ; } else if ( selected_menu_item == small_text_menu_item ) { popup_small_text_menu_item.setSelected( true ) ; } else if ( selected_menu_item == medium_text_menu_item ) { popup_medium_text_menu_item.setSelected( true ) ; } else if ( selected_menu_item == large_text_menu_item ) { popup_large_text_menu_item.setSelected( true ) ; } last_selected_menu_item = selected_menu_item.getText() ; if ( cyan_background_menu_item.isSelected() == true ) { getContentPane().setBackground( Color.cyan ) ; } else { getContentPane().setBackground( Color.white ) ; } if ( selected_menu_item == file_exit_menu_item ) { setVisible( false ) ; System.exit( 0 ) ; } else if ( selected_menu_item == about_menu_item ) { JOptionPane.showMessageDialog( this, "This is a simple GUI application" + "\nwith menus.", "About", JOptionPane.PLAIN_MESSAGE ) ; } repaint() ; } } public void paint( Graphics graphics ) { super.paint( graphics ) ; if ( small_text_menu_item.isSelected() == true ) { graphics.setFont( new Font( "Serif", Font.PLAIN, 10 ) ) ; } if ( medium_text_menu_item.isSelected() == true ) { graphics.setFont( new Font( "Serif", Font.PLAIN, 14 ) ) ; } if ( large_text_menu_item.isSelected() == true ) { graphics.setFont( new Font( "Serif", Font.PLAIN, 18 ) ) ; } graphics.drawString( "Last selected menu item: \"" + last_selected_menu_item + "\"", 100, 200 ) ; } } public class MenuDemoWithPopupMenuApplication { public static void main( String[] not_in_use ) { MenuDemoFrameWithPopupMenu this_application_window = new MenuDemoFrameWithPopupMenu() ; this_application_window.setVisible( true ) ; } } /* NOTES: The development of this program was somewhat problematic. Java textbooks advice that operations that can be activated in two ways, i.e., through conventional menus and popup menus, should be based on special action classes, such as the following class SettingsAction extends AbstractAction { public SettingsAction( String action_name ) { super( action_name ) ; } public void actionPerformed( ActionEvent event ) { if ( event.getSource() instanceof JMenuItem ) { System.out.print( "\n " + getValue( Action.NAME ) ) ; } } } When this kind of a class is defined, it is possible to specify menu items in the following way: Action cyan_background_action = new SettingsAction( "Cyan background" ); JCheckBoxMenuItem cyan_background_menu_item = new JCheckBoxMenuItem( cyan_background_action ) ; JCheckBoxMenuItem popup_cyan_background_menu_item = new JCheckBoxMenuItem( cyan_background_action ) ; Action small_text_action = new SettingsAction( "Small" ) ; Action medium_text_action = new SettingsAction( "Medium" ) ; Action large_text_action = new SettingsAction( "Large" ) ; JRadioButtonMenuItem small_text_menu_item = new JRadioButtonMenuItem( small_text_action ) ; JRadioButtonMenuItem medium_text_menu_item = new JRadioButtonMenuItem( medium_text_action ) ; JRadioButtonMenuItem large_text_menu_item = new JRadioButtonMenuItem( large_text_action ) ; JRadioButtonMenuItem popup_small_text_menu_item = new JRadioButtonMenuItem( small_text_action ) ; JRadioButtonMenuItem popup_medium_text_menu_item = new JRadioButtonMenuItem( medium_text_action ) ; JRadioButtonMenuItem popup_large_text_menu_item = new JRadioButtonMenuItem( large_text_action ) ; However, the use of action objects does not help much when we use menu items that represent ON/OFF selections or group selections. Because of this reason I ended up not using action objects. */