Leak of this in the constructor - where to properly add listeners and other methods requiring "this"

I have a class that extends JPanel. In my constructor, I pass this other methods, mainly to add a jpanel object as a listener to containers / controls in jpanel (but also other objects). Since Netbeans shows a warning leaking this in constructor for these calls, I put them in another 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); } 

This will relieve the symptom. But I doubt that he is establishing the reason netbeans is showing a warning.
Where is the appropriate place to initialize this kind in the JPanel class?

+6
source share
3 answers

I wonder if there is a big problem here - asking your class to do too much. The class should have one main goal, and the view should be responsible for viewing this too. So that he executes a model or controls functions, and you lose cohesion , coupling may increase and risk creating god objects that are difficult, if not impossible, to debug or extend. Therefore, frankly, your GUI or presentation classes should also not be listener classes. In other words, there is no good reason and no small reason for the GUI class to also implement the listener interface.

Best solution: don't use GUI classes to listen. Instead, use either anonymous inner classes, or private inner classes, or quite complex ones, or you expect to expand and / or change the code in the future, separate listener classes.

+2
source

I assume that you added the JPanel extension to another component (for example, JFrame , JApplet , another JPanel , etc.). You mentioned that you have a mixture between the need to add a panel to the subcomponents inside this panel and the โ€œother objectsโ€ that the panels need to listen to. It would probably be better to add a panel to these "other objects" next to where you add the JPanel extension to its spanning JFrame or other parent component outside the definition of your extension class.

However, for the subcomponents of the panel that your panel should listen to, I think that everything you do is fine if these subcomponents are not visible to objects outside of your JPanel extension class definition. A warning simply indicates that what you are doing may be unsafe, but ultimately, when your panel receives garbage collection, like all subcomponents that it owns, including any listener lists, they support this point back to the JPanel extension. Because of this, I think that calling add*Listener(this) using the private method of your JPanel extension and calling it from your constructor is fine.

Another option is to use Eclipse so that you no longer receive these warnings ... (completely joke;).

0
source

The reason for this warning is that you pass this until the constructor is complete and therefore the object is not fully initialized. Even you use it at the end of your constructor, most likely your class is extended and there is a constructor for the subclass that needs to be executed yet. In your case (registering an object as a listener) this is safe, since Swing is single-threaded, and events will be passed to listeners only after the initialization of your object.

0
source

Source: https://habr.com/ru/post/911115/


All Articles