简体   繁体   中英

How to change background an extended JButton in java when mouse over

I am using my class call KButton that extends from JButton bui I add some code that make it more beautiful such as changing the font, set rounded border, change the background using Graphics and Graphics2D. However it is not work when i want to add code to make it change color when move over! my code is here

public class KButton extends JButton implements MouseMotionListener{

    private static final long serialVersionUID = 1L;
    public KButton(){
        setStyle();
    }
    public KButton(String text){        
        super(text);
        this.setText(text);
        setStyle();
        addMouseMotionListener(this);
    }
    public void setStyle(){
        setFont(new Font("San Serif",Font.PLAIN,12));
        setContentAreaFilled(false);
        setBorder(new RoundedBorder(3));
    }
    @Override
    protected void paintComponent(Graphics g){
        Graphics2D g2 = (Graphics2D)g.create();
        g2.setPaint(new GradientPaint(new Point(0, 0), Color.WHITE, new Point(0, getHeight()), Color.LIGHT_GRAY));
        g2.fillRect(0, 0, getWidth(), getHeight());
        g2.dispose();
        super.paintComponent(g);
    }
    @Override
    public void mouseDragged(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void mouseMoved(MouseEvent arg0) {
        Graphics g=this.getGraphics();
        Graphics2D g2 = (Graphics2D)g.create();
        g2.setPaint(new GradientPaint(new Point(0, 0), Color.WHITE, new Point(0, getHeight()), Color.BLUE.brighter()));
        g2.fillRect(0, 0, getWidth(), getHeight());
        g2.dispose();
        super.setText(getText());
        setBorder(new RoundedBorder(3));
        super.paintComponent(g);
    }

}

and it seems not work!

Don't use getGraphics . The approriate place to perform custom painting is within the paintComponent method. getGraphics is a transient reference to the graphics context last used to the paint the component, when the component is repainted, any changes will be overridden by those in the various paintXxx methods.

You should, also, never be calling any of the paintXxx methods yourself (unless you are trying to render the component to an image of course)

Instead, use a state flag to changes the way that paintComponent works and call repaint when you want to update the state.

In your case, there are at least two things that destroying your painting efforts in your mouseMoved method, setText and the mouse movement itself. Both of which will cause a repaint to occur.

Personally, I would use MouseListener#mouseEntered and MouseListener#mouseExited instead and change the state of the button model (to rolled over for example) and then examine that value in the paintComponent method to make my painting decisions

Also, beware that super.paintComponent will attempt to clear the graphics context, preparing for painting and should be called first

Don't do painting in mouseMoved , just set the properties to paint, and then repaint the component . Also, MouseListener provides mouseEntered and mouseExited events, which work better for this use case. :

public class KButton extends JButton {
  private Color bottomBg = Color.LIGHT_GRAY;

  public KButton(String text) {
    super(text);
    addMouseListener(this);
  }

  @Override
  protected void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;
    g2.setPaint(new GradientPaint(new Point(0, 0), Color.WHITE, new Point(0, getHeight()), this.bottomBg));
    g2.fillRect(0, 0, getWidth(), getHeight());
  }

  public void mouseEntered(MouseEvent evt) {
    this.bottomBg = Color.BLUE.brighter();
    this.repaint();
  }

  public void mouseExited(MouseEvent evt) {
    this.bottomBg = Color.LIGHT_GRAY;
    this.repaint();
  }

  // add other MouseListener methods, or use a MouseAdapter 
  // with just those two methods overridden

}

Although @MadProgrammer's advice is true, you can omit all this burden by setting the buttons rollover image:

//In constructor
setRolloverImage(myRolloverImage); 

But I'm not sure this is the exact method name, do some research.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM