001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.util; 003 004import java.awt.Color; 005import java.awt.Graphics; 006import java.awt.Rectangle; 007import java.lang.reflect.Method; 008 009import javax.swing.JComponent; 010import javax.swing.JMenuItem; 011import javax.swing.MenuSelectionManager; 012import javax.swing.UIManager; 013import javax.swing.plaf.ComponentUI; 014import javax.swing.plaf.basic.BasicCheckBoxMenuItemUI; 015import javax.swing.plaf.basic.BasicMenuItemUI; 016 017import org.openstreetmap.josm.tools.Logging; 018import org.openstreetmap.josm.tools.ReflectionUtils; 019 020/** 021 * A CheckBoxMenuItem UI delegate that doesn't close the menu when selected. 022 * @author Darryl Burke https://stackoverflow.com/a/3759675/2257172 023 * @since 15288 024 */ 025public class StayOpenCheckBoxMenuItemUI extends BasicCheckBoxMenuItemUI { 026 027 @Override 028 protected void doClick(MenuSelectionManager msm) { 029 menuItem.doClick(0); 030 } 031 032 @Override 033 protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { 034 ComponentUI ui = UIManager.getUI(menuItem); 035 if (ui instanceof BasicMenuItemUI) { 036 try { 037 Method paintBackground = BasicMenuItemUI.class.getDeclaredMethod( 038 "paintBackground", Graphics.class, JMenuItem.class, Color.class); 039 ReflectionUtils.setObjectsAccessible(paintBackground); 040 paintBackground.invoke(ui, g, menuItem, bgColor); 041 } catch (ReflectiveOperationException | SecurityException | IllegalArgumentException e) { 042 Logging.error(e); 043 super.paintBackground(g, menuItem, bgColor); 044 } 045 } else { 046 super.paintBackground(g, menuItem, bgColor); 047 } 048 } 049 050 @Override 051 protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { 052 ComponentUI ui = UIManager.getUI(menuItem); 053 if (ui instanceof BasicMenuItemUI) { 054 try { 055 Method paintText = BasicMenuItemUI.class.getDeclaredMethod( 056 "paintText", Graphics.class, JMenuItem.class, Rectangle.class, String.class); 057 ReflectionUtils.setObjectsAccessible(paintText); 058 paintText.invoke(ui, g, menuItem, textRect, text); 059 } catch (ReflectiveOperationException | SecurityException | IllegalArgumentException e) { 060 Logging.error(e); 061 super.paintText(g, menuItem, textRect, text); 062 } 063 } else { 064 super.paintText(g, menuItem, textRect, text); 065 } 066 } 067 068 /** 069 * Creates a new {@code StayOpenCheckBoxMenuItemUI}. 070 * @param c not used 071 * @return newly created {@code StayOpenCheckBoxMenuItemUI} 072 */ 073 public static ComponentUI createUI(JComponent c) { 074 return new StayOpenCheckBoxMenuItemUI(); 075 } 076}