Java tutorial
import java.awt.Color; import java.awt.Component; import java.awt.Point; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import javax.swing.ButtonModel; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JToggleButton; import javax.swing.MenuElement; import javax.swing.MenuSelectionManager; import javax.swing.event.MouseInputListener; class JToggleButtonMenuItem extends JToggleButton implements MenuElement { Color savedForeground = null; private static MenuElement NO_SUB_ELEMENTS[] = new MenuElement[0]; public JToggleButtonMenuItem(String label) { super(label); init(); } private void init() { updateUI(); setRequestFocusEnabled(false); // Borrows heavily from BasicMenuUI MouseInputListener mouseInputListener = new MouseInputListener() { // If mouse released over this menu item, activate it public void mouseReleased(MouseEvent mouseEvent) { MenuSelectionManager menuSelectionManager = MenuSelectionManager.defaultManager(); Point point = mouseEvent.getPoint(); if ((point.x >= 0) && (point.x < getWidth()) && (point.y >= 0) && (point.y < getHeight())) { menuSelectionManager.clearSelectedPath(); // Component automatically handles "selection" at this point // doClick(0); // not necessary } else { menuSelectionManager.processMouseEvent(mouseEvent); } } // If mouse moves over menu item, add to selection path, so it becomes // armed public void mouseEntered(MouseEvent mouseEvent) { MenuSelectionManager menuSelectionManager = MenuSelectionManager.defaultManager(); menuSelectionManager.setSelectedPath(getPath()); } // When mouse moves away from menu item, disarm it and select something // else public void mouseExited(MouseEvent mouseEvent) { MenuSelectionManager menuSelectionManager = MenuSelectionManager.defaultManager(); MenuElement path[] = menuSelectionManager.getSelectedPath(); if (path.length > 1) { MenuElement newPath[] = new MenuElement[path.length - 1]; for (int i = 0, c = path.length - 1; i < c; i++) { newPath[i] = path[i]; } menuSelectionManager.setSelectedPath(newPath); } } // Pass along drag events public void mouseDragged(MouseEvent mouseEvent) { MenuSelectionManager.defaultManager().processMouseEvent(mouseEvent); } public void mouseClicked(MouseEvent mouseEvent) { } public void mousePressed(MouseEvent mouseEvent) { } public void mouseMoved(MouseEvent mouseEvent) { } }; addMouseListener(mouseInputListener); addMouseMotionListener(mouseInputListener); } // MenuElement methods public Component getComponent() { return this; } public MenuElement[] getSubElements() { // No subelements return NO_SUB_ELEMENTS; } public void menuSelectionChanged(boolean isIncluded) { ButtonModel model = getModel(); // Only change armed state if different if (model.isArmed() != isIncluded) { model.setArmed(isIncluded); } if (isIncluded) { savedForeground = getForeground(); if (!savedForeground.equals(Color.BLUE)) { setForeground(Color.BLUE); } else { // In case foreground blue, use something different setForeground(Color.RED); } } else { setForeground(savedForeground); // If null, get foreground from installed look and feel if (savedForeground == null) { updateUI(); } } } public void processKeyEvent(KeyEvent keyEvent, MenuElement path[], MenuSelectionManager manager) { // If user presses space while menu item armed, select it if (getModel().isArmed()) { int keyChar = keyEvent.getKeyChar(); if (keyChar == KeyEvent.VK_SPACE) { manager.clearSelectedPath(); System.out.println("Selected: JToggleButtonMenuItem, by KeyEvent"); doClick(0); // inherited from AbstractButton } } } public void processMouseEvent(MouseEvent mouseEvent, MenuElement path[], MenuSelectionManager manager) { // For when mouse dragged over menu and button released if (mouseEvent.getID() == MouseEvent.MOUSE_RELEASED) { manager.clearSelectedPath(); System.out.println("Selected: JToggleButtonMenuItem, by MouseEvent"); doClick(0); // inherited from AbstractButton } } // Borrows heavily from BasicMenuItemUI.getPath() private MenuElement[] getPath() { MenuSelectionManager menuSelectionManager = MenuSelectionManager.defaultManager(); MenuElement oldPath[] = menuSelectionManager.getSelectedPath(); MenuElement newPath[]; int oldPathLength = oldPath.length; if (oldPathLength == 0) return new MenuElement[0]; Component parent = getParent(); if (oldPath[oldPathLength - 1].getComponent() == parent) { // Going deeper under the parent menu newPath = new MenuElement[oldPathLength + 1]; System.arraycopy(oldPath, 0, newPath, 0, oldPathLength); newPath[oldPathLength] = this; } else { // Sibling/child menu item currently selected int newPathPosition; for (newPathPosition = oldPath.length - 1; newPathPosition >= 0; newPathPosition--) { if (oldPath[newPathPosition].getComponent() == parent) { break; } } newPath = new MenuElement[newPathPosition + 2]; System.arraycopy(oldPath, 0, newPath, 0, newPathPosition + 1); newPath[newPathPosition + 1] = this; } return newPath; } } public class JToggleButtonMenuItemDemo { public static void main(final String args[]) { JFrame frame = new JFrame("MenuSample Example"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JMenuBar menuBar = new JMenuBar(); // File Menu, F - Mnemonic JMenu fileMenu = new JMenu("File"); fileMenu.setMnemonic(KeyEvent.VK_F); menuBar.add(fileMenu); // File->New, N - Mnemonic JToggleButtonMenuItem newMenuItem = new JToggleButtonMenuItem("New"); fileMenu.add(newMenuItem); frame.setJMenuBar(menuBar); frame.setSize(350, 250); frame.setVisible(true); } }