• Post Reply Bookmark Topic Watch Topic
  • New Topic

Moving listener registration out of the constructor  RSS feed

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey ho everyone,

I am pretty new to the coding world and would really appreciate your advice on how I can properly register listeners in my code. This is actually my first own programming project. I am trying to build a MP3 player based on what I learned with the BlueJ book.
There is a player class that is implementing/wrapping the JLayer Basicplayer and a GUI class that extends JFrame and provides user interaction with the player. The GUI class gets informed by the player about playlist changes, playback progress and such things.

I initally registered the GUI class as a listener to the player in the GUI class constructor. But I found that this isn't really ideal here: IBM Listener advice . I understood that I can't be sure that my constructor finished before "this" would be passed as a listener and generally about the order of code execution in the constructor. While I see the benefit of the advice given in the IBM resource I am not quite sure how to apply it to my code or if I did it properly.

What I did was to transfer the registration of the GUI as a listener of the player into a method: I "postpone" the call of that method to the main method since calling it in the cunstructor would make no difference to the problem. In the main method it is called after the GUI class object is generated. At least I hope that is the case.

However, I am completely unsure if that is a proper way of doing it. The only other way I saw is having separate listener classes. But since the repsonse to the events are carried out in the GUI class these new classes would need to know the GUI class really well and would be pretty tightly coupled, which doesn't seem like a good thing to do. I am aware that I will also need to improve the separation of GUI and functionality, but if it is possible to fix this issue on its own I would prefer that. I took a look at the clementine source code to get an idea how such stuff is done properly and was a bit lost to be honest. So I thought I first fix this problem and some more issues related to the listeners (thread safety), before moving on. Unless the lack of separation is the root of the problem. I posted (hopefully all) relevant code below. The whole project is also on GitHub in case that helps to understand the implementation, which I am afraid probably isn't too good. The listener branch is the current state of the project: GitHub  
  



If anyone is willing to help and able to understand what I am trying to do and say, that would be really great.

Cheers
Mark
 
Marshal
Posts: 56608
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

Why are you extending JFrame? It is usually better not to subclass GUI display components, though there are a few methods which have to be overridden. You would usually do something like this:-Obviously you won't need both lines 4 and 5.
Don't make your GUI components, nor the enclosing class, implement a listener interface. Create a class, whether an anonymous class, a private inner class, or a public top‑level class to implement whichever Listeners you need. Now that Java8 has arrived (and gone to Java9) most people don't use anonymous classes any more; they use λs.
 
mark q. murphy
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the welcome and your suggestions!

Regarding JFrame I once read that extending it or using it as an object both would be fine. Maybe that was not quite true. I am aware that I am not quite up to date with the newest java version. So far I justified that witht the thought
that I'd better focus on getting down some basics first But I promise I will move on to JavaFX and its mediaplayer option soon.

As far as I understood implementing the listeneres as inner or anonymouses class still wouldn't work if they are connected in the constructor though. However, I guess I should be decomposing the whole GUI part of the application as it
currently is one class containing everything. Does anyone have recommendations for a simple java application with source code available that I could take a look at to get a better idea for how to structure this part better?

Somehow, I still can't see though how I could keep the listener out of the GUI that gets informed about playback progress, since this has to be displayed directly in the GUI. That information has to be passed continuously to the GUI. So how would
I go about that?
 
Campbell Ritchie
Marshal
Posts: 56608
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
mark q. murphy wrote:. . . . Regarding JFrame I once read that extending it or using it as an object both would be fine. . . .
You can get both to work, but what is the point of subclassing JFrame since you are not adding any functionality to the frame itself. Things have changed and inheritance is used much less than it was twenty years ago.
As far as I understood implementing the listeneres as inner or anonymouses class still wouldn't work if they are connected in the constructor though. . . . .
Where did you find that? It doesn't quite sound correct.
. . . . That information has to be passed continuously to the GUI. So how would I go about that?
Have you found out about progress bars, or worker threads to do the playing or update your progress bar? Look in the Java™ Tutorials: 1 2
 
Ranch Foreman
Posts: 3071
37
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I liken extending JFrame, when all you do is add stuff into it, to extending ArrayList in order to write code to prepopulate it.
It doesn't make much sense.
 
mark q. murphy
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey ho,

sorry for the late repsonse. Coding is restricted to my spare time, which is a bit limited at the moment.

   
    As far as I understood implementing the listeneres as inner or anonymouses class still wouldn't work if they are connected in the constructor though. . . . .

Where did you find that? It doesn't quite sound correct.


I founf that in the IBM source posted above. This regards registering the listening class from its constructor with a this reference or an inner class instead of this. I should have made this more clear I think.

     . That information has to be passed continuously to the GUI. So how would I go about that?

Have you found out about progress bars, or worker threads to do the playing or update your progress bar? Look in the Java™ Tutorials: 1 2


Thanks I saw that before, but it did not quite work for what I need it to do (or so I think), because it also needs to do some slider positioning and controling. If I generally do it that way, I think I need to extend a lot of JPanels etc and make them implement listener adapers. Another way would be to have the playlist and player control etc GUI bits subclassed. Then have a main window class that assembles everything and connects the subcomponents as listeners to the functional obejects. That seems not quite right to me though.
My main problem is that I found plenty info on how to use listeners that repsond to interactions with GUI components (eg clicking buttons) but not that much on making the GUI respond to changes from the underlying functional components. So suggestions for some real world, properly done Java GUI apps that I could take a look at to get some ideas are still very appreciated.
 
Campbell Ritchie
Marshal
Posts: 56608
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
mark q. murphy wrote:. . . I founf that in the IBM source posted above. . . .
I don't remember seeing that in the IBM link (good link, by the way; Brian Goetz always is good). What you usually do is add listeners to buttons, etc. I have already said about separate classes, or for something like ActionListener, which is a functional interface even though it isn't tagged @FunctionalInterface, use a λ. To revisit the code I posted a week ago:-Obviously those variable and method names are pretty dreadful.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!