鼠标悬停时如何在java中更改后台扩展的JButton

时间:2013-06-26 03:02:28

标签: java image swing jbutton mouselistener

我正在使用我从JButton扩展的类调用KButton我添加了一些代码,使其更加美观,例如更改字体,设置圆角边框,使用Graphics和Graphics2D更改背景。但是当我想要添加代码以使其在移动时改变颜色时它不起作用!我的代码在这里

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);
    }

}

似乎不起作用!

3 个答案:

答案 0 :(得分:1)

请勿使用getGraphics。执行自定义绘画的合适位置在paintComponent方法内。 getGraphics是对最后用于绘制组件的图形上下文的瞬态引用,当重新绘制组件时,任何更改都将被各种paintXxx方法中的更改覆盖。

你也不应该自己调用任何paintXxx方法(除非你试图将组件渲染成图像)

相反,使用状态标志可以更改paintComponent的工作方式,并在您想要更新状态时调用repaint

在您的情况下,至少有两件事会破坏您的mouseMoved方法,setText和鼠标移动本身的绘画工作。这两个都会导致repaint发生。

就个人而言,我会改为使用MouseListener#mouseEnteredMouseListener#mouseExited并更改按钮模型的状态(例如滚动),然后在paintComponent方法中检查该值我的绘画决定

另外,请注意super.paintComponent将尝试清除图形上下文,为绘画做准备并应首先调用

答案 1 :(得分:0)

不要在mouseMoved中绘画,只需设置要绘制的属性,然后重新绘制组件。此外,MouseListener提供mouseEntered和mouseExited事件,这些事件更适合此用例。 :

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

}

答案 2 :(得分:0)

虽然@ MadProgrammer的建议是正确的,但您可以通过设置按钮翻转图像来省略所有这些负担:

//In constructor
setRolloverImage(myRolloverImage); 

但我不确定这是确切的方法名称,做一些研究。