my dog learned polymorphism*
The moose likes Swing / AWT / SWT and the fly likes custom repaint on JButton on mouserollover Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "custom repaint on JButton on mouserollover" Watch "custom repaint on JButton on mouserollover" New topic
Author

custom repaint on JButton on mouserollover

Chris Dancy
Ranch Hand

Joined: Feb 14, 2006
Posts: 136
hey i was just looking to do a custom repaint on a button say when the mouse rolls over it. I was looking around and couldent find anything.

sincerely,
Chris Dancy


("Anger is not an emotion, its a symptom of fear.")
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41065
    
  43
You could add a MouseMotionListener to the button, and trigger repainting of the button from the mouseMoved method.


Ping & DNS - my free Android networking tools app
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37926
    
  22
Wouldn't a MouseListener work better, with repainting in one colour on mouseEntered() and repainting in another colour on mouseExited()?
Chris Dancy
Ranch Hand

Joined: Feb 14, 2006
Posts: 136
What i was looking to do was say:

custombutton cb = new custombutton();
cb.addMouseListener(MouseMoved(MouseEvent e){
//do some painting here, but how do I do it without
//being in paintcomponent. i simply wanted to give
//this custom jbutton a different gradient.
}

any help would be great.

sincerely,
Chris Dancy
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41065
    
  43

do some painting here, but how do I do it without being in paintcomponent. i simply wanted to give this custom jbutton a different gradient.

You could set a boolean variable (say, doTheCustomButtonPaintJob) to true, and then call repaint() on the button. Then the Button's paintComponent method just needs to be smart enough to know what it should do depending on the value of the boolean variable. This would be easiest if you make a custom button class that extends JButton.
Chris Dancy
Ranch Hand

Joined: Feb 14, 2006
Posts: 136
yes thats what i was looking for. Thank you.
Chris Dancy
Ranch Hand

Joined: Feb 14, 2006
Posts: 136
So it doesent work when i set the boolean variable and then repaint. Nothing repaints and all buttons stay the same. in the paint component method if boolean gradRepaint is true then its suppose to do custom repaint and if its not true it does its normal repaint. The custom class implements mouseListener and then in the mouseEntered mehthod i trigger the custom rollover repaint. Only it doesent work and i cant figure it out.

sincerely,
Chris Dancy
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37926
    
  22
?

Make sure to check I have got the names of the 5 methods correct.
Chris Dancy
Ranch Hand

Joined: Feb 14, 2006
Posts: 136
this is somewhat what i have with a few things left out for brevity...

class mybutton extends JButton implements MouseMotionListener{
boolean gradientRepaint = false;
public void mouseMoved(MouseEvent e){
gradientRepaint = true;
Chris Dancy
Ranch Hand

Joined: Feb 14, 2006
Posts: 136
this is somewhat what i have with a few things left out for brevity...

class mybutton extends JButton implements MouseMotionListener{
boolean gradientRepaint = false;
public void mouseMoved(MouseEvent e){
gradientRepaint = true;
repaint();
}
public void mouseEntered(MouseEvent e){
gradientRepaint = true;
repaint();
}
public void paintComponent(Graphics g){
if(!gradientRepaint){
// normal drawing button code...which works by the way.
super.paintComponent(g);
}else{
// in here is what i want to happen when mouseEntered is called...
super.paintComponent(g);
}
}

Everything works its just that it doesent repaint when i call it from mouseEntered....and i cant figure out why...any takers?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37926
    
  22
Don't know. I tried this, and it doesn't seem to work as you would like:
Sorry, but I don't seem to be able to help any more.

Anybody else?
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41065
    
  43
Campbell's code is close if you add an "addMouseListener(this);" in the ColouredButton constructor. In addition to setBackground you could also use setForeground, depending on your graphical tastes.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37926
    
  22
Is that all I was missing? %$$$@#>!

I usually avoid addXYZListener(this), but in this case it works beautifully. Thank you, Ulf

I presume you will want something more complicated than setBackground(), but with the addition Ulf suggests, what I quoted will work. I have tried it.
Chris Dancy
Ranch Hand

Joined: Feb 14, 2006
Posts: 136
here is the code in full and maybe you can see what im talking about...


import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
public class RoundJButton extends JButton implements MouseListener{
boolean pressed = false;
boolean gradientRepaint = false;
public RoundJButton(String name){
super(name);
Dimension size = getPreferredSize();
size.width = size.height = Math.max(size.width,size.height);
setPreferredSize(new Dimension(size));
setContentAreaFilled(false);
}
public void mouseClicked(MouseEvent e){
gradientRepaint = true;
this.repaint();
}
public void mousePressed(MouseEvent e){
gradientRepaint = false;
pressed = true;
this.repaint();
}
public void mouseReleased(MouseEvent e){
gradientRepaint = false;
this.repaint();
}
public void mouseEntered(MouseEvent e){
gradientRepaint = true;
this.repaint();
}
public void mouseExited(MouseEvent e){
gradientRepaint = false;
this.repaint();
}
protected void paintBorder(Graphics g){
Graphics2D g2 = (Graphics2D)g;

g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON );
g2.setRenderingHint( RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY );

Color col1 = Color.WHITE;
Color col2 = Color.BLUE;

Stroke s = new BasicStroke(3);
g2.setStroke(s);

Arc2D.Double arc = new Arc2D.Double(1, 1, getSize().width-3, getSize().height-3, 0, 360, Arc2D.CHORD);

Point2D.Double pt1 = new Point2D.Double(0,0);
Point2D.Double pt2 = new Point2D.Double(getSize().width-1, getSize().height-1);
GradientPaint gp = null;

if (pressed || gradientRepaint)
gp = new GradientPaint(pt1, col1, pt2, col2, true);
else
gp = new GradientPaint(pt1, col2, pt2, col1, true);

g2.setPaint(gp);
g2.draw(arc);
}
protected void paintComponent(Graphics g){
if(!gradientRepaint){
int width = getWidth();
int height = getHeight();

Color color2 = Color.WHITE;
Color color1 = Color.BLUE;

GradientPaint paint = new GradientPaint(0, 0, color1, width, height, color2, true);
Graphics2D g2d = (Graphics2D)g;
Paint oldPaint = g2d.getPaint();
g2d.setPaint(paint);

pressed = getModel().isPressed();
Arc2D.Double arc = new Arc2D.Double(0, 0, getSize().width-1, getSize().height-1, 0, 360, Arc2D.CHORD);
g2d.fill(arc);

g2d.setPaint(oldPaint);
super.paintComponent(g2d);
}
else if(gradientRepaint){

int width = getWidth();
int height = getHeight();

Color color2 = Color.WHITE;
Color color1 = Color.red;

GradientPaint paint = new GradientPaint(0, 0, color1, width, height, color2, true);
Graphics2D g2d = (Graphics2D)g;
Paint oldPaint = g2d.getPaint();
g2d.setPaint(paint);

Arc2D.Double arc = new Arc2D.Double(0, 0, getSize().width-1, getSize().height-1, 0, 360, Arc2D.CHORD);
g2d.fill(arc);

g2d.setPaint(oldPaint);
gradientRepaint = false;
super.paintComponent(g2d);
}
}
}

im not sure where its going wrong. The code works so if you plug it in you can see. The button is painted in a white and blue gradient and just for hoohoos until i get it working i wanted it to be painted with a red and white gradient when the mouse moves over...but its not working...
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41065
    
  43
That code is also missing a "addMouseListener(this);" in the constructor.

Part of the problem is that you're calling super.paintComponent at the end of your paintComponennt method. That will effectively paint over (and thus erase) what your code has painted.
Chris Dancy
Ranch Hand

Joined: Feb 14, 2006
Posts: 136
ok that was the problem...i didnt add mouselistener to the actual object, i think i was so focused on doing the drawing that i overlooked the simplicity of simply of it all. Thank you not it works like a charm. Yet i do have a problem with what you said about calling paintComponent. I was always told that if you painting buttons or smaller components then call paintcomponent at the end, but if your painting panels or frames to call it at the beginning.
Im not sure why for either one, but i know it has something to do with repainting the children if you call paintComponent at the end thus negating what you've just painted on the button. I would love to hear another opinion on this issue, cause im not too sure myself.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41065
    
  43
I was always told that if you painting buttons or smaller components then call paintcomponent at the end, but if your painting panels or frames to call it at the beginning.


The Sun Java Tutorial has the following to say about Swing painting:
For components with a UI Delegate, you should pass the Graphics parameter with the line super.paintComponent(g) as the first line of code in your paintComponent override. If you do not, then your component will be responsible for manually painting its background.

and
If your custom component extends JPanel or a more specialized JComponent descendant, then you can paint the background by invoking super.paintComponent before painting the contents of your component.


(That's at http://java.sun.com/docs/books/tutorial/uiswing/painting/summary.html and http://java.sun.com/docs/books/tutorial/uiswing/painting/problems.html).

I've never seen or heard anything about calling it at the end.
[ March 25, 2008: Message edited by: Ulf Dittmer ]
Chris Dancy
Ranch Hand

Joined: Feb 14, 2006
Posts: 136
If i do however call it at the beginning the text does not get repainted, its only if i call it at the end that everything works ok....
Brian Cole
Author
Ranch Hand

Joined: Sep 20, 2005
Posts: 862
I think you guys are working too hard here.

JButton already knows how to repaint itself on rollover,
so I see no reason to mess with the MouseListener stuff.
Just call setRolloverEnabled(true). [Depending on the LnF,
it may already be set to true.]
[ March 31, 2008: Message edited by: Brian Cole ]

bitguru blog
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: custom repaint on JButton on mouserollover
 
Similar Threads
paint
customized jcomponent icon is painting itslef on top of menu
naming.sar and security.sar
repainting in shapes other than square
Repainting Swing Components