Question

Why do some people prefer to use

.setCommandListener(this)

over

.setCommandListener(new CommandListener(){})

more often? In what case should I use the second one and why? I am assuming it's just a matter of style or is there a particular issue?

Was it helpful?

Solution

If you use "this", you must implement the listener to the class, and then you can access fields of class in the implemented methods of listener.

If you use the second one(new Listener...) then it might be more readable code if you don't need to access many other stuff in your class.

OTHER TIPS

setCommandListener(this) is noticeably easier to read in "toy code". I think that's why I've seen it used in many entry level tutorials, where authors just don't want to get too deep.

It also looks like beginner programmers just blindly copy this anti-pattern from tutorials, without giving it additional thought.

For more complicated code though setCommandListener(new CommandListener(){/*..*/}) was in my experience much easier to maintain and read.

Note also that you can access fields of class in both cases, just latter requires use of Qualified this:

//import javax.microedition.midlet.*;
//import javax.microedition.lcdui.*;

abstract class ListenerTest extends MIDlet {
    protected Display display;

    protected void startApp() {
        display = Display.getDisplay(this);
        Form form = new Form("welcome");
        form.addCommand(new Command("go", Command.OK, 1));
        form.setCommandListener(new CommandListener() {
            public void commandAction(Command c, Displayable d) {
                // qualified this - see JLS 15.8.4
                ListenerTest.this.cmdAction(c, d);
            }
        });
        // display "welcome" screen with "go" command
        display.setCurrent(form);
    }

    protected void pauseApp() { }

    protected void destroyApp(boolean unconditional) {
        notifyDestroyed();
    }

    protected abstract void displayNext();

    private void cmdAction(Command c, Displayable d) {
        // invoke from listener to display next screen
        displayNext();
    }
} // ListenerTest

class NextTest extends ScreenTest {

    protected void displayNext() {
        Form form = new Form("bye-bye");
        form.addCommand(new Command("EXIT", Command.EXIT, 1));
        form.setCommandListener(new CommandListener() {
            public void commandAction(Command c, Displayable d) {
                notifyDestroyed();
            }
        });
        // display "bye-bye" screen with "exit" command
        display.setCurrent(form);
    }
} // NextTest

BTW did I mention that above approach is also safer? It guarantees that the listener you expect for particular screen is exactly the one that you set.

Say, if you do a straightforward rewrite to setCommandListener(this) and run it, you'll notice weird behavior - command "go" will now quit the midlet instead of showing next screen:

    // don't do that
    abstract class ListenerTest extends MIDlet implements CommandListener {
        protected Display display;

        protected void startApp() {
            display = Display.getDisplay(this);
            Form form = new Form("welcome");
            form.addCommand(new Command("go", Command.OK, 1));
            form.setCommandListener(this);
            // display "welcome" screen with "go" command
            display.setCurrent(form);
        }

        protected void pauseApp() { }

        protected void destroyApp(boolean unconditional) {
            notifyDestroyed();
        }

        protected abstract void displayNext();

        public void commandAction(Command c, Displayable d) {
            // invoke from listener... really??? check the subclass
            displayNext();
        }
    } // ListenerTest

    class NextTest extends ScreenTest implements CommandListener {

        protected void displayNext() {
            Form form = new Form("bye-bye");
            form.addCommand(new Command("EXIT", Command.EXIT, 1));
            form.setCommandListener(this);
            // display "bye-bye" screen with "exit" command
            display.setCurrent(form);
        }

        public void commandAction(Command c, Displayable d) {
            // you may not notice but...
            notifyDestroyed();
            // ...this actually overrides superclass implementation
        }
    } // NextTest
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top