Respecting the alpha setting of JXPanel

July 20th, 2007

SwingX features a very useful API on the JXPanel. The setAlpha allows setting the alpha (translucency / opacity) value for the panel and all its children. For example, if you want all the child components to be painted with 50% translucency, call myJxPanel.setAlpha(0.5f) and you’re done. As a side note, you can have nested JXPanels; in this case the lowest value wins (see the implementation of JXPanel.getEffectiveAlpha). So, if the outer panel has 0.6 alpha, and the inner panel has 0.4 alpha, the children of the inner panel will be painted with 40% opacity (not 0.6*0.4 = 24% opacity).

One case in which you need to be aware of this setting is when you override the paint or paintComponent and use custom composites. In such a case, you need to respect the current composite set on the Graphics object passed to the paint method(s). The current implementation of JXPanel.paint uses the SRC_OVER alpha composite, and if this is what you’re using as well, you can call the following helper method to compute the “combined” composite to set during your custom painting routine:


   public static Composite getAlphaComposite(
         float translucency, Graphics g) {
      float xFactor = 1.0f;
      if ((g != null) && (g instanceof Graphics2D)) {
         Graphics2D g2d = (Graphics2D) g;
         Composite c2 = g2d.getComposite();
         if (c2 instanceof AlphaComposite) {
            AlphaComposite ac = (AlphaComposite) c2;
            if (ac.getRule() == AlphaComposite.SRC_OVER)
               xFactor = ac.getAlpha();
         }
      }
      if ((translucency == 1.0f) && (xFactor == 1.0f))
         return AlphaComposite.SrcOver;
      else
         return AlphaComposite.getInstance(
               AlphaComposite.SRC_OVER,
               translucency * xFactor);
   }

As you can see, the implementation is pretty straightforward, combining the alpha already set on the Graphics with the one passed to the method. The special case where both are 1.0f simply returns AlphaComposite.SrcOver.

Note that if you’re using a composite different from SRC_OVER, you’ll have to create a temporary image, paint on it and then paint that image back onto the original Graphics (that has the composite of the JXPanel alpha).