14

I just started learning GUI with Swing and don't exactly understand how the actionPerformed method works. Consider the following code:

//code to create a button and change its text when clicked
public class simplegui implements ActionListener {
  JButton button;

  public static void main(String[] args) {
    simplegui gui=new simplegui();
    gui.go();
  }

  public void go() {
    JFrame frame=new Frame();
    button=new JButton("click Me");
    button.addActionListener(this);

    frame.getContentPane().add(button);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(300,300);
    frame.setVisible(true);
  }

  public void actionPerformed(ActionEvent event) {
    button.setText("I've been clicked!");
  }
}

Shouldn't an object be created for a class before a method on it is evoked (except for static methods)?

When the button is clicked the actionPerformed method is called, but how? Where is the call made? I've implemented the interface ActionListener, but where is the code that knows that when an action occurs the 'ActionEvent' Object should be sent to the 'actionPerformed' method? Is it present in the Button class? Is the addActionListener method present in the Button class?

When I click the button, how is the system call action performed and where is the code that executes gui.actionPerformed()?

I followed Java concepts of OO, static etc. until now but this whole event driven programming is confusing.

Jongware
  • 22,200
  • 8
  • 54
  • 100
Sainath S.R
  • 3,074
  • 9
  • 41
  • 72
  • 1
    But there **is** a specific call to this method, only it's not occurring in your code but rather in the JVM. A button push instigates internal events that leads the JVM to tell the button to notify all of its listeners that it has been pushed. This will cause the actionPerformed methods of all attached ActionListeners to be called. – Hovercraft Full Of Eels Aug 31 '14 at 12:49
  • 1
    @HovercraftFullOfEels I suggest adding that as a complete answer (possibly with links to Java/swing runtime library source) – nanofarad Aug 31 '14 at 12:52
  • Yeah i get that but if there is a call being made somewhere else is the code for it in any of these classes etc , if so please link me the correspoding API documentation that makes it clear? – Sainath S.R Aug 31 '14 at 12:53

1 Answers1

5

But there is a specific call to this method, only it's not occurring in your code but rather in the JVM. A button push instigates internal events that leads the JVM to tell the button to notify all of its listeners that it has been pushed. This will cause the actionPerformed methods of all attached ActionListeners to be called.

To see information on how this works, first look at the Java API for the AbstractButton class where you'll find the method

protected void fireActionPerformed(ActionEvent event)

Where

Notifies all listeners that have registered interest for notification on this event type. The event instance is lazily created using the event parameter.

Then for further information, you will want to go beyond the Java API to the source code which can be found here. If you check out the Java 8.0 source code there, and look up javax then swing, then AbstractButton, you'll find a fireActionPerformed(ActionEvent event) method:

2002    protected void More ...fireActionPerformed(ActionEvent event) {
2003        // Guaranteed to return a non-null array
2004        Object[] listeners = listenerList.getListenerList();
2005        ActionEvent e = null;
2006        // Process the listeners last to first, notifying
2007        // those that are interested in this event
2008        for (int i = listeners.length-2; i>=0; i-=2) {
2009            if (listeners[i]==ActionListener.class) {
2010                // Lazily create the event:
2011                if (e == null) {
2012                      String actionCommand = event.getActionCommand();
2013                      if(actionCommand == null) {
2014                         actionCommand = getActionCommand();
2015                      }
2016                      e = new ActionEvent(AbstractButton.this,
2017                                          ActionEvent.ACTION_PERFORMED,
2018                                          actionCommand,
2019                                          event.getWhen(),
2020                                          event.getModifiers());
2021                }
2022                ((ActionListener)listeners[i+1]).actionPerformed(e);
2023            }
2024        }
2025    }
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • 2
    For reference, this approach is outlined in the [`EventListenerList`](http://docs.oracle.com/javase/8/docs/api/javax/swing/event/EventListenerList.html) API, examined [here](http://stackoverflow.com/q/2159803/230513). – trashgod Aug 31 '14 at 13:41
  • Hi, @Hovercraft. Is it possible to call a method from the method actionPerformed(). For example : - I want to call a _void_ method **add()** and pass 3 variables to it `add(int a, int b, int c)`, and then fetch those variables and to the process that I want to in the **add()** method. Thanks in advance. – Vibhav Chaddha Jan 11 '17 at 09:02
  • @Hovercraft. I cracked it. Thanks anyways. :) – Vibhav Chaddha Jan 11 '17 at 09:46