Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Separating GUI from ActionListeners in two different (external) classes  RSS feed

 
cristian zoccarato
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello everybody, I know this problem has been discussed several times and I tried every possible solution but, after hours and hours I'm still in the mud.
My problem: I wrote a small application that should simulate a defibrillator and I would like to split the GUI from the actionListener(s).
I did it and both classes do the compiling...but when it comes to run it..it comes with this error:
at EsdGUI.<init>(EsdGUI.java:39)
at EsdActions.<init>(EsdActions.java:16)

I see there's something wrong with the instantiation of the Listener class (which I called EsdActions) in the main class (EsdGUI) as well for the other class I'm not including here that deals with the ItemListener (called ItemHandler),

Don't really know what's wrong with that. I tried to do some rewriting but, since my skills are not so well-developed, I'm stuck into problems.

My solution was: create an instance of the class of Listeners into the GUI class, then add the actionlisteners to the components. I do that, and still nothing happens.
Is there anyone who can give me some advice? Where i do wrong?

I apologize in advance for the lenght of my code but this, as well as the will of satisfy the Observer Pattern is what's giving me headaches...
So here's the main class


and here's the listeners class...



I hope the topic includes scrollbars....thanks in advance to whoever would like to help me.
 
Campbell Ritchie
Sheriff
Posts: 53742
127
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

I shall have to go back to your code and break some of the long lines; you can see how it should be done.
I worry when I see lots of if‑elses in a Listener. It looks like procedural programming to me. I think you should have a Listener object for each button, a VentricularFibrillationListener, a VentricularTachycardiaListener, etc.
What was the error you are suffering? Was it an Exception? You appear only to have posted part of the stack trace.
 
Campbell Ritchie
Sheriff
Posts: 53742
127
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Never use == true or == false. It is poor style and error‑prone if you write = by mistake.
Not if (b == true) ... or if (b == false) ...
Write if (b) ... or if (!b) ...
 
cristian zoccarato
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello! thanks for your advices!
About the IF(s) in Listeners..well I had the same feeling but I didn't know if it was a good idea or not to have one listener for each button. I'll follow you advice...

About my other problem...I passed through several kinds of errors..but, if I compile this code the only one I get is (when compiling EsdActions)
"cammot find symbol"..and this to EVERY button (such as "print", "release" etc).
I tried to instantiate a EsdGUI object in the listener class but that doesn't work..
I know solution is right in front of me but can't see that clearly...

[EDIT]

I followed your suggestion and created an external class RsListener that extends EsdGUI with a single listener for the button SinusalRhythm.

I also put this, into EsdGUI code

but when it comes compiling I get a very long list of this error
at EsdGUI.<init>(EsdGUI.java:49)
at RsListener.<init>(RsListener.java:15)
at EsdGUI.<init>(EsdGUI.java:49)
at RsListener.<init>(RsListener.java:15)
that points at the line 49 I posted above and the introducing line into RsListener class which says

but, if I remove "extends EsdGUI" I know I will get an error since the buttons in there wouldn't be recognized as part of the EsdGUI class...
What I'm doing wrong now?
 
Campbell Ritchie
Sheriff
Posts: 53742
127
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are right about extending. The Listener class should implement ActionListener and should not extend a GUI class.
You still appear to be posting only part of the stack trace. If we don't know what sort of Exception you are suffering, we can't help you.
 
cristian zoccarato
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for answering..I'm trying to give all the informations you need.
when i run the code it happens this:
nothing happens for a little while..then a big number of these error lines appear on the screen and cannot scroll back to the beginning and tell what happened. A very long list and cannot see even the top of the terminal.
I think I should try-catch an exception but I'm just supposing..

What seems to create troubles is the fact that I put the actions happening when I press a button in the Listener class.
Things such as "setEnable(false)" buttons or setText(). But, whenever I try to compile it rightly says that can't recognize those buttons. So I instantiated a new GUI object in the Listener class
and put it before every button. But that seems not right to me.

[EDIT/UPDATE]
I added

into the GUI constructor and it seems I found the name of the error:
Exception in thread "main" java.lang.NullPointerException
at EsdGUI.<init>(EsdGUI.java:55)
at EsdGUI.main(EsdGUI.java:163)

it points here:


and here



so it seems it points to somewhere null...side question: if it says "<init>, does it means that is that the place where the exception is generated?
 
Randall Twede
Ranch Hand
Posts: 4583
6
Java Python Scala
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
i gave Campbell a thumbs up for his answer about not using ==true etc
personally, i disagree with him about this
I think you should have a Listener object for each button

he is probably not the only one who doesn't like the way i do it but i will give you an option.

i generally have my "main" class implement actionListener
i have one actionPerformed() for all the action events
yes, it is a long if else statement
yes all the action events are handled in one easy to find place
if actionListener had more than one required method i would use a named inner class.

great minds don't all think alike
 
Campbell Ritchie
Sheriff
Posts: 53742
127
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Randall Twede wrote:i gave Campbell a thumbs up for his answer about not using ==true etc
Thank you
personally, i disagree with him about this . . . great minds don't all think alike
And you only start getting an interesting discussion when people disagree.

There are instances where a Listener is intimately connected with a GUI class; for example a MouseListener needs to know the position of the mouse on a panel, so it it probably a good idea to make the panel implement MouseListener. In other cases, however, you are making the class do two unrelated things, which is usually a bad idea: display itself and respond to events. You get an Event object and a source object. If the source is a button, why make some other GUI object listen for the event?

Why have such a large method? That breaches the principle that a method should do one thing. A large method like that is not easier to maintain; you have to hunt through it to find the part to alter. The very worst I ever saw, on this website, and thank goodness I can't find it back, in a calculator application, and it looked something like this:-I have forgotten the full details. All you have to do is get one digit wrong in that block of if‑elses, and the calculator won't work. In a real‑life application, the error might not become apparent for some time, and real damage could be done before it is found. Think how much more object‑oriented this would beAnd also how much less code you have to write.

I have a rule of thumb about Listeners giving flexibility about where you write them:
  • Listeners likely to be used in several other applications: public top‑level class.
  • Listeners likely to be used only in this class: private inner class.
  • Listener only used once, not even something similar used elsewhere: consider anonymous class.
  • In each case you will have one object per action and one object per source.
    You can have several listeners on a Component, and you can even add and remove them at runtime. That allows you to change their functionality, which you cannot easily do with addActionListener(this).

    If Rob Spoor were here, he would say it is even better to use an Action and we should learn how to extend AbstractAction. He would be right.
     
    cristian zoccarato
    Greenhorn
    Posts: 14
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks Campbell for your precious advices about Listeners. Actually I'm trying to make my code less "fat" and trying to be more familiar with these features..I'm close to find a good solution for my problem..
     
    Campbell Ritchie
    Sheriff
    Posts: 53742
    127
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    You're weelcome

    Go back and search on this forum and you will find this question discussed frequently. This is one of the more heated threads, and note the link to an older thread in the first post.
     
    Randall Twede
    Ranch Hand
    Posts: 4583
    6
    Java Python Scala
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    If Rob Spoor were here, he would say it is even better to use an Action and we should learn how to extend AbstractAction. He would be right.

    i like what i have learned so far about Actions. i especially like the ones that are predefined in the API
    anonymous inner classes is what i don't like very much(i have used them).
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!