001/*
002
003*/
004
005package renderer.gui;
006import  renderer.framebuffer.FrameBuffer;
007
008import java.awt.Color;
009import java.awt.event.*;
010import javax.swing.JFrame;
011import java.awt.BorderLayout;
012
013/**
014   This class allows our rendering code to be used as the primary renderer
015   for interactive Java programs. That is, this class allows us to write
016   interactive Java GUI programs that use our renderer instead of the
017   renderer built into Java's GUI library. Of course, our renderer will be
018   much slower than the one built into Java (which uses the computer's GPU).
019<p>
020   This {@link JFrame} displays our renderer's {@link FrameBuffer} in a
021   {@link FrameBufferPanel} and this class acts as an interface between the
022   Java GUI event system and our renderer.
023<p>
024   This class acts as an "adapter class" for several kinds of event
025   listeners, so applications only need to worry about the events that
026   are relevant to them.
027<p>
028   This class is meant to be sub classed by an application that uses our
029   renderer. The sub class constructor should initialize a
030   {@link renderer.scene.Scene} object with appropriate models and geometry.
031   The sub class should also provide implementations of any desired event
032   handlers. The event handlers provide interactivity by updating the
033   {@link renderer.scene.Scene} object in response to user actions. After
034   an event handler updates the {@link renderer.scene.Scene} object, it will
035   render the {@link renderer.scene.Scene} into the {@link FrameBuffer} object
036   contained in this object's {@link FrameBufferPanel}.
037<p>
038   Each instance of {@code InteractiveFrame} has a reference to a
039   {@link FrameBufferPanel} object, which has a reference to a
040   {@link FrameBuffer} object. When a GUI event happens, one of the
041   implemented event listeners will update this {@link JFrame} window by
042   modifying a {@link renderer.scene.Scene} object appropriately and then
043   having our renderer render the {@link renderer.scene.Scene} object into
044   the {@link FrameBuffer}. When the renderer is done updating the
045   {@link FrameBuffer}, the event listener will call the
046   {@link FrameBufferPanel}'s update() method, which will pass the
047   {@link FrameBuffer}'s pixel data to the {@link java.awt.Image} being drawn
048   on the {@link java.awt.Graphics} context of the {@link FrameBufferPanel}
049   (which is a {@link JPanel}). Then the event listener will call this
050   object's repaint() method which will trigger the {@link FrameBufferPanel}'s
051   paintComponent() method. This will display the {@link java.awt.Image} (that
052   holds the {@link FrameBuffer}'s contents) in the {@link JPanel} within this
053   {@link JFrame}'s window.
054<p>
055   This window may be resizeable. When this window resizes, its FrameBufferPanel
056   will also resize, and the FrameBufferPanel's FrameBuffer object will also need
057   to resize. But FrameBuffer objects cannot be resized. So each time this window
058   resizes, a new FrameBuffer object needs to be created for the FrameBufferPanel.
059   The componentResized() method from the ComponentListener interface should call
060   the setFrameBuffer() method in this object's FrameBufferPanel and pass it a
061   reference to a new FrameBuffer object with the new dimensions of the resized
062   window
063*/
064@SuppressWarnings("serial")
065public class InteractiveFrame extends JFrame implements
066  ActionListener, ItemListener,  AdjustmentListener,  TextListener,
067  KeyListener,    MouseListener, MouseMotionListener, ComponentListener,
068  WindowListener, FocusListener
069{
070   protected FrameBufferPanel fbp;
071
072   /**
073      Create a {@link JFrame} window with a {@link BorderLayout} and place a
074      {@link FrameBufferPanel} (containing a {@link FrameBuffer}) in the center
075      of the layout.
076
077      @param title     title for the {@link JFrame} window
078      @param fbWidth   width for the initial {@link FrameBuffer} used by this {@link JFrame}
079      @param fbHeight  height for the initial {@link FrameBuffer} used by this {@link JFrame}
080   */
081   public InteractiveFrame(String title, int fbWidth, int fbHeight)
082   {
083      super(title);
084      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
085      this.setLocationByPlatform(true);
086
087      // Create the initial FrameBuffer for the FrameBufferPanel.
088      FrameBuffer fb = new FrameBuffer(fbWidth, fbHeight);
089
090      // Create a FrameBufferPanel (a JPanel) for this JFrame.
091      fbp = new FrameBufferPanel(fb);
092
093      // Place the JPanel in this JFrame.
094      this.getContentPane().add(fbp, BorderLayout.CENTER);
095      this.pack();
096      this.setVisible(true);
097
098      // Make this object the event handler for the following
099      // events, which are events created by this window itself.
100      this.addKeyListener(this);
101      this.addMouseListener(this);
102      this.addMouseMotionListener(this);
103      this.addComponentListener(this);
104      this.addWindowListener(this);
105      this.addFocusListener(this);
106   }
107
108
109   /**
110      Accessor method for the {@link FrameBuffer} currently being used
111      as the source for the {@link java.awt.Image} painted on the FrameBufferPanel.
112
113      @return a reference to the FrameBuffer used for this JFrame
114   */
115   public FrameBuffer getFrameBuffer()
116   {
117      return fbp.getFrameBuffer();
118   }
119
120
121   /**
122      Change the FrameBuffer being used as the source
123      for the Image painted on the FrameBufferPanel.
124   <p>
125      This will usually be in response to a call to the
126      componentResized() event handler.
127
128      @param fb  new FrameBuffer object for this JFrame
129   */
130   public void setFrameBuffer(FrameBuffer fb)
131   {
132      fbp.setFrameBuffer(fb);
133   }
134
135
136   // Implement the ActionListener interface.
137   @Override public void actionPerformed(ActionEvent e){}
138   // Implement the ItemListener interface.
139   @Override public void itemStateChanged(ItemEvent e){}
140   // Implement the AdjustmentListener interface.
141   @Override public void adjustmentValueChanged(AdjustmentEvent e){}
142   // Implement the TextListener interface.
143   @Override public void textValueChanged(TextEvent e){}
144   // Implement the KeyListener interface.
145   @Override public void keyPressed(KeyEvent e){}
146   @Override public void keyReleased(KeyEvent e){}
147   @Override public void keyTyped(KeyEvent e){}
148   // Implement the MouseListener interface.
149   @Override public void mouseClicked(MouseEvent e){}
150   @Override public void mousePressed(MouseEvent e){}
151   @Override public void mouseReleased(MouseEvent e){}
152   @Override public void mouseEntered(MouseEvent e){}
153   @Override public void mouseExited(MouseEvent e){}
154   // Implement the MouseMotionListener interface.
155   @Override public void mouseDragged(MouseEvent e){}
156   @Override public void mouseMoved(MouseEvent e){}
157   // Implement the ComponentListener interface.
158   @Override public void componentMoved(ComponentEvent e){}
159   @Override public void componentHidden(ComponentEvent e){}
160   @Override public void componentShown(ComponentEvent e){}
161   @Override public void componentResized(ComponentEvent e){}
162   // Implement the WindowListener interface.
163   @Override public void windowOpened(WindowEvent e){}
164   @Override public void windowClosing(WindowEvent e){}
165   @Override public void windowClosed(WindowEvent e){}
166   @Override public void windowActivated(WindowEvent e){}
167   @Override public void windowDeactivated(WindowEvent e){}
168   @Override public void windowIconified(WindowEvent e){}
169   @Override public void windowDeiconified(WindowEvent e){}
170   // Implement the FocusListener interface.
171   @Override public void focusGained(FocusEvent e){}
172   @Override public void focusLost(FocusEvent e){}
173}