Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Leaking this in constructor - where to properly add listeners and other methods requiring "this"

Tags:

java

swing

I have a class that extends JPanel. In its constructor I'm passing this to other methods, mainly to add the jpanel object as a listener to containers/controls within the jpanel (but also other objects). Since Netbeans shows a leaking this in constructor warning for those calls I've put them in an other method that is called from the constructor.

before:

class Foo ... {
    public Foo() {
      initComponents();
      tabX.addChangeListener(this); // <- netbeans complains here
    }

after:

class Foo ... {
    public Foo() {
      initComponents();
      initListeners();
    }

    protected void initListeners() {
      tabX.addChangeListener(this);
    }

That gets rid of the symptom. But I doubt it fixes the reason why netbeans shows the warning.
Where is the proper place to do this kind of initialization in a JPanel-derived class?

like image 468
chendral Avatar asked Mar 19 '12 16:03

chendral


1 Answers

I wonder if there's a bigger issue at play here -- that of asking your class to do too much. A class should have one main purpose, and a view should be responsible for view and that's it. To have it do model or control functions and you lose cohesion, may increase coupling and risk creating god objects that are difficult if not impossible to debug or extend. So to put it bluntly, your GUI or view classes should not also be listener classes. In other words, there is no good reason and a lot of bad reasons for a GUI class to also implement a listener interface.

The best solution: don't have your GUI classes implement listeners. Instead either use anonymous inner classes, or private inner classes, or if complex enough or you anticipate extending and/or modifying your code in the future, stand alone listener classes.

like image 132
Hovercraft Full Of Eels Avatar answered Sep 23 '22 18:09

Hovercraft Full Of Eels