Как изменить фон расширенного JButton в java при наведении курсора мыши

Я использую свой вызов класса KButton, который расширяет JButton. Я добавляю некоторый код, который делает его более красивым, например, изменение шрифта, установка закругленной границы, изменение фона с помощью 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);
    }

}

и вроде не работает!


person Sopheakdey Moeun    schedule 26.06.2013    source источник
comment
Вы можете изучить возможность использования пользовательского PLAF.   -  person Andrew Thompson    schedule 26.06.2013


Ответы (3)


Хотя совет @MadProgrammer верен, вы можете опустить все это бремя, установив изображение прокрутки кнопок:

//In constructor
setRolloverImage(myRolloverImage); 

Но я не уверен, что это точное название метода, проведите небольшое исследование.

person Mordechai    schedule 26.06.2013

Не используйте getGraphics. Соответствующее место для выполнения пользовательского рисования находится в методе paintComponent. getGraphics — это временная ссылка на графический контекст, последний раз использовавшийся для рисования компонента. Когда компонент перерисовывается, любые изменения будут переопределены изменениями в различных методах paintXxx.

Вы также никогда не должны вызывать какой-либо из методов paintXxx самостоятельно (если, конечно, вы не пытаетесь визуализировать компонент в изображение)

Вместо этого используйте флаг состояния, чтобы изменить способ работы paintComponent, и вызовите repaint, когда вы хотите обновить состояние.

В вашем случае есть как минимум две вещи, которые разрушают ваши усилия по рисованию в вашем методе mouseMoved, setText и самом движении мыши. И то, и другое приведет к возникновению repaint.

Лично я бы использовал вместо этого MouseListener#mouseEntered и MouseListener#mouseExited и изменил состояние модели кнопки (например, на перевернутую), а затем проверил это значение в методе paintComponent, чтобы принять решение о рисовании.

Кроме того, имейте в виду, что super.paintComponent попытается очистить графический контекст, готовясь к рисованию, и его следует вызывать первым.

person MadProgrammer    schedule 26.06.2013

Не рисуйте в 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

}
person Ben Taitelbaum    schedule 26.06.2013