Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

How to Set dual color as the background color of JLabel?  RSS feed

 
SunilK Chauhan
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dear Friends,

I want to Show Jlabel background in dual colors as first color shown at the top of the jlabel and the second one at the bottom of jlabel in Swing Application.

but i didn't know how to set it to make it possible as we can make it in web page using html design?
Thanks and regards,
Sunil
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi SunilK,

an easy way is to create a subclass of JLabel (or if you only need one, just make an anonymous version),
and override 'paintComponent(Graphics g)'. By getting the width and the height, it is then quite
easy to draw the two colours. Don't forget to do 'label.setOpaque(true)'.
 
Campbell Ritchie
Sheriff
Posts: 53750
127
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can also set gradients on the colours, so the top colour merges into the bottom colour. Look at this Java™ Tutorials section.
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is possible as well, to get only two colors, you need to specify
the starting color and the intermediate color to be the same, and
also for the second color.

But more important: I must correct myself. The way I described it
is not correct. If you create such a label with text, then the two
colors will overdraw the text (and, I presume, a possible icon
as well). I just tried it out and saw this, to my dismay.

Here is an example that does work:
 
Brian Cole
Author
Ranch Hand
Posts: 935
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is a minor quibble, but this SpecialJLabel class should either:
1) Respect the opaque property, and only make those fillRect() calls when it is true [could also call setOpaque(true) in the constructor]
2) Override isOpaque() to always return true.

 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You could just as well make the colors more or less transparent.
Unless something could go very wrong, I wouldn't make it any
more complex than this.
 
Brian Cole
Author
Ranch Hand
Posts: 935
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The problem is the class, as written, will report that it's transparent even though it doesn't behave like it's transparent. Granted, that's less of a problem then if it were the other way around. And in many situations it's not a problem at all. I did say it was a minor quibble.
 
Rob Camick
Ranch Hand
Posts: 2753
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You could just as well make the colors more or less transparent.


No you can't as you will have painting artifacts as Swing does not handle transparency properly.

See Backgrounds With Transparency for more information.

Another approach might be to use the Background Panel for the gradient and then just add the label to the panel. This way the panel paints the background and the label can still remain non-opaque and you don't need custom painting every time you need a gradient.
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Camick wrote:
You could just as well make the colors more or less transparent.


No you can't as you will have painting artifacts as Swing does not handle transparency properly.

I don't quite follow you here. My reply was to Brian's remark to set the opacity to true.
(@Brian: thans for bringing the subject up. I had not thought of opacity questions at all!).

Here is the program I used to see what happened. The second JLabel is a normal one,
with opacity set to true and with semi-transparant background, to see if I notice some of the
artifacts in your article. I see none, but correct me if I'm wrong.

(I also used a LinearGradientPaint, btw, never used it before).

 
Rob Camick
Ranch Hand
Posts: 2753
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Piet

I was concerned with your statement to "just as well make the color more or less transparent".

Maybe I misinterpreted that statement but I just wanted to point out there is the potential for painting artifacts anytime you use transparent colors (on an opaque component).

Your original code works because when Swing encounters a non-opaque component it will search for a parent component that is opaque and paint that component first so the transparent color is painted properly. So effectively painting is done twice which is not very efficient.

As Brian pointed out, your custom component is doing all the painting so it should be opaque to prevent the painting from being done twice and to follows the Swing painting conventions.

However, if you make the custom component opaque AND then make your gradient colors transparent, then you will have painting problems.

This case can be demonstrated by your usage of the normal label. However your Timer code is invoking repaint on the panel and you don't see any problems as the panel background is painted first.

If you change your code to:



you will see the painting artifacts as each transparent color is painted on top of one another until it essentially becomes opaque.

I was attempting to clarify that you should not use opaque and a transparent background on a component (as there is the potential for painting artifacts depending on how the component is used).
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Rob, I see it indeed.

Hmm.. as I replied to Brian, letting this special-thing being
non-opaque gives no problems, at the cost of some inefficiency.

I solved that last item by introducing a variable
'boolean reportNotOpaque', that steers the overriden
method 'isOpaque'

and using this in the paintComponent method:

Well, it turned out to be more involved than I first thought.
A JPanel encapsulating the label is indeed easier, but not half
as much fun
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!