views:

297

answers:

3

I have a main class in a program that launches another class that handles all the GUI stuff. In the GUI, i have a button that i need to attach an ActionListener to.

The only problem is, the code to be executed needs to reside within the main class.

How can i get the ActionPerformed() method to execute in the main class when a button is clicked elsewhere?

A: 

Implement ActionListener in your main class and add the main class instance as a listener on your GUI button.

Software Monkey
what form does the instance take in the main class? is it a class of its own?
Allen
+1  A: 

Make your controller ("main" class) implement the ActionListener interface, then pass a reference to the view class:

public class View extends JFrame {
  public View(final ActionListener listener) {
   JButton button = new JButton("click me");
   button.addActionListener(listener);
   button.setActionCommand("do_stuff");

   getContentPane().add(button);

   pack();
   setVisible(true);
  }
 }

 public class Control implements ActionListener {

  public Control() {
   new View(this);
  }

  @Override
  public void actionPerformed(ActionEvent e) {
   if (e.getActionCommand().equals("do_stuff")) {
    // respond to button click
   }
  }
 }

It can also be done with Actions, but that's more useful where you want one piece of code to respond to many buttons.

tom
the only issue now seems to be that I am passing the 'control' class through. however, it is the class that contains my main method, and so is coming from a static context, which the 'view' class is not.any idea how to remedy?
Allen
The simplest solution is to instantiate your control class from the main method. IN my example that would be a main method with one line: new Control();
tom
i already have the majority of the program's logic in the main method. are you saying that i need to restructure the entire program to accomodate this? the entire point of this was to get the ActionPerformed code within the main class. is there a simpler way?
Allen
i got it to work, I put the control class in the same file as the main class, outside of the main class
Allen
+1  A: 

Implement an anonymous inner class as ActionListener on the button, then call the method on your main class. This creates less dependencies and avoids the tag & switch style programming that implementing the ActionListener interface on a main class tends to promote.

In either case it will create a cycle in your dependency graph: the main class will know about the button and the button will need to call the main class. This might not be a good idea since it will make it hard to compose things in any other way. But without further information it is hard to judge the situation or recommend anything concrete.

Peter Becker
the main class launches the GUI, and i can give the main class access to the buttons if need be. the ActionPerformed code needs to be in the main class. I just don't know what needs to go where
Allen