1

I'm trying to make a button that toggles a boolean on/off when it is pressed. I am already using a similar format for toggling other modules on/off, and it works perfectly. However, for some reason unbeknown to me, the boolean I am trying to assign the variable to never toggles at all.

Here is the code that creates the boolean:

boolean rainbow = false; 
panels.add(new Panel("Hub", 50, 50, false) {
            public void loadElements() {
                getElements().add(new ElementBoolean("Rainbow", rainbow));
            }
        });

And here is the box class, which gets the boolean variable, and is supposed to toggle it on/off.

private String label;
private boolean property;

public ElementBoolean(String label, boolean property) {
    super(label);
    this.label = label;
    this.property = property;
}

@Override
public void mouseClicked(int mX, int mY, int button)
{
    switch(button) {
        case 0: {
            if(!isSelected(mX, mY)) return;
            this.property = !this.property;

            break;
        }
    }
}

Again, this format works fine for handling other modules, but for toggling the boolean is never assigns 'property' to the boolean 'rainbow' as it is supposed to. Therefore, the boolean 'property' is toggled correctly, however the variable 'rainbow' stays false. I'm sorry if I am missing something extremely simple, I just cannot understand why this isn't working.

No stack trace because it doesn't generate any errors.

3 Answers3

2

The problem is that primitives (e.g. boolean) are passed by value, means that when you are passing rainbow to ElementBoolean's constructor, Java creates a new local variable in stack which is not referenced anyhow with initial rainbow variable. What you actually need is a Mutable (https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/mutable/package-summary.html)
If you don't want to use Apache library you can implement it easily by yourself:

public class Mutable<T> {

  private T value;

  public Mutable(final T value) {
    this.value = value;
  }

  public T get() {
    return this.value;
  }

  public void set(final T value) {
    this.value = value;
  }
}
Sergi
  • 990
  • 5
  • 16
0

I'm not sure that I understand you, everything you posted here seems alright, but I have a feeling you are trying to do something like this:

boolean rainbow = false; 
panels.add(new Panel("Hub", 50, 50, false) {
  public void loadElements() {
    getElements().add(new ElementBoolean("Rainbow", rainbow));
  }
});

//now you click mouse
//and now you expect variable rainbow to be true after mouse clicked
if(rainbow == true)
  doSomething();

Point is you are not changing the variable rainbow, you are changing the variable property in ElementBoolean object instance. What you need to do is (before you try to use rainbow):

rainbow = yourElementBooleanInstance.getProperty()

Ofcourse, since it's private you need to make a getProperty() method returning property value and somehow save the instance of ElementBoolean, because you are not doing this right now (you can also make field property and getProperty() static and then do ElementBoolean.getProperty().

Shadov
  • 5,421
  • 2
  • 19
  • 38
0

See the following two calls:

f(x)
new ElementBoolean("Rainbow", rainbow)

The passed variable (x and rainbow) will in java never be overwritten with another value. You allways pass-by-value. The field property is not an alias of rainbow.

This was an intentional design decision, as you now know:

String s = "happy";
p(s);
// s still will be "happy", not null or whatever
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138