开发者

Accessing non-static objects from anonymous objects in Java

开发者 https://www.devze.com 2023-04-02 14:36 出处:网络
Working with the Google Web Toolkit i have written an application which is based on the Model-View-Controller concept. Now my ClientController class has two objects of the types ClientModel and Client

Working with the Google Web Toolkit i have written an application which is based on the Model-View-Controller concept. Now my ClientController class has two objects of the types ClientModel and ClientView which are declared private and non-static. With an object for asynchronous calls i have written some Remote Procedure Calls which do work, however attaching an anonymous object from the type AsyncCallback<T> makes me a problem, as i can not access the two ClientModel and ClientView objects without writing some nasty final variables in my function like you can see below:

package com.foo.bar;

/**
 * Represents the main handler holding delegates and controlling the contents of
 * the {@link ClientModel} and pushes notifications and message to both the
 * {@link ClientModel} and the {@link ClientView}.
 */
public class ClientController {
    /**
     * Exposes asynchronous functions to call the server component via RPC.
     */
    public static final MyServiceAsync mySvc = GWT.create(myService.class);

    /**
     * Represents the model associated with the {@link ClientController} object.
     */
    private ClientModel theModel = null;
    /**
     * Represents the view associated with the {@link ClientController} object.
     */
    private ClientView theView = null;

    /**
     * Creates a new {@link ClientController} object and instantiates both the
     * {@link ClientModel} and the {@link ClientView}.
     */
    public ClientController() {
        this.theModel = new ClientModel();
        this.theView = new ClientView(this.theModel);
    }

    /* some more code */

    /**
     * Tries to login the specified user and updates the {@link ClientView}
     * object to either an error message or the main interface.
     * 
     * @param user
     *            {@link User} object representing the user to login
     */
    public void loginUser(final User user) {
        ///////////////////////////////////////////////
        // THIS IS UGLY AND I DON'T KNOW HOW TO FIX THIS
        ///////////////////////////////////////////////
        final ClientModel currentModel = this.theModel;

        // Execute the login protocol
        ClientController.mySvc.login(user, new AsyncCallback<Boolean>() {
            /**
             * The request was successfully executed. Returns a boolean value
             * indicating whether the user was logged in.
             * 
             * @param result
             *            true, if the user was logged in; otherwise开发者_StackOverflow社区, false.
             */
            @Override
            public void onSuccess(Boolean result) {
                // The user was successfully logged in and we must both store
                // him in the model and then update the view.
                if (result) {
                    // TODO: Update the view to show the chat itself and save
                    // the current User to the ClientModel.
                    System.out.println("The User " + user.getUsername()
                            + " is now logged in!");
                    // Anonymous object can not access the theModel and theView
                    // objects of ClientController directly ...
                    // drunk, fix later!
                    // UGLY FIX FOR NOW
                    currentModel.setCurrentUser(user);
                } else {
                    // TODO: Unhide the error label of the login form and output
                    // some nice error message.
                    System.out.println("Login failed for User "
                            + user.getUsername() + "!");
                }
            }

            /**
             * The request provoked an error.
             */
            @Override
            public void onFailure(Throwable up) {
                try {
                    throw up; // Ha ha
                } catch (Throwable e) {
                    // Who cares?
                }
            }
        });
    }
}

For now I am using a final pointer to the internal model in loginUser which is hoghlighted two times. Can anyone explain me whether there is a better solution without moving theModel and theView to static members? It is annoying to write such "final wrappers" in every function you access either of the components...


When you create an instance of a non-static inner class, or an instance of an anonymous class, that instance has an implicit binding to the instance of the outer class that created it. You can access members of the outer class from within the inner class using OuterClassName.this.member.

In your case: ClientController.this.theModel


Try and declare your members final, like this:

...

private final ClientModel theModel;

private final ClientView theView;

public ClientController() {
    this.theModel = new ClientModel();
    this.theView = new ClientView(this.theModel);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号