Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

transparent for real

Posted on 2004-03-22
7
Medium Priority
?
769 Views
Last Modified: 2012-05-04
in my swing application (with windows L&F) i want to set a gradient paint on my menu bar. so i extend JMenuBar and override the paintComponent method (that's the way, right?). all's ok until i add a JMenu to this menu bar of mine. I can't make the menu button (such as "File") to be transparent. Apparently setOpaque(false) works only with the Metal L&F. So how do i set my JMenu-s to see the menubar through them (both when they are selected and not selected) ??? thanks


p.s: i think the same problem occurs even if you only set the background of the menuBar
0
Comment
Question by:hapciu
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
7 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 10653061
Did you call

super.paintComponent();

?
0
 

Author Comment

by:hapciu
ID: 10653176
of course.... first thing in the method ...
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10653204
That's just my 2c i'm afraid.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 9

Expert Comment

by:doronb
ID: 10820033
Working on it, but could you post some code? :)
0
 
LVL 9

Accepted Solution

by:
doronb earned 240 total points
ID: 10821488
Ok, I've built a GradientPainter object that performs the gradient work.
I also extended JMenuBar, JMenu, JMenuItem into their respective Gradient counter-parts.
I setup the Menus and MenuItems to share the Gradient of the MenuBar so that it looks ok.

However, under Windows for some reason, things don't seem to work right.
The JMenuBar doesn't draw the Gradient background while the other menu components do!
I'm working with JBuilder and inside JBuilder everything works just fine.
However, if I use the SystemLookAndFeel classes (Windows L&F) running my program from the executable JAR, then the JMenuBar doesn't work right.
If I run the JAR with the CrossPlatform L&F, everything works fine.

I think the problem lies in the L&F UI classes themselves because I believe its not entirely up to the Menu components to draw everything by themselves!

I don't know if it'd be any help, but here's my GradientPainter class :)

import java.awt.*;
import javax.swing.*;
import java.awt.image.*;

public class GradientPainter {
      private Image background;
      private Rectangle rect;
      private TransparentColourFilter filter;
      private GradientPaint gradient;
      private Rectangle gradientRect;
      private Color start = Color.black;
      private Color finish = Color.white;
      private JComponent swingComponent;
      private GradientPainter linkedGradient;
      private boolean isMaster = false;

      // Create a GradientPainter for a specific Swing component..
      public GradientPainter(JComponent c) {
            swingComponent = c;
      }

      public void setMasterGradient(GradientPainter gp) {
            linkedGradient = gp;
            linkedGradient.setMaster();
            gradient = null;
      }

      protected void setMaster() {
            isMaster = true;
      }

      protected GradientPaint getGradientPaint() {
            verifyGradientColour();
            return gradient;
      }

      // This is the TransparentColourFilter that will help us put the Gradient as background..
      private class TransparentColourFilter extends RGBImageFilter {
            protected int from;
            protected static final int rgbMask = 0x00ffffff;

            private TransparentColourFilter(Color transparentColour) {
                  super();
                  from = transparentColour.getRGB() & rgbMask;
                  canFilterIndexColorModel = true;
            }

            public int filterRGB(int x, int y, int rgb) {
                  return ((rgb & rgbMask) == from) ? rgbMask : rgb;
            }
      }

      private Rectangle getCurrentBounds() {
            Container current = swingComponent;
            if (isMaster) {
                  while (current.getParent() != null) {
                        current = current.getParent();
                  }
            }
            return current.getBounds();
      }

      // Make sure a GradientColor object is created for our use..
      private void verifyGradientColour() {
            gradientRect = getCurrentBounds();
            if (linkedGradient != null) {
                  gradient = linkedGradient.getGradientPaint();
            } else if ((gradient == null) || ((rect.width != gradientRect.width) || (rect.height != gradientRect.height))) {
                  gradient = new GradientPaint(0, 0, start, gradientRect.width, gradientRect.height, finish, true);
            }
      }

      public void setStartColor(Color colour) {
            start = colour;
      }

      public void setEndColor(Color colour) {
            finish = colour;
      }

      public Color getStartColor() {
            return start;
      }

      public Color getEndColor() {
            return finish;
      }

      // This method is used to prepare the Gradient background on the Component's Graphics..
      public Graphics prepareGraientBackground(Graphics g) {
            // Prepare a TransparentColourFilter object..
            filter = new TransparentColourFilter(swingComponent.getParent().getBackground());
            // Get the rectangle where we'll draw..
            rect = g.getClipBounds();
            // Get the Graphics object color..
            Color c = g.getColor();
            // Cast to Graphics2D..
            Graphics2D g2d = (Graphics2D)g;
            // Make sure we've created the Gradient colour..
            verifyGradientColour();
            // Set the Gradient as the Paint Object..
            g2d.setPaint(gradient);
            // Fill the rectangle with the gradient colour..
            g2d.fillRect(rect.x, rect.y, rect.width, rect.height);
            // Return to the previous paint colour..
            g2d.setPaint(c);
            // Create the background image..
            background = swingComponent.createImage(rect.width, rect.height);
            // Return the Graphics object that belongs to the background image..
            return background.getGraphics();
      }

      // This method is used to paint the transparent image over the Gradient background..
      public void paintComponent(Graphics g) {
            // Create a transparent image based on filtering the background image with the Gradient colour..
            background = swingComponent.createImage(new FilteredImageSource(background.getSource(), filter));
            // Finally, draw the transparent-gradient-background image together with the rest of the component..
            g.drawImage(background, rect.x, rect.y, null);
      }
}

I now of course have a GradientMenuBar:

public class GradientMenuBar extends JMenuBar {
      private GradientPainter tmHelper;

      public GradientMenuBar() {
            super();
            tmHelper = new GradientPainter(this);
      }

      public GradientPainter getGradientPainter() {
            return tmHelper;
      }

      public void setStartColor(Color colour) {
            tmHelper.setStartColor(colour);
      }

      public void setEndColor(Color colour) {
            tmHelper.setEndColor(colour);
      }

      public Color getStartColor() {
            return tmHelper.getStartColor();
      }

      public Color getEndColor() {
            return tmHelper.getEndColor();
      }

      protected void paintComponent(Graphics g) {
            super.paintComponent(tmHelper.prepareGraientBackground(g));
            tmHelper.paintComponent(g);
      }
}

And I also extended JMenu and JMenuItem into their respective GradientMenu and GradientMenuItem using the same template from GradientMenuBar.

The code that creates the Menus in my frame is almost the same as JBuilder's designer created for me:

      private GradientMenuBar jMenuBar1 = new GradientMenuBar();
      private GradientMenu jMenuFile = new GradientMenu();
      private GradientMenuItem jMenuFileExit = new GradientMenuItem();
      private GradientMenuItem jMenuFileStart = new GradientMenuItem();
      private GradientMenu jMenuHelp = new GradientMenu();
      private GradientMenuItem jMenuHelpAbout = new GradientMenuItem();

And I added this code to ensure the Gradient of the MenuBar is shared by its children like this:

      GradientPainter gp = jMenuBar1.getGradientPainter();
      jMenuFile.getGradientPainter().setMasterGradient(gp);
      jMenuHelp.getGradientPainter().setMasterGradient(gp);
      jMenuFileStart.getGradientPainter().setMasterGradient(gp);
      jMenuFileExit.getGradientPainter().setMasterGradient(gp);
      jMenuHelpAbout.getGradientPainter().setMasterGradient(gp);

It works for me, unless I run my JAR file completely from Windows with the Windows L&F, if this is not you current problem, my code may help.
If my code does help, I urge you to reconsider the amount of points you've dedicated to this question because it seems a bit low for the amount of work and knowledge that has to go into this, then again, you may already solved everything, in which case, the reward is the code itself ;)

Hope this helps,
Doron
0
 

Author Comment

by:hapciu
ID: 10829219
well thanks a lot for the effort, but i've already solved my problem on my own - unlike you i have  extended the UI classes (BasicMenuBarUI, BasicMenuUI and BasicMenuItemUI) and it works just fine. but as i said, i did that on my own, eventually.
i will give you the points because it doesn't hurt me, but i won't increase them.
0
 
LVL 9

Expert Comment

by:doronb
ID: 10829680
No problem, thanks for the points, I was going to suggest working with the UI classes, and do it myself too :)
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
Suggested Courses

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question