简体   繁体   中英

JButton should change background when pressed works ONLY when pressed and mouse not over button

I am getting into the whole event-based programming of Java, in addition to creating and modifying GUIs in Java and one of the most simple and first things I came across would be to change the background color of a button when hovered-over, pressed, enabled, etc.

Currently, I have this piece of code regarding the button:

public class SampleForm extends JFrame implements ActionListener, ChangeListener{
private JPanel rootPanel;
private JButton fooButton;
private JButton barButton;

public SampleForm() {
    super("Window");
    setContentPane(rootPanel);
    pack();
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setSize(400, 400);
    setVisible(true);
    fooButton.addActionListener(this);
    barButton.addActionListener(this);
    fooButton.addChangeListener(this);
    barButton.addChangeListener(this);
}

public void stateChanged(ChangeEvent e) {
    AbstractButton abs = (AbstractButton) e.getSource();
    ButtonModel model = abs.getModel();

    if (e.getSource() == barButton)
        if (model.isPressed()) {
            barButton.setBackground(new Color(255, 255, 255));
        } else if (model.isRollover()){
            barButton.setBackground(new Color(174, 20, 70));
        } else if (!model.isEnabled()) {
            barButton.setBackground(new Color(0, 0, 0));
        } else {
            barButton.setBackground(new Color(60, 63, 65));
        }

}

public void actionPerformed(ActionEvent event){
    if (event.getSource() == fooButton){
        barButton.setEnabled(true);
    } else {
        barButton.setEnabled(false);
    }
}

I have made the form in IntelliJ, so it handles the whole element adding to the panel, meaning that the form renders out perfectly. When I click the fooButton, barButton is Enabled and gets a dark-grey color. When I hover over it, it gets a reddish color (and it works well so far).

However, when I press the button, the button SHOULD become white, but instead becomes the default high-brightness, cyan color and stays like this. If I keep the button pressed, but move the mouse away from the button (mouse is not hovering over the button), the button becomes white as it should when pressed.

I have tried numerous properties and tried to pinpoint the culprit, but it's obvious that I am missing something. I have made a .gif to show you what I mean:

http://imgur.com/AeppEtF

Excuse my erratic mouse jiggling at beginning and ending :D

Thank you in advance!

Change color to red and you will observe that the problem is not what you think but a matter of look and feel. Background color of JButton is not what you think.

The problem is that Swing uses an MVC model, and that the painting is not made by the JButton but by its associated ButtonUI. This ButtonUI (actually a subclass of) is dependent on the look and feel, so that the button is painted in compliance with the current look and feel.

Try this:

class MyUI extends javax.swing.plaf.basic.BasicButtonUI {
  protected void  paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) {
    super.paintText(g,b,textRect,text);
  }
}

public class SampleForm extends JFrame implements ActionListener, ChangeListener{
  public SampleForm() {
    super("Window");
    fooButton = new JButton("jkljkl");
    fooButton.addActionListener(this);
    fooButton.addChangeListener(this);
    fooButton.addMouseListener(this);
    fooButton.setUI(new MyUI());

you will see that your button will then behave the way you like.

The problem is that "clicking" a button is actually pressing and releasing it. Because of this, the following statement determines what the button looks like after a click:

} else {
    barButton.setBackground(new Color(60, 63, 65));
}

Hopefully there's a workaround!

private boolean isClicked;

public SampleForm() {
    super("Window");
    isClicked = false;
    setContentPane(rootPanel);
    pack();
    // insert the rest of the constructor body here
}

public void stateChanged(ChangeEvent e) {
    AbstractButton abs = (AbstractButton) e.getSource();
    ButtonModel model = abs.getModel();
    if(e.getSource() == barButton)
        if(model.isPressed() && !isClicked) {
            barButton.setBackground(new Color(255, 255, 255));
            isClicked = true;
        } // insert the rest of the chained if-else statements here
}

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