JButton appearance as if it were pressed - java

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.

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

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

Is there a way to detect button click in another method?

Like
#FXML
void start() {
// for game loop
while(!winning) {
if (attack.clicked()) attack();
else if (defend.clicked()) defend();
}
}
Can it possible to do this? Thanks.
You can assisgn true or false to a flag when when button click(at the button's click handler method). Your sintax may be different at click handler, but your code like this.
private boolean isAttackButtonClicked = false;
public void attackButtonclickHandler(ClickEvent e){
...
isAttackButtonClicked = true;
...
}

BooleanBinding and TimeLine

I've got a BooleanBinding, which looks like this:
public void initQueue(ObservableList<Player> players) {
queueIsFree = new BooleanBinding() {
{
players.forEach(
player -> bind(player.getRobot().animatingProperty));
}
#Override
protected boolean computeValue() {
Boolean bool = true;
for (Player p : players) {
if (p.getRobot().animatingProperty.get() == true) {
bool = false;
break;
}
}
return bool;
}
};
}
It is supposed to be true, when all of the animatingProperties of the Robots are false. As soon as one of them changes, this changeListener is called:
change = new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> arg0,
Boolean oldValue, Boolean newValue) {
if (newValue.equals(true)) {
if (list.size() > 0) {
// plays the next animation, which, when finished, sets the animatingProperty back to false
nextAnimation();
} else {
stopQueue();
}
}
}
};
Problem: the valueChangedEvent fires so often, that i get a stackOverFlowError.
In order to animate, i use a TimeLine and an AnimationTimer, i suppose that this is the problem, yet i don't know how to solve it.
Edit: I know now, that the Problem is, that TimeLines are asynchronous, meaning, that they start and then the next line of code is executed, which means, that the booleanBinding, that i've created is useless.
I'll have to think of another way to play my animations one after another.

Swing to JavaFX - equivalent of overriding a button's isEnabled() method?

In Swing we can do something like
JButton button = new JButton("button") {
public boolean isEnabled() {
return ...condition...;
}
};
Since isDisable() / isDisabled() of a JavaFX Button is declared final - what is the equivalent for enabling or disabling a JavaFX button conditionally?
Express your condition as an ObservableValue<Boolean>, and do
button.disableProperty().bind(condition);
For example, if you wanted to disable the button when a text field was empty, you could do
button.disableProperty().bind(Bindings.isEmpty(textField.textProperty()));
or, if you are still using JavaFX 2.2,
button.disableProperty().bind(new BooleanBinding() {
{ bind(textField.textProperty()); }
#Override
public boolean computeValue() {
return textField.getText().isEmpty() ;
}
});

MouseListener and KeyListener used at the same time

How do I use MouseListener and KeyListener at the same time?
For example, how to do something like this
public void keyPressed( KeyEvent e){
// If the mouse button is clicked while any key is held down, print the key
}
Use a boolean value for whether a mouse button is held down, and then update that variable in a MouseListener.
boolean buttonDown = false;
public class ExampleListener implements MouseListener {
public void mousePressed(MouseEvent e) {
buttonDown = true;
}
public void mouseReleased(MouseEvent e) {
buttonDown = false;
}
//Other implemented methods unimportant to this post...
}
Then, in your KeyListener class, just test the buttonDown variable.
Try creating a boolean isKeyPressed. In keyPressed, set it to true and in keyReleased set it to false. Then, when the mouse is clicked, first check if isKeyPressed is true.
You could try checking the state of the KeyEvent modifiers, for example...
addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
int mods = e.getModifiers();
System.out.println(mods);
if ((mods & KeyEvent.BUTTON1_MASK) != 0) {
System.out.println("Button1 down");
}
}
});
I should also point out, you can do...
int ext = e.getModifiersEx();
if ((ext & KeyEvent.BUTTON1_DOWN_MASK) != 0) {
System.out.println("Button1_down_mask");
}
Which, as I've just discovered, produces results for other mouse buttons...

Libgdx override keyDown using InputMultiplexer in Screen

I have a screen and have created a new multiplexer and set an input processor.
How can I override keyDown on my screen?
public class Screen implements Screen, TextInputListener
{
...stuff...
public Screen(Game game)
{
multiplexer = new InputMultiplexer();
multiplexer.addProcessor(mySystem);
multiplexer.addProcessor(aStage);
Gdx.input.setInputProcessor(multiplexer);
}
...more stuff....
}
Thanks
To override KeyDown you need to implement InputProcessor.
For example if you want to override the Android Back button and the Backspace button on PC you can use a class like this.
public class ScreenInputHandler implements InputProcessor {
#Override
public boolean keyDown(int keycode) {
if(keycode == Keys.BACK || keycode == Keys.BACKSPACE){
...code here
}
return false;
}
}
Remember add the input handler to your InputMultiplexer.
This is how I ended up solving it:
InputProcessor backProcessor = new InputAdapter()
{
#Override
public boolean keyDown(int keycode)
{
//do stuff
return false;
}
};
multiplexer.addProcessor(backProcessor);

Categories