2

JPopupMenu

I need to remove the background and Border in JPopupMenu. JPopupMenu should be completely transparent. Overriding the paintComponent does not give a positive result. I also tried to find the solution in BasicMenuItemUI/PopupMenuUI and MenuItemUI/BasicPopupMenuUI but found that the rendering background and border is not in them.

public class CustomMenuItemUI extends BasicMenuItemUI {
    protected MouseInputListener mouseInputListener;
    protected MenuDragMouseListener menuDragMouseListener;
    public static ComponentUI createUI(JComponent c) {
        return new CustomMenuItemUI();
    }

    private static float alpha = 0.0f;
    private static float selectionAlpha = 0.0f;

    public static float getAlpha() {
        return alpha;
    }

    public static void setAlpha(float _alpha) {
        alpha = _alpha;
    }

    @Override
    public void installUI(JComponent c) {
        super.installUI(c);
        menuItem.setOpaque(false);
    }

    @Override
    public void paint(Graphics g, JComponent comp) {
        Graphics2D gx = (Graphics2D) g.create();
        gx.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
        super.paint(gx, comp);
        gx.dispose();
    }

    @Override
    protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) {
        ButtonModel model = menuItem.getModel();
        Color oldColor = Color.red;
        int menuWidth = menuItem.getWidth();
        int menuHeight = menuItem.getHeight();
        if (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) {
            Graphics2D g2 = (Graphics2D) g.create(); 
            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, selectionAlpha));
            g2.setColor(Color.red);
            g2.fillRect(0, 0, menuWidth, menuHeight);
        } else {
            g.setColor(Color.red);
            g.fillRect(0, 0, menuWidth, menuHeight);
        }
        g.setColor(oldColor);
    }

    @Override
    protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) {
        ButtonModel model = menuItem.getModel();
        if (model.isArmed() || model.isSelected() || !model.isSelected()) {
            Graphics2D g2 = (Graphics2D) g.create();
            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
            super.paintText(g2, menuItem, textRect, text);
            g2.dispose();
        } else {
            super.paintText(g, menuItem, textRect, text);
        }
    }
    public static void setSelectionAlpha(float alpha) {
        selectionAlpha  = alpha;
    }
}

    String poppUI = CustomPopupMenuUI.class.getName(); 
UIManager.put("PopupMenuUI", poppUI);
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
user1221483
  • 431
  • 2
  • 7
  • 20
  • 1
    *"not give a positive result"* I would not consider the text of a pop-up floating/intermingled with the BG text to be a positive result. But then, maybe it is just me (& 100,000 other end users). – Andrew Thompson Sep 19 '12 at 17:18
  • What are you trying to accomplish? Are you shure JPopupMenu is the right Component? – keuleJ Sep 19 '12 at 17:23
  • `BasicPopupMenuUI` includes code to install the relevant L&F defaults. – trashgod Sep 19 '12 at 17:29
  • http://s05.radikal.ru/i178/1209/e9/b6c030c2d732.gif background spoils. km1 unfortunately it does not work because remains band – user1221483 Sep 19 '12 at 17:40

1 Answers1

6

You can change the PopupMenuUI delegate's properties, although there's no guarantee that your chosen Look & Feel will honor the changes. the change should be early in the program, before any GUI component is instantiated.

UIManager.put("PopupMenu.background", new Color(0));
UIManager.put("PopupMenu.border", BorderFactory.createEmptyBorder());

Addendum: As @MadProgrammer commented, the platform's peer component may be opaque and outside your control. Your code (MenuTest, CustomPopupMenuUI, CustomMenuItemUI) has the appearance shown below on com.apple.laf.AquaLookAndFeel. Absent a better solution, you might look at implementing your own translucent window as shown here.

image

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • If your your chosen Look & Feel doesn't honor the settings, you'll have to find one that does or write your own `PopupMenuUI` subclass that does. – trashgod Sep 19 '12 at 18:00
  • 1
    @user1221483 The larger problem you are facing is you have no real means of know how the popup is eventually displayed on the screen. The `JPopupMenu` is added to a "native peer" at some time in the future, to which you have little or no real access to... – MadProgrammer Sep 19 '12 at 20:26
  • I created an empty CustomMenuItemUI. Even so the Border is not lost. I looked a few times all the source code and can not find a code for drawing this border http://s53.radikal.ru/i140/1209/50/dbc9048a2683.gif – user1221483 Sep 19 '12 at 20:37
  • @user1221483 The border is probably been painted by the `JMenu` not the `JMenuItem` – MadProgrammer Sep 19 '12 at 20:42
  • @user1221483: It may help to edit your question to include an [sscce](http://sscce.org/) that shows your current approach. In particualr, what L&F are you using? – trashgod Sep 19 '12 at 20:56
  • I'm using the default LAF. Added my CustomMenuItemUI – user1221483 Sep 19 '12 at 21:05
  • The default varies by platform; for example, I'm using `com.apple.laf.AquaLookAndFeel`. – trashgod Sep 19 '12 at 21:10
  • AFAIK, the Metal L&F is cross-platform, but the popup peer may be platform-dependednt, as @MadProgrammer points out; when you post an [sscce](http://sscce.org/), I'll try it and post a picture. – trashgod Sep 19 '12 at 21:30
  • http://rghost.ru/download/40468757/1e72201997c6faeee5abda7fbd1a11e78e119e67/CustomMenuItemUI.java http://rghost.ru/download/40468763/9ffbee8b482c6b7fdda3fa865c348e6513a0119d/CustomPopupMenuUI.java http://rghost.ru/download/40468766/9732a7ad1e6f94080dd25128816cdb9fb76b83c5/MenuTest.java]MenuTest.java – user1221483 Sep 19 '12 at 23:16