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.
TextBox txt = new TextBox(){
public void onLoad(){
final TextBox finalThis = this;
this.addFocusHandler(new FocusHandler(){
finalThis.doSomething();
);
}
};
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);
});
}
};
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");
}
});
}
};
}
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();
}
}
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.
Related
I'm just looking some another efficient way to pass an object parameter to method.
So I have some method like this:
private void dashboardMenu() {
Dashboard dashboard = new Dashboard();
body.removeAll();
body.add(dashboard);
dashboard.setSize(body.getWidth(), body.getHeight());
dashboard.setVisible(true);
}
private void dataMenu() {
Data data = new Data();
body.removeAll();
body.add(data);
data.setSize(body.getWidth(), body.getHeight());
data.setVisible(true);
}
And I want an efficient method to call between this two method with object parameter (dashboard = new Dashboard(), and data = new Data()).
What I think it should be like this for example:
private void dasboardMenu() {
navigateMenu(Type object);
}
private void dataMenu() {
navigateMenu(Type object);
}
private void navigateMenu(Type object) {
object menu = new object();
body.removeAll();
body.add(menu);
menu.setSize(body.getWidth(), body.getHeight());
menu.setVisible(true);
}
Is it possible to do that?
Please give me an example. I don't even know what keyword should I do.
How about this (assuming your Dashboard and Data are Swing Components)?
private void dashboardMenu() {
navigateMenu(new Dashboard());
}
private void dataMenu() {
navigateMenu(new Data());
}
private void navigateMenu(JComponent c) {
body.removeAll();
body.add(c);
c.setSize(body.getWidth(), body.getHeight());
c.setVisible(true);
}
How to pass outer anon class ref to a method in an inner anon class in Java?
I have a method that makes async call to a server - sendCall(some_args, callback). The callback is represented by anonymous class (let's name it OuterAnon) and contains a method for failure case. Inside this method a message box is created and sendCall() is called each time OK button is pressed. So I need to pass OuterAnon to the method again.
Here is a code to demonstrate what I mean:
private void sendCall(MyData data, OuterAnon<Boolean> callback){/*...*/}
private void myCall(final MyData data) {
sendCall(data, new OuterAnon<Boolean>() {
public void onFailure(Throwable throwable) {
final OuterAnon<Boolean> callback = this; //how to avoid this?
MessageBox.show(throwable.getMessage(), new MessageListener() {
public void process(MessageBox.OnClick action) {
if (action == MessageBox.OnClick.OK) {
sendCall(new MyData("resend?"), callback);
}
}
});
}
}
});
}
As you noticed, I take a ref for callback here:
final OuterAnon<Boolean> callback = this;
and use it here:
sendCall(new MyData("resend?"), callback);
But I want to avoid ref creation and pass callback like:
sendCall(new MyData("resend?"), this); //at the moment we point to MessageListener instead of OuterAnon.
Is there any way to do it in Java?
It's hard for us to fix since you've only shown incomplete code with classes that aren't supplied, so I don't know if this example is syntactically correct. That being said, a refactoring like this may suit your needs:
private void myCall(final MyData data)
{
sendCall(data, new OuterAnon<Boolean>()
{
public void onFailure(Throwable throwable)
{
showErrorMessage(throwable);
}
});
}
private void showErrorMessage(Throwable throwable)
{
MessageBox.show(throwable.getMessage(), new MessageListener()
{
public void process(MessageBox.OnClick action)
{
if (action == MessageBox.OnClick.OK)
{
sendCall(new MyData("resend?"));
}
}
});
}
private void sendCall(MyData data)
{
sendCall(data, this);
}
In general, I think it's a usually good idea to abstract code out of anon inner classes and into their own method on the enclosing class. It's now testable, reusable, and more readable, IMO.
If you really need to specify the onFailure inside the inner class the way you showed the code, and if you need to use that specific reference for callback, and you need to code this way...
Let's answer the question: no.
In my attempts, I've achieved 3 ways to access the anon-inner-least instance inside the anon-inner-most instance, but I think that none satisfies what you expect.
In that case, the anon-inner-most doesn't have a reference to the anon-inner-least: as you said, the this now points to the anon-inner-least.
Also, I tried to search at the java specification, but couldn't find exactly the answer to the question - if someone find the answer there, please contribute.
My try:
import java.util.ArrayList;
import java.util.LinkedList;
public abstract class AnonTest {
public static void main(String[] args) {
new ArrayList<Object>() {
private static final long serialVersionUID = -5986194903357006553L;
{
// initialize inner anon class
add("1");
}
// Way 1
private Object thisReference1 = this;
// Way 2
private Object getThisReference2() {
return this;
}
#Override
public boolean equals(Object obj) {
// Way 3
final Object thisReference3 = this;
new LinkedList<Object>() {
private static final long serialVersionUID = 900418265794508265L;
{
// initialize inner inner anon class
add("2");
}
#Override
public boolean equals(Object innerObj) {
// achieving the instance
System.out.println(thisReference1);
System.out.println(getThisReference2());
System.out.println(thisReference3);
System.out.println(this);
System.out.println();
// achieving the class
System.out.println(thisReference1.getClass());
System.out.println(getThisReference2().getClass());
System.out.println(thisReference3.getClass());
System.out.println(this.getClass());
System.out.println(this.getClass().getEnclosingClass());
return super.equals(innerObj);
}
}.equals("");
return super.equals(obj);
}
}.equals("");
}
}
I'm bit confused. I have the following:
public static String showInputDialog() {
Form frm = new Form();
final Command cmd = new Command("Ok");
final TextField txt = new TextField("Enter the text", null, 1024, 0);
frm.addCommand(cmd);
frm.append(txt);
frm.setCommandListener(new CommandListener() {
public void commandAction(Command c, Displayable d) {
if (c == cmd) {
return txt.getString(); // Error !!
} else {
return null; // Error !!
}
}
});
}
As you can see, I want to return the input dialog string, while the anonymous class method should return void. How can I resolve this problem?
This does not work as you expected.
I see there are already some solutions, but I feel a bit more discussion about what is actually going on might be helpful.
When you call the frm.setCommandListener(new CommandListener() { ... }) the code presents the user with a dialog where she can type in some text and submit, but the code does not stop and wait until the user finishes.
Instead the code continues to execute - without yielding the result. Only after the user finished typing and submits, you get called back to process the result - which might happen much later, or not at all.
I guess you have some code calling this method like:
public void someMethod(int foo, String bar) {
[...]
String result = MyInputForm.showInputDialog();
// do something with the result
System.out.println("hey, got a result "+ result);
[...]
}
Instead you need to reorganize this. First write a helper class handling the result:
public static class MyCallBack {
public MyCallBack(... /* here pass in what you need to process the result*/) {
... remember necessary stuff in instance variables
}
public void processResult(String result) {
// do something with the result
System.out.println("hey, got a result "+ result);
[...]
}
}
then the calling side does just:
public void someMethod(int foo, String bar) {
[...]
MyInputForm.showInputDialog( new MyCallBack(... here pass in stuff ...) );
[...]
}
and the actual code has to be changed to:
public static String showInputDialog(final MyCallBack callback) {
Form frm = new Form();
final Command cmd = new Command("Ok");
final TextField txt = new TextField("Enter the text", null, 1024, 0);
frm.addCommand(cmd);
frm.append(txt);
frm.setCommandListener(new CommandListener() {
public void commandAction(Command c, Displayable d) {
if (c == cmd) {
return callback.processResult(txt.getString());
} else {
return; // or just omit the else part
}
}
});
}
Two issues:
this way of programming feels pretty backwards, but it is really the way it works.
what feels not right is that I need to define a second helper class aside of the CommandListener. That is really not good style. I hope it can be improved, but as I do not see the complete code (which would be too much information anyway), I have to leave it to you to improve the code and get rid of the clutter. While I feel you want to have a modular, reusable input dialog helper, this might not be the best approach; better define the Form,TextField and Command directly where you need the result and get that running. Make it reusable in a second step after you get it running.
You don't need to return it if you instead do something with the String or store it somewhere, for example:
static String result;
public String commandAction(Command c, Displayable d) {
if (c == cmd) {
result = txt.getString();
} else {
result = null;
}
}
Although you'll have threading issues to deal with.
Given that CommandListener is fixed, 2 possible options are
Use a class member variable in the outer class & assign to that variable instead
private static String myText;
...
public static String showInputDialog() {
...
frm.setCommandListener(new CommandListener() {
public void commandAction(Command c, Displayable d) {
if (c == cmd) {
myText = txt.getString();
} else {
myText = null;
}
}
});
}
or Create a concrete implementation of your CommandListener and set the return value as a property of the new implementation
I would have a look at making the method/variable in this snippet non-static...
You cant return the string because you dont know when the listener will be called.
You can do something with it once you have the string though.
public static void showInputDialog() {
StringHandler sh = new StringHandler();
frm.setCommandListener(new CommandListener() {
public void commandAction(Command c, Displayable d) {
if (c == cmd) {
sh.handle(txt.getString());
} else {
sh.handle(null);
}
}
});}
public class StringHandler {
public void handle(String s){
// Do something with that string.
}
}
The dialogue and the array displays just fine, I just want to be able to set the static variable from the originating class within the onClick that is in a method that is in a different class. All of the try, catch and
<?> were things that I put in at the insistence of the compiler:
public class Setter
{
public void myList(Context context, Class<?> thisclass, int arrayid, String choice)
{
return new AlertDialog.Builder(context)
.setItems(arrayid, new OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
setChoice(thisclass, context, arrayid, which, choice);
}
})
.create();
}
public void setChoice(Class<?> thisclass, Context context, int arrayid, int which, String choice)
{
String[] array = context.getResources().getStringArray(arrayid);
try
{
Field f = thisclass.getDeclaredField(choice);
f.set(null, array[which]);
}
catch (SecurityException e)
{
e.printStackTrace();
}
catch (NoSuchFieldException e)
{
e.printStackTrace();
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
}
}
public class ClassA extends Activity
{
static String stringa;
Setter setted = new Setter();
...
public void onCreate()
{
super.onCreate();
...
AlertDialog thinga = setted.myList(this, getclass(), R.array.thinga, stringa).show();
...
}
}
When I select an item from the list, I get this from debugger:
ClassCache.findFieldByName(Field[], String) line: 438
Class.getDeclaredField(String) line: 666
Setter.setChoice(Class, Context, int, int, String) line: 45 // the line with the Field
I think I'm passing it the class wrong but this is a bit out of my current depth.
I have a number of different classes each with their own static Strings. I am passing the method below the name of the String (in choice) and the context of what I had hoped was the original class that called a method that called a method that led to the code below. I was hoping I could call context.choice = something and the machine would read that as ClassA.stringa = something; how do I do that?
Briefly, I want to have a list of items that the user can choose from be the content of a dialogue, and have their selection be saved and accessible to the class that called for the creation of the dialogue. Perhaps I'm going about this all wrong but I got tired of dealing with other 'kludges' involving using spinners to do the same thing.
Because onClick can't have non-final objects declared elsewhere (at least that is my understanding) I thought maybe I could get around that by calling to another method, setChoice that would store the value of whatever was chosen. I would definitively say this is a kludge and would love to be shown the light as to how you are supposed to deal with these things.
Java does not have closures, but you can get close with anonymous inner classes.
String output;
public void onCreate() {
Setter.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
output = "selected";
}
});
}
See also this swing tutorial: http://download.oracle.com/javase/tutorial/uiswing/events/actionlistener.html
Edit:
In spirit of your example, this should look like this:
public class Setter
{
public void setChoice(IsetString setter, String something)
{
setter.setString(something);
}
}
class ClassA extends Activity implements setString
{
static String stringa;
string polka = "dots";
Setter setted = new Setter();
...
public void onCreate()
{
super.onCreate();
...
setted.setChoice(new IsetString() {
#Override
public void setString(String s) {
stringa = s;
}
}, polka);
...
}
}
interface IsetString {
void setString(String s);
}
The short answer - use the Reflection API.
The long answer - you'll need to obtain access to the Fields of the desired Context Class. Once you gain access to the Field instances, you can set their values using the set() method; the API call is a bit tricky in that you'll need to pass in the object reference (the context object and not the context class) whose field you wish to modify.
It is necessary that your Context, choice and something parameters to the method, contain the necessary information to make this operation as simple as possible. In other words, the Context class might have to contain the actual Class object (or provides a way to get one) that contains the field.
You can use reflection for that. Suppose you context is class itself
public void setChoice(Class<?> context, String choice, String something)
{
try {
Field f = context.getDeclaredField(choice);
f.set(null, something);
} catch (....) {
}
}
Add proper exception handling
Note that first argument to set is null. That is only valid for static methods. So you may want to check that method is static using f.getModifiers().
I want to remove a GWT event handler the first time I receive an event. I also want to avoid polluting my class with tracking registration objects that aren't really necessary. I currently have it coded as:
final HandlerRegistration[] registrationRef = new HandlerRegistration[1];
registrationRef[0] = dialog.addFooHandler(new FooHandler()
{
public void onFoo(FooEvent event)
{
HandlerRegistration removeMe = registrationRef[0];
if(removeMe != null)
{
removeMe.removeHandler();
}
// do stuff here
}
});
but the use of registrationRef makes the code less readable. Is there a better way to do this without adding variables to my class?
I'd just make the HandlerRegistration object a field of the enclosing class, that way you won't be bothered by the compiler and it's more "elegant" than shuffling arrays and stuff:
public class TestWidget extends Composite {
//...
HandlerRegistration handler;
public TestWidget() {
// ...
handler = button.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
// ...
handler.removeHandler();
}
});
}
}