package view; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * Same functionality as Frame2 but uses an adapter interface to communicate * with the outside world instead. This design allows varying the communication * with the outside world. How the outside world reacts to the events that * happen to the view is a variant behavior! * Uses the Null-Object Pattern to initialize the adapter avoiding checking for * null. * @author DXN */ public class Frame3 extends Frame2 { // Initializes the adapter to a null object: private IView2World _v2wAdapter = new IView2World() { public Object button1Clicked (ActionEvent e) { return null; // does nothing! } public Object button2Clicked (ActionEvent e) { return null; // does nothing! } }; public Frame3(String title) { super(title); } public void setV2WAdapter(IView2World v2w) { if (null == v2w) { throw new IllegalArgumentException("Argument cannot be null!"); } _v2wAdapter = v2w; } /** * Tells _v2wAdapter the button click event happens on jb1. */ protected void jb1Clicked(ActionEvent e) { _v2wAdapter.button1Clicked(e); } /** * Tells _v2wAdapter the button click event happens on jb2. */ protected void jb2Clicked(ActionEvent e) { _v2wAdapter.button2Clicked(e); } }
package view; import java.awt.event.*; /** * Adapter connecting Frame3 (the View) to the outside world. */ public interface IView2World { /** * Called by Frame3 when its button 1 is clicked. */ public Object button1Clicked (ActionEvent e); /** * Called by Frame3 when its button 2 is clicked. */ public Object button2Clicked (ActionEvent e); }
package controller; import view.*; import java.awt.event.*; import javax.swing.JFrame; import java.awt.*; // For layout managers. /** * The controller that instantiates a concrete IView2World object and connects * the world outside of Frame3 (the view) to Frame3. * The concrete adapter is implemented as an anonymous inner classe. */ public class Frame3Controller { public JFrame constructFrame() { // Local variable needs to be final so that the local inner class // can access it: final Frame3 frame = new Frame3("View and Controller"); /** * Install as concrete anonymous IView2World adapter in frame, without * frame knowing what the adapter does. */ frame.setV2WAdapter(new IView2World() { public Object button1Clicked (ActionEvent e) { frame.getContentPane().setLayout(new GridLayout(2,1)); frame.validate(); return null; } public Object button2Clicked (ActionEvent e) { frame.getContentPane().setLayout(new FlowLayout()); frame.validate(); return null; } }); frame.setVisible(true); return frame; } }
package app; import view.*; import controller.*; /** * Instantiates the controller and builds the frame! */ public class Frame3App { public static void main(String[] args) { new Frame3Controller().constructFrame().validate(); } }