Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / February 2006

Tip: Looking for answers? Try searching our database.

Action Listener, Determing which button was pressed

Thread view: 
Ben - 11 Feb 2006 22:02 GMT
Hi,
  Could anyone help me with this problem.  I have an action listener
associated with a number of buttons.  I can get the action listener to
work, but what code do I need to findout which button was pressed.

This is the layout of the action listener class.

import java.awt.event.*;
import java.awt.Component;

public class ButtonListener implements ActionListener
{
   public void actionPerformed (ActionEvent e)
   {
       
   }

}

Thanks in advance.

Ben.
Chris Lamb - 11 Feb 2006 22:21 GMT
> Hi,
>    Could anyone help me with this problem.  I have an action listener
[quoted text clipped - 18 lines]
>
> Ben.

Have you tried setActionCommand() method for the JButton? Then you can use
e.getActionCommand() in your ActionListener to query it.

Chris
Thomas Hawtin - 12 Feb 2006 00:02 GMT
>>    Could anyone help me with this problem.  I have an action listener
>> associated with a number of buttons.  I can get the action listener to
[quoted text clipped - 16 lines]
> Have you tried setActionCommand() method for the JButton? Then you can use
> e.getActionCommand() in your ActionListener to query it.

Or more directly, use e.getSource().

It's usually better to create a new listener instance for each event source.

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Chris Lamb - 12 Feb 2006 00:10 GMT
>>>    Could anyone help me with this problem.  I have an action listener
>>> associated with a number of buttons.  I can get the action listener to
[quoted text clipped - 20 lines]
>
> It's usually better to create a new listener instance for each event source.

Ah, yes indeedy. I'm afraid I must put my hand up and admit to using the
'cheap 'n' nasty' on more occasions than is appropriate :).

Chris
Knute Johnson - 12 Feb 2006 00:27 GMT
>> Have you tried setActionCommand() method for the JButton? Then you can
>> use
[quoted text clipped - 6 lines]
>
> Tom Hawtin

I don't know, for one or two buttons maybe.  But if you have a bunch of
menus and buttons I find it to be much less confusing to have all of the
events go to the same listener and separate them out there.

Signature

Knute Johnson
email s/nospam/knute/

ossie.moore@gmail.com - 12 Feb 2006 05:29 GMT
Here here. Separate listeners for each button in many situations is
stunningly inefficient and confusing.
Thomas Hawtin - 12 Feb 2006 15:03 GMT
> Here here. Separate listeners for each button in many situations is
> stunningly inefficient and confusing.

Really?? Are you referring to class loading time? I would be surprised
if that makes any significant difference in this day and age. I'm
confused by the idea that it's confusing.

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Knute Johnson - 12 Feb 2006 18:31 GMT
>> Here here. Separate listeners for each button in many situations is
>> stunningly inefficient and confusing.
[quoted text clipped - 4 lines]
>
> Tom Hawtin

You said better, I said less confusing, I think we both have
preferences.  It is my preference to group the event handling together
if I have more than a couple of related events.  I usually do that when
I create a frame with a bunch of menus.  I like the menu creation code
together and the event processing code together.  Less confusing for the
unimaginative like me :-).

Signature

Knute Johnson
email s/nospam/knute/

Roedy Green - 13 Feb 2006 10:06 GMT
On Sun, 12 Feb 2006 10:31:19 -0800, Knute Johnson
<nospam@ljr-2.frazmtn.com> wrote, quoted or indirectly quoted someone
who said :

>> Really?? Are you referring to class loading time? I would be surprised
>> if that makes any significant difference in this day and age. I'm
>> confused by the idea that it's confusing.

each anonymous listener class adds about 3K overhead.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Thomas Hawtin - 13 Feb 2006 15:42 GMT
> On Sun, 12 Feb 2006 10:31:19 -0800, Knute Johnson
> <nospam@ljr-2.frazmtn.com> wrote, quoted or indirectly quoted someone
[quoted text clipped - 5 lines]
>
> each anonymous listener class adds about 3K overhead.

3K overhead to what?

Class files each have string references to all packages, method names
and signatures involved, which makes them larger than should be
expected. Within JAR files they will normally be compressed.

I have to confess a good deal of ignorance about runtime structures.
Presumably you don't need all the copies of the same data. That should
strip away most of the inefficiency.

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Roedy Green - 13 Feb 2006 15:47 GMT
On Mon, 13 Feb 2006 15:58:52 +0000, Thomas Hawtin
<usenet@tackline.plus.com> wrote, quoted or indirectly quoted someone
who said :

>> each anonymous listener class adds about 3K overhead.
>
>3K overhead to what?
that is how much real ram they consume when they are sitting there
fielding events.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Thomas Hawtin - 13 Feb 2006 22:42 GMT
> On Mon, 13 Feb 2006 15:58:52 +0000, Thomas Hawtin
> <usenet@tackline.plus.com> wrote, quoted or indirectly quoted someone
[quoted text clipped - 6 lines]
>  that is how much real ram they consume when they are sitting there
> fielding events.

I couldn't believe it. So I consulted the google. And indeed the web
does say 3K. It's even printed on like real paper, so it must be right.

http://java.sun.com/docs/books/performance/1st_edition/html/JPClassLoading.fm.ht
ml#24833


Okay, so perhaps it's the old school book trick wherein generations of
authors copying other authors' mistakes. So I shall do my own testing.
Below is a quick & dirty program to create simplistic scalable example
code. And indeed going up to 1000 anonymous inner classes it takes 3K a
class. Unbelievable.

Going higher hit a problem with a laughable hash algorithm in javac. I
patched that with the String code, and reduced my expectations to fit
within the limits of the class file format. 3000 anonymous inner classes
require less memory than just one!!

???

Ah yes, the permanent generation is reluctant to have its garbage
collected (the clue is in the name). One of the EJB servers (BEA?) had a
problem running on Sun's JRE because it could throw OutOfMemoryError
despite having plenty of memory available.Apparently, it used to be the
case that running out of memory for the permanent generation didn't
trigger gc, so you need create transient data to force a collection
(proper details are on the Bug Parade somewhere).

In today's world, System.gc does not appear to collect from the
permanent generation. Naive memory measurements are therefore misleading.

    The folk wisdom that inner classes are really expensive is hogwash.

Still, it seems inefficient of the JVM to allocate permanent generation
memory in such a manner.

Tom Hawtin

import java.io.*;

class Gen {
    public static void main(String[] args) throws IOException {
        final int inners = Integer.getInteger("inners");
        File dir = new File("test"+inners);
        if (!dir.mkdir()) {
            throw new Error("mkdir: "+dir);
        }
        String pkg = "mylongpackagenameandsomerandompadding";
        File pkgDir = new File(dir, pkg);
        if (!pkgDir.mkdir()) {
            throw new Error("mkdir: "+pkgDir);
        }
        String cls = "Test"+inners;
        Writer out = new BufferedWriter(new FileWriter(new File(
                   pkgDir, cls+".java"
        )));

        out.write(
 "package "+pkg+";\n"
+"\n"
+"import java.awt.*;\n"
+"import java.awt.event.*;\n"
+"import javax.swing.*;\n"
+"\n"
+"class "+cls+" {\n"
+"    public static void main(String[] args) throws Exception {\n"
+"        final JButton button = new JButton();\n"
+"\n"
        );
        for (int ct=0; ct<inners; ++ct) {
            out.write(
 "        button.addActionListener(new ActionListener() {\n"
+"                public void actionPerformed(ActionEvent event) {\n"
+"                    button.setText(\""+ct+"\");\n"
+"                }\n"
+"        });\n"
            );
        }
        out.write(
 "\n"
+"        System.gc();\n"
+"        Runtime runtime = Runtime.getRuntime();\n"
+"        System.out.println(\n"
+"            \""+inners+" - \"+\n"
+"            \"freeMemory: \" +runtime.freeMemory() +\",  \"+\n"
+"            \"maxMemory: \"  +runtime.maxMemory()  +\",  \"+\n"
+"            \"totalMemory: \"+runtime.totalMemory()+\",  \"\n"
+"        );\n"
+"        Thread.currentThread().join();\n"
+"    }\n"
+"}\n"
        );
        out.close();
    }
}
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Thomas Hawtin - 13 Feb 2006 23:41 GMT
> In today's world, System.gc does not appear to collect from the
> permanent generation. Naive memory measurements are therefore misleading.

Playing around with it some more, seems I want to be measuring non-heap
memory. I get around 1K or so per anonymous inner class with -server. I
shall play some more.

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Chris Uppal - 15 Feb 2006 14:08 GMT
> Playing around with it some more, seems I want to be measuring non-heap
> memory. I get around 1K or so per anonymous inner class with -server. I
> shall play some more.

I get the same using the 1.5 client VM.  Each inner seems to add around 1.1K or
1.2K to the what jconsole/JMX calls the "Perm Gen" memory pool.  (I haven't
been able to find any info relating the "Perm Gen" to the "Perm Gen [shared
ro]" and "Perm Gen [shared rw]" pools.)

They add some load to the code-cache too, but that's to be expected since there
are actually more methods...  Presuming that the choice is between putting a
fixed amount of code in either an dedicated inner class or somewhere else, I
don't think the code size is relevant.  Sadly the monitoring doesn't seem to
work with -Xint.

Other than that, they don't seem to add any load to reported memory use.

   -- chris
Thomas Hawtin - 15 Feb 2006 18:58 GMT
> I get the same using the 1.5 client VM.  Each inner seems to add around 1.1K or
> 1.2K to the what jconsole/JMX calls the "Perm Gen" memory pool.  (I haven't
> been able to find any info relating the "Perm Gen" to the "Perm Gen [shared
> ro]" and "Perm Gen [shared rw]" pools.)

I think the details go like this. The Perm Gen houses class data and
interned Strings (so don't intern Strings unless you really mean it).

The [shared ro] and [shared rw] is to do with Class Data Sharing (CDS).
Using either -server or -Xshare:off should switch it off. The rw (read
write) section is presumably Copy-on-Write. Both sections are
initialised by a memory mapped file that is created during the install
process and contains data normally found in rt.jar.

On Linux you can see the mapped files with pmap. For 1.6 I get:

...
94280000   6184K r-xs-  /usr/java/jdk1.6.0/jre/lib/i386/client/classes.jsa
9488a000   2008K rwx--    [ anon ]
94a80000   7596K rwx--  /usr/java/jdk1.6.0/jre/lib/i386/client/classes.jsa
951eb000   4692K rwx--    [ anon ]
95680000    896K rwx--  /usr/java/jdk1.6.0/jre/lib/i386/client/classes.jsa
95760000   3200K rwx--    [ anon ]
95a80000     16K r-xs-  /usr/java/jdk1.6.0/jre/lib/i386/client/classes.jsa
...

I have no idea why Perm Gen is not considered part of "the heap".

But bare in mind I demonstrably don't know what I'm talking about.

Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Chris Uppal - 17 Feb 2006 15:46 GMT
> I think the details go like this. The Perm Gen houses class data and
> interned Strings (so don't intern Strings unless you really mean it).
[...]
> I have no idea why Perm Gen is not considered part of "the heap".

The only justification I can think of would be that it wasn't GCed (as is also
suggested -- in fact implied -- by the name "Perm Gen"), but that is manifestly
not the case.

Ho hum...

   -- chris
Roedy Green - 14 Feb 2006 06:31 GMT
On Mon, 13 Feb 2006 23:02:10 +0000, Thomas Hawtin
<usenet@tackline.plus.com> wrote, quoted or indirectly quoted someone
who said :

> And indeed go

then on top of that you might have multiple instances of those
classes.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Thomas Hawtin - 15 Feb 2006 18:58 GMT
> On Mon, 13 Feb 2006 23:02:10 +0000, Thomas Hawtin
> <usenet@tackline.plus.com> wrote, quoted or indirectly quoted someone
[quoted text clipped - 4 lines]
>  then on top of that you might have multiple instances of those
> classes.

Each instance will be around two dozen bytes. You will need a lot of
buttons (which come in at a few K each, IIRC) for that to be a problem.

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Chris Uppal - 14 Feb 2006 11:22 GMT
> Going higher hit a problem with a laughable hash algorithm in javac.

?

Details, please ;-)

   -- chris
Thomas Hawtin - 14 Feb 2006 18:00 GMT
>>Going higher hit a problem with a laughable hash algorithm in javac.
>
> ?
>
> Details, please ;-)

For lengths greater than zero:

                len * (41 * 41 * 41) +
                cs[start] * (41 * 41) +
                cs[start + len - 1] * 41 +
                cs[start + (len >> 1)]

So it's based on the length, first character, last character and middle
character. I had class names like Test1000, Test1010,, Test1020, etc.
Not good. Even the JDK 1.02 String hashCode was better than that.
Sampling does not pay when it come to hash codes.

The patched version seemed to run much faster. It actually completed
before being killed.

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Chris Uppal - 15 Feb 2006 13:48 GMT
> So it's based on the length, first character, last character and middle
> character.

Dear Gods!

> The patched version seemed to run much faster. It actually completed
> before being killed.

Dunno what you're complaining about -- even with 3000 inner classes it still
compiled in only a little over two minutes ;-)

   -- chris
steve - 14 Feb 2006 23:52 GMT
> Hi,
>    Could anyone help me with this problem.  I have an action listener
[quoted text clipped - 18 lines]
>
> Ben.

something like this

public class ShipmentsCard1 extends JPanel implements ActionListener {

    Quit_BUTT.setText("Quit");
       Quit_BUTT.setBounds(new Rectangle(615, 10, 90, 25));
       Quit_BUTT.setFont(new Font("Arial", 0, 9));
Reports_BUTT.setText("Reports");
       Reports_BUTT.setBounds(new Rectangle(501, 10, 110, 25));
       Reports_BUTT.setFont(new Font("Arial", 0, 9));

Quit_BUTT.addActionListener(this);
   Reports_BUTT.addActionListener(this);
   

   public void actionPerformed(ActionEvent evt) {
Object source = evt.getSource();

if (source == Quit_BUTT) {
   Killprogram();
}

 if (source == Reports_BUTT) {
         //this is working (21/12/2005)
           printRecords();
       }

}

}

where possible keep it all together in 1 routine, adding listener classes all
over the place as separate items makes code maintanance a PIG.
IchBin - 15 Feb 2006 04:04 GMT
>> Hi,
>>    Could anyone help me with this problem.  I have an action listener
>> associated with a number of buttons.  I can get the action listener to
>> work, but what code do I need to findout which button was pressed.

[snip code]

If I implement ActionListener. I usually do it this way:

 public class ShipmentsCard1 extends JPanel implements ActionListener {
     private final String QUIT   = "Quit";
     private final String REPORT = "Reports";

     Quit_BUTT.setText(QUIT);
     Quit_BUTT.setBounds(new Rectangle(615, 10, 90, 25));
     Quit_BUTT.setFont(new Font("Arial", 0, 9));
     Quit_BUTT.setActionCommand(QUIT);
     Quit_BUTT.addActionListener(this);

     Reports_BUTT.setText(REPORT);
     Reports_BUTT.setBounds(new Rectangle(501, 10, 110, 25));
     Reports_BUTT.setFont(new Font("Arial", 0, 9));
     Reports_BUTT.setActionCommand(REPORT);
     Reports_BUTT.addActionListener(this);
  .
  .
  .
public void actionPerformed(ActionEvent evt) {
    String source = evt.getActionCommand();

  if (source.equals(QUIT))
  {
     Killprogram();
  }
  else if (source.equals(REPORT))
  {
       printRecords();
  }
  .
  .
  .

Signature

Thanks in Advance...
IchBin, Pocono Lake, Pa, USA
http://weconsultants.servebeer.com/JHackerAppManager
__________________________________________________________________________

'If there is one, Knowledge is the "Fountain of Youth"'
-William E. Taylor,  Regular Guy (1952-)



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.