How can i make a JPopupMenu transparent?

后端 未结 4 1400
暖寄归人
暖寄归人 2021-01-18 20:19

I\'d like to customize the look of JPopupMenu so i made a custom class extending the JPopupMenu class on i overrode the paintComponent method as i

4条回答
  •  广开言路
    2021-01-18 20:36

    See this excellent 2008 article Translucent and Shaped Swing Windows by Kirill Grouchnikov.

    Based on examples given in the above article and code borrowed from the JGoodies project, you can install a custom popup Look & Feel using the following 2 classes:

    1. TranslucentPopup is the customized Popup, used by JPopupMenu:

      /**
       * Translucent Popup
       *
       * @author Kirill Grouchnikov [https://www.java.net/pub/au/275]
       */
      public class TranslucentPopup extends Popup {
          final JWindow popupWindow;
      
          TranslucentPopup(Component contents, int ownerX, int ownerY) {
              // create a new heavyweight window
              popupWindow = new JWindow();
              // mark the popup with partial opacity
              com.sun.awt.AWTUtilities.setWindowOpacity(popupWindow, 0.7f);
              // determine the popup location
              popupWindow.setLocation(ownerX, ownerY);
              // add the contents to the popup
              popupWindow.getContentPane().add(contents, BorderLayout.CENTER);
              contents.invalidate();
              JComponent parent = (JComponent) contents.getParent();
              // set a custom border
              parent.setBorder(BorderFactory.createRaisedSoftBevelBorder());
          }
      
          public void show() {
              popupWindow.setVisible(true);
              popupWindow.pack();
              // mark the window as non-opaque, so that the
              // border pixels take on the per-pixel opacity
              com.sun.awt.AWTUtilities.setWindowOpaque(popupWindow, false);
          }
      
          public void hide() {
              popupWindow.setVisible(false);
          }
      }
      
    2. TranslucentPopupFactory is requried to install the custom Look and Feel:

      /**
       * Translucent Popup Factory
       *
       * @author Kirill Grouchnikov [https://www.java.net/pub/au/275]
       * @author Karsten Lentzsch (JGoodies project)
       */
      public class TranslucentPopupFactory extends PopupFactory {
          /**
           * The PopupFactory used before this PopupFactory has been installed in
           * {@code #install}. Used to restored the original state in
           * {@code #uninstall}.
           */
          protected final PopupFactory storedFactory;
      
          protected TranslucentPopupFactory(PopupFactory originalFactory) {
              storedFactory = originalFactory;
          }
      
          public Popup getPopup(Component owner, Component contents, int x, int y) throws IllegalArgumentException {
              // A more complete implementation would cache and reuse popups
              return new TranslucentPopup(contents, x, y);
          }
      
          /**
            * Utility method to install the custom Popup Look and feel.
            * Call this method once during your application start-up.
            *
            * @author Karsten Lentzsch (JGoodies project)
            */
          public static void install() {
              PopupFactory factory = PopupFactory.getSharedInstance();
              if (factory instanceof TranslucentPopupFactory) {
                  return;
              }
      
              PopupFactory.setSharedInstance(new TranslucentPopupFactory(factory));
          }
      
          /**
            * Utility method to uninstall the custom Popup Look and feel
            * @author Karsten Lentzsch (JGoodies project)
            */
          public static void uninstall() {
              PopupFactory factory = PopupFactory.getSharedInstance();
              if (!(factory instanceof TranslucentPopupFactory)) {
                  return;
              }
      
              PopupFactory stored = ((TranslucentPopupFactory) factory).storedFactory;
              PopupFactory.setSharedInstance(stored);
          }
      }
      

    The result is that all Popups (including JPopupMenu and perhaps also ToolTips) will now be Translucent, and optionally have a custom border: Translucent Context Menu shown on World Wind Context Menu example app

提交回复
热议问题