Home > Mobile >  JButton appearance as if it were pressed
JButton appearance as if it were pressed

Time:02-03

In some cases a need my JButton to appear as if it were pressed. This depends on some boolean.
I tried to create my own ButtonModel that overrides the default isPressed() method but in that way the button appears pressed only in case the mouse pointer is on top of it (without pressing a mouse button). I need it to appear pressed also if the mouse is somewhere else.

So far I tried this:

class MyButtonModel extends DefaultButtonModel
{
  private boolean appearPressed;

  @Override
  public boolean isPressed()
  {
    return super.isPressed() || appearPressed;
  }
}

I cannot use a JToggleButton or something similar.
My button derives from another class that implements some additional features and derives itself from JButton.

UPDATE:
I'm running on Windows 10 and use the WindowsClassic Look&Feel.

CodePudding user response:

you also need to override isArmed():

class MyButtonModel extends DefaultButtonModel
{
    private boolean appearPressed = true;

    @Override
    public boolean isPressed()
    {
        return super.isPressed() || appearPressed;
    }

    @Override
    public boolean isArmed() {
        return super.isArmed() || appearPressed;
    }
}

CodePudding user response:

The partial reply was given by @Philipp Li and @camickr. Thank you.
My button model needs to override isArmed() in order to obtain the desired result.

However, once the button is pressed, it doesn't respond anymore.
Digging in the source of DefaultButtonModel, I found this:

public void setPressed(boolean b)
{
  if ((isPressed() == b) || (!isEnabled()))
    return;
  ...
}

This method is invoked by AbstractButton.doClick() in order to notify the various ActionListeners.
In other words, if the overridden method isPressed() returns true because I want to make the button appear pressed, a successive click on that button will be ignored.
A similar thing occurs within DefaultButtonModel.setArmed().

Therefore, I implemented my button model as follows:

class MyButtonModel extends DefaultButtonModel
{
  boolean appearPressed = false;

  private boolean withinSetPressedMethod = false;

  private boolean withinSetArmedMethod = false;

  @Override
  public void setPressed(boolean pressed)
  {
    withinSetPressedMethod = true;
    super.setPressed(pressed);
    withinSetPressedMethod = false;
  }

  @Override
  public void setArmed(boolean armed)
  {
    withinSetArmedMethod = true;
    super.setArmed(armed);
    withinSetArmedMethod = false;
  }

  @Override
  public boolean isPressed()
  {
    if (withinSetPressedMethod)
      return (super.isPressed());
    else
      return (super.isPressed() || appearPressed);
  }
  
  @Override
  public boolean isArmed()
  {
    if (withinSetArmedMethod)
      return (super.isArmed());
    else
      return (super.isArmed() || appearPressed);
  }
  
} // class MyButtonModel
  • Related