A Java GUI will have listeners attached to components. The components will need to be accessible to the listeners. Managing access to variables is a general problem. Here I give four techniques. These four programs all implement the same functionality. There are others.

In terms of which technique is preferred, the first is usually the nicer. The event handling routine is lexically close to the component it is linked to.

For specificity, the examples will be for a Java app that has a textfield for input, a textfield for output, and a button. When the user enters data to the input text field and then clicks the button, the data value is copied to the output field.

  1. When you connect the listener to the component, instantiate an anonymous ActionListener with actionPerformed in situ.

    (Wikipedia: "When an anonymous inner class is defined within the body of a method, all variables declared final in the scope of that method are accessible from within the inner class. Once it has been assigned, the value of the final variable cannot change. This allows the Java compiler to "capture" the value of the variable at run-time and store a copy as a field in the inner class. ")

    Here is an example:

    /* Demonstrating anonymous inner function for ActionListener */
    /* @name smh
     * @version 1
     * @date 11/21/2013
     */
    
    import javax.swing.JFrame;
    import java.awt.FlowLayout;
    import javax.swing.JButton;
    import javax.swing.JTextField;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    
    public class Demo1 extends JFrame {
    	
    	public Demo1() {
    		this.setTitle("Anonymous ActionListener");
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setSize(300,80);
    		this.setLayout(new FlowLayout());
    		
    		final JTextField textfield1 = new JTextField("input", 5);
    		final JTextField textfield2 = new JTextField("output", 5);
    		textfield2.setEditable(false);
    		
    		JButton button = new JButton("click");
    		button.addActionListener ( new ActionListener() {    
    			public void actionPerformed(ActionEvent ev) {
    				String str = textfield1.getText();
    				textfield2.setText(str);		
    				}
    			} );
    	
    		this.add(textfield1);
    		this.add(textfield2);
    		this.add(button);
    		}
    	
    	public static void main(String args[]) {
    		Demo1 gui = new Demo1();
    		gui.setVisible(true);
    	}
    }
    
    
    
  2. Your GUI class extends JFrame AND implements ActionListener. Link up the component and the listener using this.

    Notice that the components are data members of the GUI class.

    /* Demonstrating GUI class that extends JFrame and implements ActionListener */
    /* @name smh
     * @version 1
     * @date 11/21/2013
     */
    
    import javax.swing.JFrame;
    import java.awt.FlowLayout;
    import javax.swing.JButton;
    import javax.swing.JTextField;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    
    public class Demo2 extends JFrame implements ActionListener{
    
    	JTextField textfield1, textfield2;
    	
    	public Demo2() {
    		this.setTitle("Class extends JFrame implements ActionListener");
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setSize(400,80);
    		this.setLayout(new FlowLayout());
    		
    		textfield1 = new JTextField("input", 5);
    		textfield2 = new JTextField("output", 5);
    		textfield2.setEditable(false);
    		
    		JButton button = new JButton("click");
    		button.addActionListener ( this );   
    	
    		this.add(textfield1);
    		this.add(textfield2);
    		this.add(button);
    		}
    	
    	public static void main(String args[]) {
    		Demo2 gui = new Demo2();
    		gui.setVisible(true);
    		}
    	
    	public void actionPerformed(ActionEvent ev) {
    		textfield2.setText(textfield1.getText());		
    		}
    }
    
  3. Make the listener an inner class.

    Notice the textfields are data members of the outer class.

    /* Demonstrating GUI class that uses an inner class for its listener */
    /* @name smh
     * @version 1
     * @date 11/21/2013
     */
    
    import javax.swing.JFrame;
    import java.awt.FlowLayout;
    import javax.swing.JButton;
    import javax.swing.JTextField;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    
    public class Demo3 extends JFrame{
    
    	JTextField textfield1, textfield2;
    	
    	public Demo3() {
    		this.setTitle("Using an named inner class to implement ActionListener");
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setSize(400,80);
    		this.setLayout(new FlowLayout());
    		
    		textfield1 = new JTextField("input", 5);
    		textfield2 = new JTextField("output", 5);
    		textfield2.setEditable(false);
    		
    		JButton button = new JButton("click");
    		button.addActionListener ( new ButtonListener() );   
    	
    		this.add(textfield1);
    		this.add(textfield2);
    		this.add(button);
    		}
    	
    	public static void main(String args[]) {
    		Demo3 gui = new Demo3();
    		gui.setVisible(true);
    		}
    	
    	public class ButtonListener implements ActionListener {
    		public void actionPerformed(ActionEvent ev) {
    			textfield2.setText(textfield1.getText());		
    			}
    	    }
        }
    
  4. Make the listener a separate class. Pass the component (e.g., button) listener's constructor. The listener has a data member that stores the reference to the component on the JFrame.
    /* Demonstrating GUI class that uses a separate class for its listener */
    /* @name smh
     * @version 1
     * @date 11/21/2013
     */
    
    import javax.swing.JFrame;
    import java.awt.FlowLayout;
    import javax.swing.JButton;
    import javax.swing.JTextField;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    
    public class Demo4 extends JFrame{
    
    	JTextField textfield1, textfield2;
    	
    	public Demo4() {
    		this.setTitle("Listener in separate class");
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setSize(400,80);
    		this.setLayout(new FlowLayout());
    		
    		textfield1 = new JTextField("input", 5);
    		textfield2 = new JTextField("output", 5);
    		textfield2.setEditable(false);
    		
    		JButton button = new JButton("click");
    		button.addActionListener ( new ButtonListener(textfield1, textfield2) );   
    	
    		this.add(textfield1);
    		this.add(textfield2);
    		this.add(button);
    		}
    	
    	public static void main(String args[]) {
    		Demo4 gui = new Demo4();
    		gui.setVisible(true);
    		}
    }
    
    class ButtonListener implements ActionListener {
    	JTextField t1, t2;
    	public ButtonListener(JTextField t1, JTextField t2) {
    		this.t1 = t1;
    		this.t2 = t2;
    		}
    	public void actionPerformed(ActionEvent ev) {
    		t2.setText(t1.getText());		
    		}
    	}