3

I have code like this:

TextBox txt = new TextBox(){
  public void onLoad(){
    this.addFocusHandler(new FocusHandler(){
      //some codes here
      //if I use "this" keyword, it refers to the handler, but how can I get a reference to the textbox?
    });
  }
};

Question is embedded in the position.


Edit:

In respect to the answers, the creation of a pre-defined reference works for this situation, but this apparently lost (or at least reduce) the benefits of anonymous object/function.

I hope to find a way without creating a new reference. Rather just to get the reference from that scope.


After all the answers, here is a conclusion:

  • Reflection does not work in GWT. (at least I did not succeed) obj.getClass() works, but others like getMethods() or getEnclosingClass() don't work.
  • The way to get a reference can either be declaring a reference in the right scope, or get a higher level object reference and reference downwards. I prefer the latter simply because you don't need to create a new variable.
SwiftMango
  • 15,092
  • 13
  • 71
  • 136
  • You probably shouldn't extend TextBox in this way just to addFocusHandler. If your concern is _readability_, then use an [anonymous code block](http://stackoverflow.com/questions/1563030/anonymous-code-blocks-in-java) or refactor into a method to construct the TextBox and add a focus handler to it. – Thomas Broyer Sep 20 '12 at 16:14

5 Answers5

3
TextBox txt = new TextBox(){
    public void onLoad(){
        final TextBox finalThis = this;
        this.addFocusHandler(new FocusHandler(){
             finalThis.doSomething();
        );
    }
};
Gilberto Torrezan
  • 5,113
  • 4
  • 31
  • 50
  • 1
    This looks ok but it is not actually pointing to the right instance. I tried this methods and called a member function, but it cannot find that function. – SwiftMango Sep 20 '12 at 17:10
  • First one is still not working. It gives error saying no instance of given class is in scope. – SwiftMango Sep 20 '12 at 17:24
  • 1
    Yeah I saw some other examples with that method, but it seems like only be working when the outter class is not an anonymous class. I am assuming that if it is anonymous object hierarchy, it would not work. – SwiftMango Sep 20 '12 at 17:29
  • Looks like this doesn't compile. – John Ericksen Sep 20 '12 at 18:45
  • @johncart Yeap, FocusHandler needs a method. It is just an example, following the code from the question. – Gilberto Torrezan Sep 20 '12 at 20:51
2

The enclosing instance of a non-static inner class (anonymous or named) in Java is available as ClassName.this, i.e.

TextBox txt = new TextBox(){
  public void onLoad(){
    this.addFocusHandler(new FocusHandler(){
      doSomethingCleverWith(TextBox.this);
    });
  }
};
Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
1

This has worked for me in the past. It works in client side js too. Here is a reference to more detail What is the difference between Class.this and this in Java

public class FOO {

    TextBox txt = new TextBox(){
          public void onLoad(){
            this.addFocusHandler(new FocusHandler(){

                @Override
                public void onFocus(FocusEvent event) {
                    FOO.this.txt.setHeight("100px");
                }
            });
          }
        };


}
Community
  • 1
  • 1
Chris Hinshaw
  • 6,967
  • 2
  • 39
  • 65
0

This may work for you:

TextBox txt = new TextBox(){
    public void onLoad(){
        final TextBox ref = this;
        this.addFocusHandler(new FocusHandler(){

            public void doSomething(){ 
                //some codes
                ref.execute();
            }
        });
    }
};

But I prefer to migrate inner classes to named classes:

public class Test {

    public void demo(){
        TextBox txt = new TextBox(){
            public void onLoad(){
                this.addFocusHandler(new DemoFocusHandler(this));
            }
        };
    }
}

External FocusHandler:

public class DemoFocusHandler extends FocusHandler {

    private TextBox textBox;

    public DemoFocusHandler(TextBox textBox){
        this.textBox = textBox;
    }

    public void doSomething(){ 
        //some codes
        textBox.execute();
    }
}
John Ericksen
  • 10,995
  • 4
  • 45
  • 75
0

If gwt supported reflection you could do something along the lines of this:

final TextBox txt = new TextBox() {
   public void onLoad() {

      final Object finalThis  = this;

      this.addFocusHandler(new FocusHandler() {

         @Override
         public void onFocus(FocusEvent event) {
           try {
            Method method= finalThis.getClass().getMethod("getVisibleLength");
            method.invoke(finalThis);
           } catch (Exception e) {
            e.printStackTrace();
           } 
        }
    });
  }
};

Without reflection the existing answers are you best bet. There are two gwt reflection projects gwt reflection and gwt-preprocessor both are in beta and I have not tried them.

Rebzie
  • 310
  • 1
  • 3
  • 9