Search code examples
javaooprefactoringencapsulation

How to refactor inner class MouseAdapter?


Suppose I have a file like this:

import javax.swing.JPanel;
import java.awt.event.MouseAdapter;
public class Foo extends JPanel
{
    private int m;
    private int n;
    private int o;

    public Foo()
    {
        this.addMouseListener(new Bar());
    }

    class Bar extends MouseAdapter
    {
        // ...
        // methods here access and modify values of the private
        // instance variables.
        // ...
    }
}

Obviously I can add simple accessors and mutators to Foo but that gets tedious fast and completely breaks encapsulation. How can I refactor this inner class while keeping damage to encapsulation to a minimum?


Solution

  • If these classes seem too big, then you should split them. The first step in splitting them would be to stop relying on private instance variables of the outer class. You could, as you say, add public getters and setters, but better would be to have Foo implement a public interface of Bar, and have Bar simply talk to that interface. And initialize each Bar with self.

    public class Bar extends MouseAdapter {
        public interface Caller {
            void thingClicked();
            ...
        }
    }
    
    public class Foo extends JPanel implements Bar.Caller {
        ...
    }
    

    So where now in Bar you have something like:

    public void mouseUp() {
       m = m + 1;
       n = 0
    }
    

    you would now have

    public void mouseUp() {
       caller.thingClicked();
    }
    

    and, in Foo:

    public void thingClicked() {
       m = m + 1;
       n = 0
    }
    

    It's hard to make this clear without more specifics, but basically your outer class is responding to messages, and the mouse listener is only responsible for delivering those messages, not for what happens in response to them. In the examples above it looks like this is more code than what you already have, but I suspect you'll find that slicing it out in this way ultimately leads to less code - and certainly code which is easier to test and reuse.