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}