C: THE PROGRAM Devin Kwok: Dossier 2008

Size: px
Start display at page:

Download "C: THE PROGRAM Devin Kwok: Dossier 2008"

Transcription

1 C: THE PROGRAM Devin Kwok: Dossier 2008

2 C.I: Using Good Programming Style C.I.i: Package: com.gmai.kwok.devin.gui.frame Class: Main 01 package com.gmail.kwok.devin.gui.frame; import javax.swing.jframe; /** 06 * The class containing the main method for the dossier program. 07 * 08 Devin Kwok 09 * 10 */ 11 public class Main 12 { 13 /** 14 * Runs the dossier program by showing the main frame. 15 * 16 args 17 */ 18 public static void main( String[] args ) 19 { 20 UniverseFrame frame = new UniverseFrame(); 21 frame.setvisible( true ); 22 frame.setdefaultcloseoperation( JFrame.EXIT_ON_CLOSE ); 23 } 24 } Devin Kwok: Dossier 2008 C: The Program: Page 1 of 185

3 Class: UniverseFrame 001 package com.gmail.kwok.devin.gui.frame; import javax.swing.jframe; 004 import javax.swing.jmenubar; import com.gmail.kwok.devin.gui.component.universecomponent; 007 import com.gmail.kwok.devin.gui.frame.menu.filemenu; 008 import com.gmail.kwok.devin.gui.frame.menu.helpmenu; 009 import com.gmail.kwok.devin.gui.frame.menu.simulationmenu; 010 import com.gmail.kwok.devin.gui.frame.menu.viewmenu; 011 import com.gmail.kwok.devin.gui.panel.universepanel; 012 import com.gmail.kwok.devin.rulesets.gameofliferuleset; 013 import com.gmail.kwok.devin.rulesets.ruleset; /** 016 * A frame containing the dossier program. 017 * 018 Devin Kwok. 019 * 020 */ 021 public class UniverseFrame extends JFrame 022 { 023 /** 024 * 025 */ 026 private static final long serialversionuid = 1L; /** 029 * Constructs a new frame. Currently the frame only supports Game of Life 030 * rules, and thus sets those rules as its default. 031 */ 032 public UniverseFrame() 033 { 034 super( FRAME_TITLE ); 035 setpanel(); 036 setmenu(); 037 setrules( new GameOfLifeRuleSet() ); setsize( FRAME_WIDTH, FRAME_HEIGHT ); 040 } /** 043 * Sets the main panel of the frame. 044 */ 045 private void setpanel() 046 { 047 universepanel = new UniversePanel(); 048 add( universepanel ); 049 } /** 052 * Sets the menu bar of the frame. 053 */ 054 private void setmenu() 055 { 056 menubar = createmenu(); 057 this.setjmenubar( menubar ); 058 simulation.setenabled( false ); 059 view.setenabled( false ); 060 } Devin Kwok: Dossier 2008 C: The Program: Page 2 of 185

4 /** 063 * Creates the menu bar of the frame. 064 * 065 created menu bar. 066 */ 067 private JMenuBar createmenu() 068 { 069 JMenuBar menubar = new JMenuBar(); 070 simulation = new SimulationMenu( this, universepanel ); 071 view = new ViewMenu( this, universepanel ); menubar.add( new FileMenu( this, universepanel ) ); 074 menubar.add( simulation ); 075 menubar.add( view ); 076 menubar.add( new HelpMenu( this ) ); return menubar; 079 } /** 082 * Sets the universe component to be displayed by the frame. 083 * 084 component component to be displayed. 085 */ 086 public void setcomponent( UniverseComponent component ) 087 { 088 universepanel.setuniversecomponent( component ); 089 component.updatechanges(); simulation.setenabled( true ); 092 view.setenabled( true ); 093 } /** 096 * Sets the set of rules used by the universe. Currently has no use. 097 * 098 ruleset rules to set to universe. 099 */ 100 public void setrules( RuleSet ruleset ) 101 { 102 rules = ruleset; 103 } /** 106 * Gets the rules currently used by the universe. 107 * 108 rule set used by the universe. 109 */ 110 public RuleSet getrules() 111 { 112 return rules; 113 } /** 116 * Main panel of frame. 117 */ 118 private UniversePanel universepanel; /** 121 * Menu bar of frame. 122 */ 123 private JMenuBar menubar; Devin Kwok: Dossier 2008 C: The Program: Page 3 of 185

5 /** 126 * Simulation menu reference for enabling purposes. 127 */ 128 private SimulationMenu simulation; /** 131 * View menu reference for enabling purposes. 132 */ 133 private ViewMenu view; /** 136 * Rule set currently in use by simulation program. 137 */ 138 private RuleSet rules; /** 141 * Default frame width. 142 */ 143 private static final int FRAME_WIDTH = 500; /** 146 * Default frame height. 147 */ 148 private static final int FRAME_HEIGHT = 400; /** 151 * Title of frame. 152 */ 153 public static final String FRAME_TITLE = "Universal Simulator 1.0"; /** 156 * File menu name. 157 */ 158 public static final String FILE_MENU = "File"; /** 161 * Simulation menu name. 162 */ 163 public static final String SIMULATION_MENU = "Simulation"; /** 166 * View menu name. 167 */ 168 public static final String VIEW_MENU = "View"; /** 171 * Help menu name. 172 */ 173 public static final String HELP_MENU = "Help"; /** 176 * Dialog "Ok" button name. 177 */ 178 public static final String OK = "Ok"; /** 181 * Dialog "Cancel" button name. 182 */ 183 public static final String CANCEL = "Cancel"; 184 } Devin Kwok: Dossier 2008 C: The Program: Page 4 of 185

6 C.I.ii: Package: com.gmai.kwok.devin.gui Class: Resource 01 package com.gmail.kwok.devin.gui; /** 04 * A class containing static final fields which are resources to be used by the 05 * program. 06 * 07 Devin Kwok 08 * 09 */ 10 public class Resource 11 { 12 /** 13 * Maximum string length of file fields. 14 */ 15 public static final int MAX_STRING_LENGTH = 15; /** 18 * File extension for universe files. 19 */ 20 public static final String FILE_EXTENSION = "uni"; /** 23 * Cursor icon for drag tool. 24 */ 25 public static final String DRAG_ICON = "hand_cursor.gif"; /** 28 * Cursor icon for edit tool. 29 */ 30 public static final String EDIT_ICON = "mangifying_glass_cursor.gif"; /** 33 * Icon for stepping simulation button. 34 */ 35 public static final String STEP_ICON = "step_icon.gif"; /** 38 * Icon for running simulation button. 39 */ 40 public static final String RUN_ICON = "run_icon.gif"; /** 43 * Icon for stopping simulation button. 44 */ 45 public static final String STOP_ICON = "stop_icon.gif"; /** 48 * HTML page of contents for help section. 49 */ 50 public static final String HELP_CONTENTS = "User's Manual.html"; 51 } Devin Kwok: Dossier 2008 C: The Program: Page 5 of 185

7 Class: StateTable 001 package com.gmail.kwok.devin.gui; import java.awt.dimension; import javax.swing.joptionpane; 006 import javax.swing.jtable; 007 import javax.swing.listselectionmodel; 008 import javax.swing.event.listselectionlistener; 009 import javax.swing.table.abstracttablemodel; import com.gmail.kwok.devin.gui.graphics.stategraphic; 012 import com.gmail.kwok.devin.gui.panel.universepanel; 013 import com.gmail.kwok.devin.universe.change.change; 014 import com.gmail.kwok.devin.universe.change.stackoverflowexception; /** 017 * A table component for displaying the states within a universe. May also 018 * display cell values at a given cell address and modify them. 019 * 020 Devin Kwok 021 * 022 */ 023 public class StateTable extends JTable 024 { 025 /** 026 * 027 */ 028 private static final long serialversionuid = 1L; /** 031 * Constructs a new state table. 032 * 033 states states to display 034 panel panel to access other components from. 035 listener listener for list selection. 036 */ 037 public StateTable( StateGraphic[] states, UniversePanel panel, 038 ListSelectionListener listener ) 039 { 040 super(); 041 this.states = states; 042 this.panel = panel; 043 this.celladdress = -1; this.setmodel( new StateTableModel() ); this.setcolumnselectionallowed( false ); 048 this.setrowselectionallowed( true ); 049 this.setselectionmode( ListSelectionModel.SINGLE_SELECTION ); this.getselectionmodel().addlistselectionlistener( listener ); 052 int width = setcolumnwidths(); 053 this.setpreferredscrollableviewportsize( new Dimension( width, this 054.getRowHeight() 055 * states.length ) ); 056 } /** 059 * Sets column widths of table. 060 * Devin Kwok: Dossier 2008 C: The Program: Page 6 of 185

8 061 total width of table. 062 */ 063 private int setcolumnwidths() 064 { 065 int total = 0; 066 for( int i = 0; i < this.getcolumncount(); i++ ) 067 { 068 int width = COLUMN_NAMES[ i ].length() * CHAR_MULTIPLIER; 069 total = total + width; 070 this.getcolumn( COLUMN_NAMES[ i ] ).setpreferredwidth( width ); 071 } 072 return total; 073 } /** 076 * Gets the cell address currently set to the table. 077 * 078 cell address of table. 079 */ 080 public int getcelladdress() 081 { 082 return celladdress; 083 } /** 086 * Sets the cell address currently set to the table. This causes the table 087 * to display the state values at that address. 088 * 089 celladdress cell address of table. 090 */ 091 public void setcelladdress( int celladdress ) 092 { 093 this.celladdress = celladdress; 094 this.validate(); 095 } /** 098 * State graphic objects that the table displays. 099 */ 100 private StateGraphic[] states; /** 103 * Universe panel where some functions are accessed. 104 */ 105 private UniversePanel panel; /** 108 * Table's current cell address. The table displays default values if this 109 * value is */ 111 private int celladdress; /** 114 * Number of columns in table. 115 */ 116 private static final int COLUMNS = 6; /** 119 * Index of the editable column in the table. 120 */ 121 private static final int EDITABLE = 5; /** Devin Kwok: Dossier 2008 C: The Program: Page 7 of 185

9 124 * Multiplier for finding the width of columns. 125 */ 126 private static final int CHAR_MULTIPLIER = 7; /** 129 * Column headings. 130 */ 131 private static final String[] COLUMN_NAMES = { "Key", "Type ", "Min", 132 "Max", "Continuous", "Value" }; /** 135 * Custom implemented table model for the state table. 136 * 137 Devin Kwok 138 * 139 */ 140 private class StateTableModel extends AbstractTableModel 141 { 142 /** 143 * 144 */ 145 private static final long serialversionuid = 1L; /** 148 * Returns column count. 149 */ 151 public int getcolumncount() 152 { 153 return COLUMNS; 154 } /** 157 * Returns row count. 158 */ 160 public int getrowcount() 161 { 162 return states.length; 163 } /** 166 * Returns the value at the specified row and column index. The return 167 * values are as follows for column indexes: 0: state key, 1: state 168 * type, 2: minimum value, 3: maximum value, 4: is continuous coloring, 169 * 5: value at the given cell address or default value of state if the 170 * cell address is */ 173 public Object getvalueat( int rowindex, int columnindex ) 174 { 175 // state type 176 if( columnindex == 1 ) 177 { 178 return states[ rowindex ].getstate().getdefinition() 179.getType(); 180 } // minimum value 183 if( columnindex == 2 ) 184 return states[ rowindex ].getstate().getdefinition().getmin(); // maximum value Devin Kwok: Dossier 2008 C: The Program: Page 8 of 185

10 187 if( columnindex == 3 ) 188 return states[ rowindex ].getstate().getdefinition().getmax(); // continuous 191 if( columnindex == 4 ) 192 { 193 return states[ rowindex ].iscontinuous(); 194 } // value or default value 197 if( columnindex == 5 ) 198 { 199 return states[ rowindex ].getstate().getvalue( celladdress ); 200 } // state key 203 return states[ rowindex ].getstate().getdefinition() 204.getStateKey(); 205 } /** 208 * Returns column names. 209 */ 210 public String getcolumnname( int column ) 211 { 212 return COLUMN_NAMES[ column ]; 213 } /** 216 * Returns the class associated with the column's values. 217 */ 218 public Class getcolumnclass( int c ) 219 { 220 return getvalueat( 0, c ).getclass(); 221 } /** 224 * Returns whether a cell is editable. Only editable if it is in the 225 * EDITABLE column and the cell address is not */ 227 public boolean iscelleditable( int row, int col ) 228 { 229 if( celladdress == -1 ) 230 return false; if( col == EDITABLE 233 && states[ row ].getstate().getdefinition() 234.isModifiable() ) 235 return true; return false; 238 } /** 241 * Sets the value at the given location. Assumes this is in the EDITABLE 242 * column. Adds teh appropriate change to the universe and updates the 243 * graphics components. 244 */ 245 public void setvalueat( Object value, int row, int col ) 246 { 247 // assume must be column 5 where celladdress!= double changevalue = (Double) value states[ row ].getstate().getvalue( celladdress ); Devin Kwok: Dossier 2008 C: The Program: Page 9 of 185

11 250 try 251 { 252 Change change = states[ row ].getstate().limitchange( 253 new Change( row, celladdress, changevalue ) ); 254 panel.getuniversecomponent().addchange( change ); 255 panel.getuniversecomponent().updatechanges(); 256 panel.getuniversecomponent().repaint(); 257 } 258 catch( StackOverflowException e ) 259 { 260 JOptionPane.showMessageDialog( panel, OVERFLOW_MESSAGE, 261 "Simulation Error", JOptionPane.ERROR_MESSAGE ); 262 } 263 } /** 266 * Overflow message displayed in the case of a change stack error. 267 */ 268 private static final String OVERFLOW_MESSAGE = "Unable to set value."; 269 } 270 } Devin Kwok: Dossier 2008 C: The Program: Page 10 of 185

12 C.I.iii: Package: com.gmai.kwok.devin.gui.frame.menu Class: FileMenu 001 package com.gmail.kwok.devin.gui.frame.menu; import java.awt.event.actionevent; 004 import java.awt.event.actionlistener; import javax.swing.jmenu; 007 import javax.swing.jmenuitem; 008 import javax.swing.joptionpane; import com.gmail.kwok.devin.file.universereader; 011 import com.gmail.kwok.devin.file.universewriter; 012 import com.gmail.kwok.devin.gui.component.universe2dcomponent; 013 import com.gmail.kwok.devin.gui.component.universecomponent; 014 import com.gmail.kwok.devin.gui.frame.universeframe; 015 import com.gmail.kwok.devin.gui.graphics.stategraphic; 016 import com.gmail.kwok.devin.gui.panel.universepanel; 017 import com.gmail.kwok.devin.universe.universe; 018 import com.gmail.kwok.devin.universe.universe2d; 019 import com.gmail.kwok.devin.universe.state.state; /** 022 * The file menu for the dossier program. 023 * 024 Devin Kwok 025 * 026 */ 027 public class FileMenu extends JMenu 028 { 029 /** 030 * 031 */ 032 private static final long serialversionuid = 1L; /** 035 * Constructs a new file menu. 036 * 037 frame frame to open dialogs within. 038 panel universe panel which contains needed functions. 039 */ 040 public FileMenu( UniverseFrame frame, UniversePanel panel ) 041 { 042 super( UniverseFrame.FILE_MENU ); 043 this.frame = frame; 044 this.panel = panel; 045 save = createsaveitem(); 046 save.setenabled( false ); add( createnewitem() ); 049 add( createopenitem() ); 050 add( save ); 051 add( createfileexititem() ); 052 } /** 055 * Creates a "New" item for creating new universes. 056 * 057 menu item. Devin Kwok: Dossier 2008 C: The Program: Page 11 of 185

13 058 */ 059 public JMenuItem createnewitem() 060 { 061 JMenuItem item = new JMenuItem( "New..." ); class MenuItemListener implements ActionListener 064 { 065 public void actionperformed( ActionEvent event ) 066 { 067 try 068 { 069 int rows = Integer.parseInt( JOptionPane.showInputDialog( 070 frame, "Enter universe rows:" ) ); 071 if( rows < 1 ) 072 throw new NumberFormatException(); 073 int columns = Integer.parseInt( JOptionPane 074.showInputDialog( frame, 075 "Enter universe columns:" ) ); 076 if( columns < 1 ) 077 throw new NumberFormatException(); Universe universe = new Universe2D( frame.getrules() 080.getStateDefinitions(), frame.getrules() 081.getIndependentRules(), rows, columns ); 082 universe.setdefaultboundary(); UniverseComponent component = new Universe2DComponent( 085 (Universe2D) universe, frame.getrules() 086.getDefaultGraphics( universe ) ); 087 frame.setcomponent( component ); 088 save.setenabled( true ); 089 } 090 catch( NumberFormatException e ) 091 { 092 JOptionPane.showMessageDialog( frame, 093 "Integer value > 0 required", "Error", 094 JOptionPane.ERROR_MESSAGE ); 095 } 096 } 097 } ActionListener listener = new MenuItemListener(); 100 item.addactionlistener( listener ); 101 return item; 102 } /** 105 * Creates an "Open" item for opening universe files. 106 * 107 menu item. 108 */ 109 private JMenuItem createopenitem() 110 { 111 JMenuItem item = new JMenuItem( "Open..." ); class MenuItemListener implements ActionListener 114 { 115 public void actionperformed( ActionEvent event ) 116 { 117 new UniverseReader( frame.getrules(), frame ); 118 if( panel.getuniversecomponent()!= null ) 119 save.setenabled( true ); 120 } Devin Kwok: Dossier 2008 C: The Program: Page 12 of 185

14 121 } ActionListener listener = new MenuItemListener(); 124 item.addactionlistener( listener ); 125 return item; 126 } /** 129 * Creates a "Save" item for saving the currently opened universe. 130 * 131 menu item. 132 */ 133 private JMenuItem createsaveitem() 134 { 135 JMenuItem item = new JMenuItem( "Save..." ); class MenuItemListener implements ActionListener 138 { 139 public void actionperformed( ActionEvent event ) 140 { 141 StateGraphic[] graphics = panel.getuniversecomponent() 142.getStateGraphics(); 143 Sta te[] states = new State[ graphics.length ]; 144 for( int i = 0; i < graphics.length; i++ ) 145 { 146 states[ i ] = graphics[ i ].getstate(); 147 } new UniverseWriter( states, panel.getuniversecomponent() 150.getUniverseProperties(), frame ); 151 } 152 } ActionListener listener = new MenuItemListener(); 155 item.addactionlistener( listener ); 156 return item; 157 } /** 160 * Creates an "exit" item for closing the program. 161 * 162 menu item. 163 */ 164 public JMenuItem createfileexititem() 165 { 166 JMenuItem item = new JMenuItem( "Exit" ); class MenuItemListener implements ActionListener 169 { 170 public void actionperformed( ActionEvent event ) 171 { 172 System.exit( 0 ); 173 } 174 } ActionListener listener = new MenuItemListener(); 177 item.addactionlistener( listener ); 178 return item; 179 } /** 182 * Reference to the "Save" item for enabling purposes. 183 */ Devin Kwok: Dossier 2008 C: The Program: Page 13 of 185

15 184 private JMenuItem save; /** 187 * Reference to the enclosing frame for opening dialogs. 188 */ 189 private UniverseFrame frame; /** 192 * Reference to the universe panel for various functions. 193 */ 194 private UniversePanel panel; 195 } Devin Kwok: Dossier 2008 C: The Program: Page 14 of 185

16 Class: HelpMenu 01 package com.gmail.kwok.devin.gui.frame.menu; import java.awt.event.actionevent; 04 import java.awt.event.actionlistener; import javax.swing.boxlayout; 07 import javax.swing.jdialog; 08 import javax.swing.jlabel; 09 import javax.swing.jmenu; 10 import javax.swing.jmenuitem; 11 import javax.swing.jpanel; import com.gmail.kwok.devin.gui.frame.universeframe; 14 import com.gmail.kwok.devin.gui.frame.menu.dialog.helpframe; /** 17 * The help menu for the dossier program. 18 * 19 Devin Kwok 20 * 21 */ 22 public class HelpMenu extends JMenu 23 { 24 /** 25 * 26 */ 27 private static final long serialversionuid = 1L; /** 30 * Constructs a new help menu. 31 * 32 frame frame to open dialogs within. 33 */ 34 public HelpMenu( UniverseFrame frame ) 35 { 36 super( UniverseFrame.HELP_MENU ); 37 this.frame = frame; 38 add( createcontentsitem() ); 39 add( createaboutitem() ); 40 } /** 43 * Creates a "Contents" item for displaying the help contents. 44 * 45 menu item. 46 */ 47 private JMenuItem createcontentsitem() 48 { 49 JMenuItem item = new JMenuItem( "Contents..." ); class MenuItemListener implements ActionListener 52 { 53 public void actionperformed( ActionEvent event ) 54 { 55 HelpFrame dialog = new HelpFrame( frame ); 56 dialog.setvisible( true ); 57 } 58 } ActionListener listener = new MenuItemListener(); Devin Kwok: Dossier 2008 C: The Program: Page 15 of 185

17 61 item.addactionlistener( listener ); 62 return item; 63 } /** 66 * Creates an "About" item for displaying developer information. 67 * 68 menu item. 69 */ 70 private JMenuItem createaboutitem() 71 { 72 JMenuItem item = new JMenuItem( "About..." ); class MenuItemListener implements ActionListener 75 { 76 public void actionperformed( ActionEvent event ) 77 { 78 JDialog dialog = new JDialog( frame, "About" ); 79 JPanel panel = new JPanel(); 80 panel.setlayout( new BoxLayout( panel, BoxLayout.Y_AXIS ) ); 81 panel.add( new JLabel( " " + UniverseFrame.FRAME_TITLE ) ); 82 panel.add( new JLabel( " Created by Devin Kwok" ) ); 83 panel.add( new JLabel( " For the 2008 IB HL Dossier" ) ); 84 panel.add( new JLabel( " March 31, 2008" ) ); 85 dialog.add( panel ); 86 dialog.pack(); 87 dialog.setvisible( true ); 88 } 89 } ActionListener listener = new MenuItemListener(); 92 item.addactionlistener( listener ); 93 return item; 94 } 95 /** 96 * Reference to the enclosing frame for opening dialogs. 97 */ 98 private UniverseFrame frame; 99 } Devin Kwok: Dossier 2008 C: The Program: Page 16 of 185

18 Class: SimulationMenu 001 package com.gmail.kwok.devin.gui.frame.menu; import java.awt.event.actionevent; 004 import java.awt.event.actionlistener; import javax.swing.jmenu; 007 import javax.swing.jmenuitem; import com.gmail.kwok.devin.gui.frame.universeframe; 010 import com.gmail.kwok.devin.gui.frame.menu.dialog.simulationspeeddialog; 011 import com.gmail.kwok.devin.gui.panel.universepanel; /** 014 * The simulation menu for the dossier program. 015 * 016 Devin Kwok 017 * 018 */ 019 public class SimulationMenu extends JMenu 020 { 021 /** 022 * 023 */ 024 private static final long serialversionuid = 1L; /** 027 * Constructs a new simulation menu. 028 * 029 frame frame to open dialogs within. 030 panel universe panel which contains needed functions. 031 */ 032 public SimulationMenu( UniverseFrame frame, UniversePanel panel ) 033 { 034 super( UniverseFrame.SIMULATION_MENU ); this.frame = frame; 037 this.panel = panel; step = createstepitem(); 040 run = createrunitem(); 041 stop = createstopitem(); 042 stop.setenabled( false ); add( step ); 045 add( run ); 046 add( stop ); 047 add( createresetitem() ); 048 add( createspeeditem() ); 049 } /** 052 * Creates a "Step" item for incrementing the simulation by 1 generation. 053 * 054 menu item. 055 */ 056 private JMenuItem createstepitem() 057 { 058 JMenuItem item = new JMenuItem( "Step Simulation" ); class MenuItemListener implements ActionListener Devin Kwok: Dossier 2008 C: The Program: Page 17 of 185

19 061 { 062 public void actionperformed( ActionEvent event ) 063 { 064 panel.gettimer().nextgeneration(); 065 } 066 } ActionListener listener = new MenuItemListener(); 069 item.addactionlistener( listener ); 070 return item; 071 } /** 074 * Creates a "Run" item for running the simulation. 075 * 076 menu item. 077 */ 078 private JMenuItem createrunitem() 079 { 080 JMenuItem item = new JMenuItem( "Run Simulation" ); class MenuItemListener implements ActionListener 083 { 084 public void actionperformed( ActionEvent event ) 085 { 086 panel.gettimer().runsimulation(); 087 panel.notifycomponents(); 088 step.setenabled( false ); 089 run.setenabled( false ); 090 stop.setenabled( true ); 091 } 092 } ActionListener listener = new MenuItemListener(); 095 item.addactionlistener( listener ); 096 return item; 097 } /** 100 * Creates a "Stop" item for stopping the simulation. 101 * 102 menu item. 103 */ 104 private JMenuItem createstopitem() 105 { 106 JMenuItem item = new JMenuItem( "Stop Simulation" ); class MenuItemListener implements ActionListener 109 { 110 public void actionperformed( ActionEvent event ) 111 { 112 panel.gettimer().stopsimulation(); 113 panel.notifycomponents(); 114 step.setenabled( true ); 115 run.setenabled( true ); 116 stop.setenabled( false ); 117 } 118 } ActionListener listener = new MenuItemListener(); 121 item.addactionlistener( listener ); 122 return item; 123 } Devin Kwok: Dossier 2008 C: The Program: Page 18 of 185

20 /** 126 * Creates a "Reset" item which resets the generation counter. 127 * 128 menu item. 129 */ 130 private JMenuItem createresetitem() 131 { 132 JMenuItem item = new JMenuItem( "Reset Counter" ); class MenuItemListener implements ActionListener 135 { 136 public void actionperformed( ActionEvent event ) 137 { 138 panel.gettimer().resetgenerationcount(); 139 } 140 } ActionListener listener = new MenuItemListener(); 143 item.addactionlistener( listener ); 144 return item; 145 } /** 148 * Creates a "Speed" item for modifying the simulation speed. 149 * 150 menu item. 151 */ 152 private JMenuItem createspeeditem() 153 { 154 JMenuItem item = new JMenuItem( "Simulation Speed..." ); class MenuItemListener implements ActionListener 157 { 158 public void actionperformed( ActionEvent event ) 159 { 160 SimulationSpeedDialog dialog = new SimulationSpeedDialog( 161 frame, panel, true ); 162 dialog.setvisible( true ); 163 } 164 } ActionListener listener = new MenuItemListener(); 167 item.addactionlistener( listener ); 168 return item; 169 } /** 172 * Reference to the menu item for enabling purposes. 173 */ 174 private JMenuItem step; /** 177 * Reference to the menu item for enabling purposes. 178 */ 179 private JMenuItem run; /** 182 * Reference to the menu item for enabling purposes. 183 */ 184 private JMenuItem stop; /** Devin Kwok: Dossier 2008 C: The Program: Page 19 of 185

21 187 * Reference to the enclosing frame for opening dialogs. 188 */ 189 private UniverseFrame frame; /** 192 * Reference to the universe panel for various functions. 193 */ 194 private UniversePanel panel; 195 } Devin Kwok: Dossier 2008 C: The Program: Page 20 of 185

22 Class: ViewMenu 01 package com.gmail.kwok.devin.gui.frame.menu; import java.awt.event.actionevent; 04 import java.awt.event.actionlistener; import javax.swing.jmenu; 07 import javax.swing.jmenuitem; import com.gmail.kwok.devin.gui.frame.universeframe; 10 import com.gmail.kwok.devin.gui.frame.menu.dialog.zoomdialog; 11 import com.gmail.kwok.devin.gui.panel.universepanel; /** 14 * The view menu for the dossier program. 15 * 16 Devin Kwok 17 * 18 */ 19 public class ViewMenu extends JMenu 20 { 21 /** 22 * 23 */ 24 private static final long serialversionuid = 1L; /** 27 * Constructs a new view menu. 28 * 29 frame frame to open dialogs within. 30 panel universe panel which contains needed functions. 31 */ 32 public ViewMenu( UniverseFrame frame, UniversePanel panel ) 33 { 34 super( UniverseFrame.VIEW_MENU ); 35 this.frame = frame; 36 this.panel = panel; 37 add( createstatesitem() ); 38 add( createzoomitem() ); 39 } /** 42 * Creates a "States" item for managing state displays. Currently 43 * incomplete. 44 * 45 menu item. 46 */ 47 private JMenuItem createstatesitem() 48 { 49 JMenuItem item = new JMenuItem( "State display..." ); class MenuItemListener implements ActionListener 52 { 53 public void actionperformed( ActionEvent event ) 54 { 55 // TODO 56 } 57 } ActionListener listener = new MenuItemListener(); 60 item.addactionlistener( listener ); Devin Kwok: Dossier 2008 C: The Program: Page 21 of 185

23 61 return item; 62 } /** 65 * Creates a "Zoom" item for modifying the size of the cells displayed by 66 * the universe component. 67 * 68 menu item. 69 */ 70 private JMenuItem createzoomitem() 71 { 72 JMenuItem item = new JMenuItem( "Zoom..." ); class MenuItemListener implements ActionListener 75 { 76 public void actionperformed( ActionEvent event ) 77 { 78 ZoomDialog dialog = new ZoomDialog( frame, panel, true ); 79 dialog.setvisible( true ); 80 } 81 } ActionListener listener = new MenuItemListener(); 84 item.addactionlistener( listener ); 85 return item; 86 } /** 89 * Reference to the enclosing frame for opening dialogs. 90 */ 91 private UniverseFrame frame; /** 94 * Reference to the universe panel for various functions. 95 */ 96 private UniversePanel panel; 97 } Devin Kwok: Dossier 2008 C: The Program: Page 22 of 185

24 C.I.iv: Package: com.gmai.kwok.devin.gui.frame.menu.dialog Class: HelpFrame 01 package com.gmail.kwok.devin.gui.frame.menu.dialog; import java.io.ioexception; 04 import java.net.url; import javax.swing.jeditorpane; 07 import javax.swing.jframe; 08 import javax.swing.joptionpane; 09 import javax.swing.jscrollpane; import com.gmail.kwok.devin.gui.resource; 12 import com.gmail.kwok.devin.gui.frame.universeframe; /** 15 * A frame which shows the help file. 16 * 17 Devin Kwok 18 * 19 */ 20 public class HelpFrame extends JFrame 21 { 22 /** 23 * 24 */ 25 private static final long serialversionuid = 1L; /** 28 * Creates a new help frame. 29 * 30 frame frame to display dialogs from. 31 */ 32 public HelpFrame( UniverseFrame frame ) 33 { 34 super( "Help" ); JEditorPane editorpane = new JEditorPane(); 37 editorpane.seteditable( false ); JScrollPane editorscrollpane = new JScrollPane( editorpane ); 40 this.add( editorscrollpane ); 41 this.setsize( FRAME_WIDTH, FRAME_HEIGHT ); 42 sethelpfile( editorpane, frame ); 43 } /** 46 * Sets the help file. 47 * 48 editorpane editor pane to set file to. 49 frame frame to set dialogs to. 50 */ 51 private void sethelpfile( JEditorPane editorpane, UniverseFrame frame ) 52 { 53 URL url = this.getclass().getresource( Resource.HELP_CONTENTS ); 54 if( url!= null ) 55 { 56 try 57 { Devin Kwok: Dossier 2008 C: The Program: Page 23 of 185

25 58 editorpane.setpage( url ); 59 } 60 catch( IOException ioexception ) 61 { 62 JOptionPane.showMessageDialog( frame, "Bad URL", "Bad URL", 63 JOptionPane.ERROR_MESSAGE ); 64 } 65 } 66 else 67 { 68 JOptionPane.showMessageDialog( frame, "File Not Found", 69 "File Not Found", JOptionPane.ERROR_MESSAGE ); 70 } 71 } /** 74 * Width of frame. 75 */ 76 private static final int FRAME_WIDTH = 800; /** 79 * Height of frame. 80 */ 81 private static final int FRAME_HEIGHT = 600; 82 } Devin Kwok: Dossier 2008 C: The Program: Page 24 of 185

26 Class: SimulationSpeedDialog 001 package com.gmail.kwok.devin.gui.frame.menu.dialog; import java.awt.flowlayout; 004 import java.awt.event.actionevent; 005 import java.awt.event.actionlistener; import javax.swing.boxlayout; 008 import javax.swing.buttongroup; 009 import javax.swing.jbutton; 010 import javax.swing.jdialog; 011 import javax.swing.jpanel; 012 import javax.swing.jradiobutton; 013 import javax.swing.jspinner; 014 import javax.swing.spinnernumbermodel; import com.gmail.kwok.devin.gui.frame.universeframe; 017 import com.gmail.kwok.devin.gui.panel.generationtimer; 018 import com.gmail.kwok.devin.gui.panel.universepanel; /** 021 * A dialog which controls simulation speed. 022 * 023 Devin Kwok 024 * 025 */ 026 public class SimulationSpeedDialog extends JDialog 027 { 028 /** 029 * 030 */ 031 private static final long serialversionuid = 1L; /** 034 * Creates a new dialog. 035 * 036 frame frame to open dialogs within. 037 panel universe panel which contains needed functions. 038 ismodal when true, prevents the user from accessing the frame 039 * below. 040 */ 041 public SimulationSpeedDialog( UniverseFrame frame, 042 UniversePanel universepanel, boolean ismodal ) 043 { 044 super( frame, "Simulation Speed", ismodal ); 045 this.universepanel = universepanel; inputspinner = new JSpinner(); 048 setdelayspinnermodel(); JPanel panel = new JPanel( new FlowLayout() ); 051 panel.add( createradiobuttonpanel() ); 052 panel.add( inputspinner ); 053 panel.add( createokpanel() ); this.add( panel ); 056 setsize( DIALOG_WIDTH, DIALOG_HEIGHT ); 057 setresizable( false ); 058 } /** Devin Kwok: Dossier 2008 C: The Program: Page 25 of 185

27 061 * Creates a panel allowing the user to close the dialog with or without 062 * changes. 063 * 064 panel. 065 */ 066 private JPanel createokpanel() 067 { 068 JPanel panel = new JPanel(); 069 panel.add( createbutton( UniverseFrame.OK ) ); 070 panel.add( createbutton( UniverseFrame.CANCEL ) ); 071 return panel; 072 } /** 075 * Creates a panel with radio buttons for choosing delay or skip. 076 * 077 radio button panel. 078 */ 079 private JPanel createradiobuttonpanel() 080 { 081 JPanel panel = new JPanel(); 082 panel.setlayout( new BoxLayout( panel, BoxLayout.Y_AXIS ) ); 083 JRadioButton delay = createradiobutton( DELAY ); 084 delay.setselected( true ); 085 JRadioButton skip = createradiobutton( SKIP ); ButtonGroup buttongroup = new ButtonGroup(); 088 buttongroup.add( delay ); 089 buttongroup.add( skip ); panel.add( delay ); 092 panel.add( skip ); 093 return panel; 094 } /** 097 * Creates a radio button with the specified name. 098 * 099 name name of button. 100 radio button. 101 */ 102 private JRadioButton createradiobutton( String name ) 103 { 104 JRadioButton button = new JRadioButton( name ); class ButtonListener implements ActionListener 107 { 108 public void actionperformed( ActionEvent event ) 109 { 110 JRadioButton source = (JRadioButton) event.getsource(); 111 String s = source.gettext(); 112 if( s.equals( DELAY ) ) 113 setdelayspinnermodel(); 114 else 115 setskipspinnermodel(); 116 } 117 } 118 button. addactionlistener( new ButtonListener() ); 119 return button; 120 } /** 123 * Creates a button with the specified name. Devin Kwok: Dossier 2008 C: The Program: Page 26 of 185

28 124 * 125 name name of button. 126 button. 127 */ 128 private JButton createbutton( String name ) 129 { 130 JButton button = new JButton( name ); class ButtonListener implements ActionListener 133 { 134 public void actionperformed( ActionEvent event ) 135 { 136 JButton source = (JButton) event.getsource(); 137 String s = source.gettext(); 138 if( s.equals( UniverseFrame.OK ) ) 139 settimervalue(); 140 setvisible( false ); 141 } 142 } 143 button.addactionlistener( new ButtonListener() ); 144 return button; 145 } /** 148 * Sets the spinner model to change the delay between generations. 149 */ 150 private void setdelayspinnermodel() 151 { 152 inputspinner.setmodel( new SpinnerNumberModel( universepanel 153.getTimer().getDelay(), GenerationTimer.DELAY_MIN, 154 GenerationTimer.DELAY_MAX, GenerationTimer.DELAY_INCREMENT ) ); 155 isdelay = true; 156 } /** 159 * Sets the spinner model to change the number of generations that are not 160 * displayed. 161 */ 162 private void setskipspinnermodel() 163 { 164 inputspinner.setmodel( new SpinnerNumberModel( universepanel 165.getTimer().getUpdateSkip(), GenerationTimer.SKIP_MIN, 166 GenerationTimer.SKIP_MAX, GenerationTimer.SKIP_INCREMENT ) ); 167 isdelay = false; 168 } /** 171 * Sets the timer to the values set by the user in this dialog. 172 */ 173 private void settimervalue() 174 { 175 int value = (Integer) inputspinner.getvalue(); 176 GenerationTimer timer = universepanel.gettimer(); timer.setdelay( 0 ); 179 timer.setupdateskip( 0 ); 180 if( isdelay ) 181 timer.setdelay( value ); 182 else 183 timer.setupdateskip( value ); universepanel.notifycomponents(); 186 System.out.println( this.getsize() ); Devin Kwok: Dossier 2008 C: The Program: Page 27 of 185

29 187 } /** 190 * Reference to the universe panel for various functions. 191 */ 192 private UniversePanel universepanel; /** 195 * Spinner for inputting values. 196 */ 197 private JSpinner inputspinner; /** 200 * When true, the spinner adjusts the delay. Otherwise the generation skip 201 * is adjusted. 202 */ 203 private boolean isdelay; /** 206 * Name of delay button. 207 */ 208 private static final String DELAY = "Milisecond Delay"; /** 211 * Name of skip button. 212 */ 213 private static final String SKIP = "Generations to Skip"; /** 216 * Width of dialog. 217 */ 218 private static final int DIALOG_WIDTH = 170; /** 221 * Height of dialog. 222 */ 223 private static final int DIALOG_HEIGHT = 160; 224 } Devin Kwok: Dossier 2008 C: The Program: Page 28 of 185

30 Class: ZoomDialog 001 package com.gmail.kwok.devin.gui.frame.menu.dialog; import java.awt.flowlayout; 004 import java.awt.event.actionevent; 005 import java.awt.event.actionlistener; import javax.swing.jbutton; 008 import javax.swing.jdialog; 009 import javax.swing.jlabel; 010 import javax.swing.jpanel; 011 import javax.swing.jspinner; 012 import javax.swing.spinnernumbermodel; import com.gmail.kwok.devin.gui.component.universecomponent; 015 import com.gmail.kwok.devin.gui.frame.universeframe; 016 import com.gmail.kwok.devin.gui.panel.universepanel; /** 019 * A dialog for controlling the zoom of the simulation. 020 * 021 Devin Kwok 022 * 023 */ 024 public class ZoomDialog extends JDialog 025 { 026 /** 027 * 028 */ 029 private static final long serialversionuid = 1L; /** 032 * Creates a new dialog. 033 * 034 frame frame to open dialogs within. 035 panel universe panel which contains needed functions. 036 ismodal when true, prevents the user from accessing the frame 037 * below. 038 */ 039 public ZoomDialog( UniverseFrame frame, UniversePanel universepanel, 040 boolean ismodal ) 041 { 042 super( frame, "Zoom Control", ismodal ); 043 this.universepanel = universepanel; 044 JPanel panel = new JPanel( new FlowLayout() ); 045 JLabel label1 = new JLabel( "Select zoom desired" ); 046 JLabel label2 = new JLabel( " (% of minimum size):" ); panel.add( label1 ); 049 panel.add( label2 ); 050 panel.add( createspinnerpanel() ); 051 panel.add( createokpanel() ); 052 this.add( panel ); 053 setsize( DIALOG_WIDTH, DIALOG_HEIGHT ); 054 setresizable( false ); 055 } /** 058 * Creates a panel allowing the user to close the dialog with or without 059 * changes. 060 * Devin Kwok: Dossier 2008 C: The Program: Page 29 of 185

31 061 panel. 062 */ 063 private JPanel createokpanel() 064 { 065 JPanel panel = new JPanel(); 066 panel.add( createbutton( UniverseFrame.OK ) ); 067 panel.add( createbutton( UniverseFrame.CANCEL ) ); 068 return panel; 069 } /** 072 * Creates a panel with JSpinners. 073 * 074 panel. 075 */ 076 private JPanel createspinnerpanel() 077 { 078 JPanel panel = new JPanel(); UniverseComponent component = universepanel.getuniversecomponent(); inputspinner = new JSpinner( new SpinnerNumberModel( component 083.getCellSize() 084 * MULTIPLIER, component.getmincellsize() * MULTIPLIER, 085 component.getmaxcellsize() * MULTIPLIER, MULTIPLIER ) ); panel.add( inputspinner ); 088 return panel; 089 } /** 092 * Creates a button with the specified name. 093 * 094 name name of button. 095 button. 096 */ 097 private JButton createbutton( String name ) 098 { 099 JButton button = new JButton( name ); class ButtonListener implements ActionListener 102 { 103 public void actionperformed( ActionEvent event ) 104 { 105 JButton source = (JButton) event.getsource(); 106 String s = source.gettext(); 107 if( s.equals( UniverseFrame.OK ) ) 108 setzoomvalue(); 109 setvisible( false ); 110 } 111 } 112 button.addactionlistener( new ButtonListener() ); 113 return button; 114 } /** 117 * Sets the zoom value as specified by the user in this dialog. 118 */ 119 private void setzoomvalue() 120 { 121 int value = (Integer) inputspinner.getvalue(); 122 universepanel.getuniversecomponent().setcellsize( value / MULTIPLIER ); 123 universepanel.notifycomponents(); Devin Kwok: Dossier 2008 C: The Program: Page 30 of 185

32 124 universepanel.getscrollpane().getviewport().setview( 125 universepanel.getuniversecomponent() ); 126 System.out.println( this.getsize() ); 127 } /** 130 * Reference to the universe panel for various functions. 131 */ 132 private UniversePanel universepanel; /** 135 * Spinner for inputting values. 136 */ 137 private JSpinner inputspinner; /** 140 * Zoom multiplier for converting betweeen zoom value and pixel cell size. 141 */ 142 private static final int MULTIPLIER = 100; /** 145 * Width of dialog. 146 */ 147 private static final int DIALOG_WIDTH = 170; /** 150 * Height of dialog. 151 */ 152 private static final int DIALOG_HEIGHT = 160; 153 } Devin Kwok: Dossier 2008 C: The Program: Page 31 of 185

33 C.I.v Package: com.gmai.kwok.devin.gui.panel Class: UniversePanel 001 package com.gmail.kwok.devin.gui.panel; import java.awt.borderlayout; 004 import java.awt.dimension; 005 import java.awt.event.mouseevent; 006 import java.awt.event.mouselistener; 007 import java.awt.event.mousemotionlistener; import javax.swing.jcomponent; 010 import javax.swing.jpanel; 011 import javax.swing.jscrollpane; 012 import javax.swing.jtoolbar; import com.gmail.kwok.devin.gui.component.emptycomponent; 015 import com.gmail.kwok.devin.gui.component.universecomponent; 016 import com.gmail.kwok.devin.gui.tool.tool; /** 019 * A panel containing the toolbars and universe component of the program. 020 * 021 Devin Kwok 022 * 023 */ 024 public class UniversePanel extends JPanel 025 { /** 028 * 029 */ 030 private static final long serialversionuid = 1L; /** 033 * Constructs a new panel with no universe component. 034 */ 035 public UniversePanel() 036 { 037 super( new BorderLayout() ); this.component = null ; 040 this.scrollpane = null; 041 this.timer = null; this.actiontoolbar = new ActionToolBar( this ); 044 actiontoolbar.setenabled( false ); this.currenttool = actiontoolbar.gettool( Tool.DEFAULT_TOOL ); 047 this.subpanel = createsubpanel(); add( actiontoolbar, BorderLayout.NORTH ); 050 add( subpanel, BorderLayout.CENTER ); setpreferredsize( new Dimension( 400, 400 ) ); 053 } /** 056 * Creates a sub panel which arranges the toolbars properly. 057 * Devin Kwok: Dossier 2008 C: The Program: Page 32 of 185

34 058 panel. 059 */ 060 private JPanel createsubpanel() 061 { 062 this.toolspecificbar = new JToolBar(); 063 toolspecificbar.add( currenttool.getassociatedpanel() ); 064 JPanel panel = new JPanel( new BorderLayout() ); 065 JComponent emptycomponent = new EmptyComponent(); 066 panel.add( emptycomponent, BorderLayout.CENTER ); 067 panel.add( toolspecificbar, BorderLayout.WEST ); 068 return panel; 069 } /** 072 * Sets the universe component to be displayed in the panel. 073 * 074 component component to be displayed. 075 */ 076 public void setuniversecomponent( UniverseComponent component ) 077 { 078 this.component = component; 079 this.timer = new GenerationTimer( this ); component.addmouselistener( new ComponentMouseListener() ); 082 component.addmousemotionlistener( new ComponentMouseListener() ); 083 if( scrollpane!= null ) 084 subpanel.remove( scrollpane ); 085 scrollpane = new JScrollPane( component ); 086 scrollpane.setpreferredsize( new Dimension( 300, 300 ) ); subpanel.removeall(); 089 subpanel.setlayout( new BorderLayout() ); 090 subpanel.add( scrollpane, BorderLayout.CENTER ); 091 subpanel.add( toolspecificbar, BorderLayout.WEST ); actiontoolbar.setenabled( true ); 094 this.validate(); 095 } /** 098 * Sets the mouse tool. 099 * 100 tool tool to be set. 101 */ 102 public void settool( Tool tool ) 103 { 104 currenttool = tool; 105 toolspecificbar.removeall(); if( tool!= null ) 108 { 109 toolspecificbar.add( tool.getassociatedpanel() ); 110 toolspecificbar.validate(); 111 } component.setcursor( tool.getassociatedcursor() ); 114 } /** 117 * Returns the action tool bar. 118 * 119 tool bar. 120 */ Devin Kwok: Dossier 2008 C: The Program: Page 33 of 185

35 121 public ActionToolBar getactiontoolbar() 122 { 123 return actiontoolbar; 124 } /** 127 * Returns the universe component. 128 * 129 universe component. 130 */ 131 public UniverseComponent getuniversecomponent() 132 { 133 return component; 134 } /** 137 * Returns the timer. 138 * 139 generation timer. 140 */ 141 public GenerationTimer gettimer() 142 { 143 return timer; 144 } /** 147 * Returns the scroll pane around the universe component. 148 * 149 scroll pane. 150 */ 151 public JScrollPane getscrollpane() 152 { 153 return scrollpane; 154 } /** 157 * Notifies all appropriate components about a change. This currently would 158 * be the action tool bar, which needs to be updated when the simulation's 159 * state changes. 160 */ 161 public void notifycomponents() 162 { 163 actiontoolbar.updatetoolbar( timer.isrunning() ); 164 } /** 167 * Sub panel containing the scroll pane and tool specific tool bar. 168 */ 169 private JPanel subpanel; /** 172 * Tool bar allowing the user to manipulate the current tool. 173 */ 174 private ActionToolBar actiontoolbar; /** 177 * Tool bar containing components specific to the current mouse tool. 178 */ 179 private JToolBar toolspecificbar; /** 182 * Universe component displayed in the panel. 183 */ Devin Kwok: Dossier 2008 C: The Program: Page 34 of 185

36 184 private UniverseComponent component; /** 187 * Timer for running the simulation. 188 */ 189 private GenerationTimer timer; /** 192 * Scroll pane containing the universe component. 193 */ 194 private JScrollPane scrollpane; /** 197 * Current mouse tool. 198 */ 199 private Tool currenttool; /** 202 * Component mouse listener for the universe component. Refers to the 203 * current mouse tool. 204 * 205 Devin Kwok 206 * 207 */ 208 private class ComponentMouseListener implements MouseListener, 209 MouseMotionListener 210 { 211 /** 212 * Mouse clicked. 213 */ 215 public void mouseclicked( MouseEvent event ) 216 { 217 currenttool.mouseclicked( event ); 218 } /** 221 * Mouse pressed. 222 */ 224 public void mousepressed( MouseEvent event ) 225 { 226 currenttool.mousepressed( event ); 227 } /** 230 * Mouse released. 231 */ 233 public void mousereleased( MouseEvent event ) 234 { 235 currenttool.mousereleased( event ); 236 } /** 239 * Mouse dragged. 240 */ 242 public void mousedragged( MouseEvent event ) 243 { 244 currenttool.mousedragged( event ); 245 } 246 Devin Kwok: Dossier 2008 C: The Program: Page 35 of 185

37 247 /** 248 * Mouse entered. 249 */ 251 public void mouseentered( MouseEvent event ) 252 { 253 currenttool.mouseentered( event ); 254 } /** 257 * Mouse exoted. 258 */ 260 public void mouseexited( MouseEvent event ) 261 { 262 currenttool.mouseexited( event ); 263 } /** 266 * Mouse moved. 267 */ 269 public void mousemoved( MouseEvent event ) 270 { 271 currenttool.mousemoved( event ); 272 } 273 } 274 } Devin Kwok: Dossier 2008 C: The Program: Page 36 of 185

38 Class: GenerationTimer 001 package com.gmail.kwok.devin.gui.panel; import java.awt.event.actionevent; 004 import java.awt.event.actionlistener; import javax.swing.joptionpane; 007 import javax.swing.timer; import com.gmail.kwok.devin.gui.component.universecomponent; 010 import com.gmail.kwok.devin.universe.change.stackoverflowexception; /** 013 * A timer for running the simulation. 014 * 015 Devin Kwok 016 * 017 */ 018 public class GenerationTimer 019 { 020 /** 021 * Constructs a new timer. 022 * 023 panel universe panel which contains needed functions. 024 */ 025 public GenerationTimer( UniversePanel panel ) 026 { 027 this.panel = panel; 028 this.component = panel.getuniversecomponent(); 029 this.timer = new Timer( DEFAULT_DELAY, new TimerListener() ); 030 this.generation = 0; 031 running = false; 032 } /** 035 * Steps the simulation. 036 */ 037 public void nextgeneration() 038 { 039 stepsimulation( true ); 040 } /** 043 * Steps the simulation. 044 * 045 updategraphics if true, the display is updated. 046 */ 047 private void stepsimulation( boolean updategraphics ) 048 { 049 generation++; 050 try 051 { 052 component.nextgeneration(); 053 } 054 catch( StackOverflowException e ) 055 { 056 stopsimulation(); 057 JOptionPane.showMessageDialog( panel, OVERFLOW_MESSAGE, 058 "Simulation Error", JOptionPane.ERROR_MESSAGE ); 059 } 060 Devin Kwok: Dossier 2008 C: The Program: Page 37 of 185

39 061 panel.notifycomponents(); if( updategraphics ) 064 { 065 component.updatechanges(); 066 component.repaint(); 067 } 068 } /** 071 * Runs the simulation by starting the timer. 072 */ 073 public void runsimulation() 074 { 075 running = true; 076 timer.start(); 077 } /** 080 * Stops the simulation by stopping the timer. 081 */ 082 public void stopsimulation() 083 { 084 running = false; 085 timer.stop(); 086 } /** 089 * Returns the millisecond delay. 090 * 091 delay in milliseconds. 092 */ 093 public int getdelay() 094 { 095 return timer.getdelay(); 096 } /** 099 * Sets the millisecond delay of the timer. 100 * 101 miliseconds delay of timer. 102 */ 103 public void setdelay( int miliseconds ) 104 { 105 timer.setdelay( miliseconds ); 106 } /** 109 * Returns the number of generations where the display is not updated. 110 * 111 generations skipped. 112 */ 113 public int getupdateskip() 114 { 115 return updateskip; 116 } /** 119 * Sets the number of generations where the display is not updated. 120 * 121 updateskip generations skipped. 122 */ 123 public void setupdateskip( int updateskip ) Devin Kwok: Dossier 2008 C: The Program: Page 38 of 185

40 124 { 125 this.updateskip = updateskip; 126 } /** 129 * Returns true if the timer is running. 130 * 131 true if timer is running. 132 */ 133 public boolean isrunning() 134 { 135 return running; 136 } /** 139 * Gets the number of generations that have been generated. 140 * 141 generation count. 142 */ 143 public int getgenerationcount() 144 { 145 return generation; 146 } /** 149 * Sets the generation count to */ 151 public void resetgenerationcount() 152 { 153 generation = 0; 154 panel.notifycomponents(); 155 } /** 158 * Reference to the universe panel for various functions. 159 */ 160 private UniversePanel panel; /** 163 * Universe component containing the universe to be simulated. 164 */ 165 private UniverseComponent component; /** 168 * Timer for running the simulation. 169 */ 170 private Timer timer; /** 173 * Number of generations where the display is not updated. 174 */ 175 private int updateskip; /** 178 * Current generation count. 179 */ 180 private int generation; /** 183 * True if the timer is running. 184 */ 185 private boolean running; 186 Devin Kwok: Dossier 2008 C: The Program: Page 39 of 185

41 187 /** 188 * Default timer delay. 189 */ 190 private static final int DEFAULT_DELAY = 1000; /** 193 * Overflow of change stack error message. 194 */ 195 private static final String OVERFLOW_MESSAGE = "The simulation has" " exceeded its maximum number of changes. This may be caused by" " an excessively large universe or looping rules. To avoid" " further error this universe should be closed."; /** 201 * Minimum delay. 202 */ 203 public static final int DELAY_MIN = 0; /** 206 * Maximum delay. 207 */ 208 public static final int DELAY_MAX = 5000; /** 211 * Increment of delay for use in the speed dialog. 212 */ 213 public static final int DELAY_INCREMENT = 200; /** 216 * Minimum skip. 217 */ 218 public static final int SKIP_MIN = 0; /** 221 * Maximum skip. 222 */ 223 public static final int SKIP_MAX = 50; /** 226 * Increment of skip for use in the speed dialog. 227 */ 228 public static final int SKIP_INCREMENT = 1; /** 231 * Name of step command. 232 */ 233 public static final String STEP = "Step"; /** 236 * Name of run command. 237 */ 238 public static final String RUN = "Run"; /** 241 * Name of stop command. 242 */ 243 public static final String STOP = "Stop"; /** 246 * Listener class for timer which causes the universe to generate the next 247 * generation. 248 * 249 Devin Kwok Devin Kwok: Dossier 2008 C: The Program: Page 40 of 185

42 250 * 251 */ 252 private class TimerListener implements ActionListener 253 { 254 /** 255 * Creates a new listener. 256 */ 257 public TimerListener() 258 { 259 count = 0; 260 } /** 263 * Steps the simulation. When appropriate, causes the display to be 264 * updated. 265 */ 266 public void actionperformed( ActionEvent event ) 267 { 268 if( count >= updateskip ) 269 { 270 stepsimulation( true ); 271 count = -1; 272 } 273 else 274 stepsimulation( false ); 275 count++; 276 } /** 279 * Count which determines when the display should be updated. 280 */ 281 private int count; 282 } 283 } Devin Kwok: Dossier 2008 C: The Program: Page 41 of 185

43 Class: ActionToolBar 001 package com.gmail.kwok.devin.gui.panel; import java.awt.component; 004 import java.awt.flowlayout; 005 import java.awt.event.actionevent; 006 import java.awt.event.actionlistener; import javax.swing.abstractbutton; 009 import javax.swing.boxlayout; 010 import javax.swing.buttongroup; 011 import javax.swing.imageicon; 012 import javax.swing.jbutton; 013 import javax.swing.jlabel; 014 import javax.swing.jpanel; 015 import javax.swing.jtogglebutton; 016 import javax.swing.jtoolbar; 017 import javax.swing.swingconstants; 018 import javax.swing.border.etchedborder; import com.gmail.kwok.devin.gui.resource; 021 import com.gmail.kwok.devin.gui.tool.defaulttool; 022 import com.gmail.kwok.devin.gui.tool.tool; 023 import com.gmail.kwok.devin.gui.tool.drag.dragtool; 024 import com.gmail.kwok.devin.gui.tool.edit.edittool; /** 027 * A tool bar which allows various actions to be performed. 028 * 029 Devin Kwok 030 * 031 */ 032 public class ActionToolBar extends JToolBar 033 { 034 /** 035 * 036 */ 037 private static final long serialversionuid = 1L; /** 040 * Constructs a new ActionToolBar. 041 * 042 panel universe panel which contains needed functions. 043 */ 044 public ActionToolBar( UniversePanel panel ) 045 { 046 super( "Universe Tools", SwingConstants.HORIZONTAL ); 047 this.panel = panel; 048 this.currenttool = Tool.DRAG_TOOL; 049 this.setlayout( new FlowLayout() ); createsimulationbuttons(); 052 createtoolbuttons(); 053 createlabels(); 054 } /** 057 * Creates buttons for controlling the simulation. 058 */ 059 private void createsimulationbuttons() 060 { Devin Kwok: Dossier 2008 C: The Program: Page 42 of 185

44 061 step = createstepbutton(); 062 run = createrunbutton(); 063 this.add( step ); 064 this.add( run ); 065 this.addseparator(); 066 } /** 069 * Creates buttons for controlling the current mouse tool. 070 */ 071 private void createtoolbuttons() 072 { 073 drag = createtoolbutton( Tool.DRAG_TOOL, Resource.DRAG_ICON ); 074 edit = createtoolbutton( Tool.EDIT_TOOL, Resource.EDIT_ICON ); 075 this.add( drag ); 076 this.add( edit ); 077 this.addseparator(); ButtonGroup toolgroup = new ButtonGroup(); 080 toolgroup.add( drag ); 081 toolgroup.add( edit ); 082 } /** 085 * Creates labels giving information about the universe. 086 */ 087 private void createlabels() 088 { 089 // JPanel panel = new JPanel(); JPanel runningpanel = createinfopanel( RUNNING_PANEL ); 092 running = new JLabel(); JPanel generationpanel = createinfopanel( GENERATION_PANEL ); 095 generation = new JLabel(); JPanel speedpanel = createinfopanel( SPEED_PANEL ); 098 speedtype = new JLabel(); 099 speedvalue = new JLabel(); JPanel zoompanel = createinfopanel( ZOOM_PANEL ); 102 zoom = new JLabel(); this.add( runningpanel ); 105 runningpanel.add( running ); 106 this.addseparator(); this.add( generationpanel ); 109 generationpanel.add( generation ); 110 this.addseparator(); this.add( speedpanel ); 113 speedpanel.add( speedtype ); 114 speedpanel.add( speedvalue ); 115 this.addseparator(); this.add( zoompanel ); 118 zoompanel.add( zoom ); 119 // return panel; 120 } /** 123 * Creates an information panel with the given name. Devin Kwok: Dossier 2008 C: The Program: Page 43 of 185

45 124 * 125 name name of panel. 126 panel. 127 */ 128 private JPanel createinfopanel( String name ) 129 { 130 JPanel panel = new JPanel(); 131 panel.setlayout( new BoxLayout( panel, BoxLayout.PAGE_AXIS ) ); 132 panel.setborder( new EtchedBorder() ); 133 panel.add( new JLabel( name ) ); 134 return panel; 135 } /** 138 * Creates a tool button with the name and icon location. 139 * 140 toolname name of tool. 141 iconlocation location of icon. 142 toggle button. 143 */ 144 private JToggleButton createtoolbutton( String toolname, 145 String iconlocation ) 146 { 147 final JToggleButton button = new JToggleButton(); 148 setbuttonicon( button, toolname, iconlocation ); class ButtonListener implements ActionListener 151 { 153 public void actionperformed( ActionEvent e ) 154 { 155 currenttool = button.getname(); 156 panel.settool( gettool( currenttool ) ); 157 } 158 } 159 button.addactionlistener( new ButtonListener() ); return button; 162 } /** 165 * Creates a button for stepping the simulation. 166 * 167 button. 168 */ 169 private JButton createstepbutton() 170 { 171 final JButton button = new JButton(); 172 setbuttonicon( button, GenerationTimer.STEP, Resource.STEP_ICON ); class StepButtonListener implements ActionListener 175 { 177 public void actionperformed( ActionEvent e ) 178 { 179 panel.gettimer().nextgeneration(); 180 } 181 } 182 button.addactionlistener( new StepButtonListener() ); return button; 185 } 186 Devin Kwok: Dossier 2008 C: The Program: Page 44 of 185

46 187 /** 188 * Creates a button for running the simulation. 189 * 190 button. 191 */ 192 private JButton createrunbutton() 193 { 194 final JButton button = new JButton(); 195 setbuttonicon( button, GenerationTimer.RUN, Resource.RUN_ICON ); class RunButtonListener implements ActionListener 198 { 200 public void actionperformed( ActionEvent e ) 201 { 202 boolean isrunning = panel.gettimer().isrunning(); 203 if( isrunning ) 204 panel.gettimer().stopsimulation(); 205 else 206 panel.gettimer().runsimulation(); updatetoolbar(!isrunning ); 209 } 210 } 211 button.addactionlistener( new RunButtonListener() ); return button; 214 } /** 217 * Sets the tool bar to be enabled. 218 */ 219 public void setenabled( boolean enabled ) 220 { 221 super.setenabled( enabled ); 222 for( Component c : this.getcomponents() ) 223 { 224 c. setenabled( enabled ); 225 if( enabled && c.getname()!= null 226 && c.getname().equals( currenttool ) ) 227 ( (JToggleButton) c ).setselected( true ); 228 } 229 if( enabled ) 230 { 231 panel.settool( gettool( currenttool ) ); 232 updatetoolbar( false ); 233 } 234 } /** 237 * Updates the information contained within the tool bar. 238 * 239 isrunning whether simulation is running or not. 240 */ 241 public void updatetoolbar( boolean isrunning ) 242 { 243 if( isrunning ) 244 { 245 step.setenabled( false ); 246 run.seticon( null ); 247 run.settext( null ); 248 setbuttonicon( run, GenerationTimer.STOP, Resource.STOP_ICON ); 249 running.settext( "Running..." ); Devin Kwok: Dossier 2008 C: The Program: Page 45 of 185

47 250 } 251 else 252 { 253 step.setenabled( true ); 254 run.seticon( null ); 255 run.settext( null ); 256 setbuttonicon( run, GenerationTimer.RUN, Resource.RUN_ICON ); 257 running.settext( "Stopped" ); 258 } GenerationTimer timer = panel.gettimer(); generation.settext( "" + timer.getgenerationcount() ); if( timer.getdelay() > 0 ) 265 { 266 speedtype.settext( "Delay (ms): " ); 267 speedvalue.settext( "" + timer.getdelay() ); 268 } 269 else 270 { 271 speedtype.settext( "Skipped generations: " ); 272 speedvalue.settext( "" + timer.getupdateskip() ); 273 } zoom.settext( panel.getuniversecomponent().getcellsize() * "%" ); 276 } /** 279 * Sets the icon of a button tot he given icon. 280 * 281 button button to set. 282 buttonname name of button. 283 iconlocation location of button icon. 284 */ 285 private void setbuttonicon( AbstractButton button, String buttonname, 286 String iconlocation ) 287 { 288 button.setname( buttonname ); 289 button.settooltiptext( buttonname ); ImageIcon icon = new ImageIcon( iconlocation, buttonname ); 292 if( icon.geticonwidth() == -1 ) 293 button.settext( buttonname ); 294 else 295 button.seticon( icon ); 296 } /** 299 * Returns the tool with the given tool name. 300 * 301 toolname name of tool. 302 tool. 303 */ 304 public Tool gettool( String toolname ) 305 { 306 if( toolname.equals( Tool.DRAG_TOOL ) ) 307 return new DragTool( panel ); 308 if( toolname.equals( Tool.EDIT_TOOL ) ) 309 return new EditTool( panel ); 310 return new DefaultTool(); 311 } 312 Devin Kwok: Dossier 2008 C: The Program: Page 46 of 185

48 313 /** 314 * Reference to the universe panel for various functions. 315 */ 316 private UniversePanel panel; /** 319 * Stepping simulation button. 320 */ 321 private JButton step; /** 324 * Running simulation button. 325 */ 326 private JButton run; /** 329 * Drag tool button. 330 */ 331 private JToggleButton drag; /** 334 * Edit tool button. 335 */ 336 private JToggleButton edit; /** 339 * Label showing whether simulation is running. 340 */ 341 private JLabel running; /** 344 * Label showing current generation count. 345 */ 346 private JLabel generation; /** 349 * Label showing the type of speed the simulation is running at. 350 */ 351 private JLabel speedtype; /** 354 * Label showing the speed either in milisecond delay or skipped 355 * generations. 356 */ 357 private JLabel speedvalue; /** 360 * Label showing the current zoom. 361 */ 362 private JLabel zoom; /** 365 * Name of current tool. 366 */ 367 private String currenttool; /** 370 * Title of application state panel. 371 */ 372 private static final String RUNNING_PANEL = "Application State: "; /** 375 * Title of generation panel. Devin Kwok: Dossier 2008 C: The Program: Page 47 of 185

49 376 */ 377 private static final String GENERATION_PANEL = "Generation Count: "; /** 380 * Title of simulation speed panel. 381 */ 382 private static final String SPEED_PANEL = "Simulation Speed: "; /** 385 * Title of current zoom panel. 386 */ 387 private static final String ZOOM_PANEL = "Current Zoom: "; 388 } Devin Kwok: Dossier 2008 C: The Program: Page 48 of 185

50 C.I.vi: Package: com.gmai.kwok.devin.gui.component Abstract Class: UniverseComponent 001 package com.gmail.kwok.devin.gui.component; import javax.swing.jcomponent; 004 import javax.swing.scrollable; import com.gmail.kwok.devin.gui.graphics.stategraphic; 007 import com.gmail.kwok.devin.universe.change.change; 008 import com.gmail.kwok.devin.universe.change.stackoverflowexception; 009 import com.gmail.kwok.devin.util.locationvector; /** 012 * Defines the graphical display of a universe. The universe component is 013 * responsible for the arranging and display of the cells in the universe. It 014 * must also handle mouse events that occur within it. UniverseComponent 015 * implements Scrollable so that it can be placed inside a scroll pane. 016 * 017 Devin Kwok 018 * 019 */ 020 public abstract class UniverseComponent extends JComponent implements 021 Scrollable 022 { 023 /** 024 * Constructs a new universe component. 025 * 026 states state graphic objects denoting how different states are 027 * displayed. 028 */ 029 public UniverseComponent( StateGraphic[] states ) 030 { 031 this.states = states; 032 } /** 035 * Clears every cell in the component. 036 */ 037 public abstract void clearall(); /** 040 * Returns the cell address at the specified coordinates. 041 * 042 x x coordinate in component. 043 y y coordinate in component. 044 cell address. 045 */ 046 public abstract int getcelladdress( int x, int y ); /** 049 * Adds a change to the component's universe. 050 * 051 change change to be added 052 StackOverflowException 053 */ 054 public abstract void addchange( Change change ) 055 throws StackOverflowException; /** Devin Kwok: Dossier 2008 C: The Program: Page 49 of 185

51 058 * Updates the changes of the universe to be displayed on the component. 059 */ 060 public abstract void updatechanges(); /** 063 * Causes the universe to generate the next generation. 064 * 065 StackOverflowException 066 */ 067 public abstract void nextgeneration() throws StackOverflowException; /** 070 * Returns the pixel size of cells. 071 * 072 integer size of cells. 073 */ 074 public abstract int getcellsize(); /** 077 * Sets the pixel size of cells. 078 * 079 cellsize integer size of cells. 080 */ 081 public abstract void setcellsize( int cellsize ); /** 084 * Returns the minimum pixel size of cells. 085 * 086 minimum integer size of cells. 087 */ 088 public abstract int getmincellsize(); /** 091 * Returns the maximum pixel size of cells. 092 * 093 maximum integer size of cells. 094 */ 095 public abstract int getmaxcellsize(); /** 098 * Returns the state graphic objects in this component. 099 * 100 array of state graphic objects 101 */ 102 public StateGraphic[] getstategraphics() 103 { 104 return states; 105 } /** 108 * Returns the location vector containing properties of the underlying 109 * universe such as width and height. Used for file writing. 110 * 111 location vector containing properties. 112 */ 113 public abstract LocationVector getuniverseproperties(); /** 116 * State graphic objects of component. 117 */ 118 protected StateGraphic[] states; } Devin Kwok: Dossier 2008 C: The Program: Page 50 of 185

52 Class: Universe2DComponent 001 package com.gmail.kwok.devin.gui.component; import java.awt.basicstroke; 004 import java.awt.color; 005 import java.awt.dimension; 006 import java.awt.graphics; 007 import java.awt.graphics2d; 008 import java.awt.rectangle; 009 import java.awt.geom.line2d; import javax.swing.swingconstants; import com.gmail.kwok.devin.gui.graphics.squarecellgraphic; 014 import com.gmail.kwok.devin.gui.graphics.stategraphic; 015 import com.gmail.kwok.devin.universe.universe2d; 016 import com.gmail.kwok.devin.universe.change.change; 017 import com.gmail.kwok.devin.universe.change.changestack; 018 import com.gmail.kwok.devin.universe.change.stackoverflowexception; 019 import com.gmail.kwok.devin.util.locationvector; /** 022 * A universe component for two dimensional universes, with square cells (class 023 * Universe2D). 024 * 025 Devin Kwok 026 * 027 */ 028 public class Universe2DComponent extends UniverseComponent 029 { /** 032 * 033 */ 034 private static final long serialversionuid = 1L; /** 037 * Constructs a new Universe2DComponent. 038 * 039 universe Universe2D universe to display 040 states state graphic objects denoting how state values are 041 * displayed. 042 cellsize pixel width of cells. 043 */ 044 public Universe2DComponent( Universe2D universe, StateGraphic[] states, 045 int cellsize ) 046 { 047 super( states ); 048 if( cellsize < 0 ) 049 throw new IllegalArgumentException( "Cell size less than 0" ); 050 this.cellsize = cellsize; this.universe = universe; 053 this.cells = new SquareCellGraphic[ universe.getrows() ][ universe 054.getColumns() ]; super.setsize( getpreferredsize() ); 057 super.setmaximumsize( getpreferredsize() ); 058 super.setminimumsize( getpreferredsize() ); 059 super.setautoscrolls( true ); 060 Devin Kwok: Dossier 2008 C: The Program: Page 51 of 185

53 061 clearall(); 062 } /** 065 * Clears every cell in the universe component. Updates their values to 066 * match that of the underlying universe. 067 */ 068 public void clearall() 069 { 070 for( int i = 0; i < universe.getrows(); i++ ) 071 { 072 for( int j = 0; j < universe.getcolumns(); j++ ) 073 { 074 cells[ i ][ j ] = new SquareCellGraphic( universe 075.getCell( new LocationVector( i, j ) ), super.states, 076 j * cellsize, i * cellsize, cellsize ); 077 cells[ i ][ j ].updatevalues(); 078 } 079 } 080 } /** 083 * Constructs a new universe component with the default cell size. 084 * 085 universe Universe2D universe to display 086 states state graphic objects denoting how state values are 087 * displayed. 088 */ 089 public Universe2DComponent( Universe2D universe, StateGraphic[] states ) 090 { 091 this( universe, states, DEFAULT_SIZE ); 092 } /** 095 * Paints the component. 096 */ 097 public void paintcomponent( Graphics g ) 098 { 099 Graphics2D g2 = (Graphics2D) g; 100 for( SquareCellGraphic[] a : cells ) 101 { 102 for( SquareCellGraphic cell : a ) 103 { 104 cell.drawwithoutborders( g2 ); 105 } 106 } 107 if( cellsize > NO_BORDER ) 108 { 109 g2.setcolor( Color.WHITE ); 110 g2.setstroke( new BasicStroke() ); 111 drawborders( g2 ); g2.setcolor( Color.BLACK ); 114 g2.setstroke( new BasicStroke( 1, BasicStroke.CAP_BUTT, 115 BasicStroke.JOIN_MITER, 1, new float[] { 1 }, 0 ) ); 116 drawborders( g2 ); 117 } 118 } /** 121 * Draws borders of cells. 122 * 123 g2 Graphics object. Devin Kwok: Dossier 2008 C: The Program: Page 52 of 185

54 124 */ 125 private void drawborders( Graphics2D g2 ) 126 { 127 int max = universe.getrows() * cellsize; 128 for( int i = 0; i <= universe.getrows(); i++ ) 129 { 130 Line2D.Double line = new Line2D.Double( 0, i * cellsize, max, i 131 * cellsize ); 132 g2.draw( line ); 133 } max = universe.getcolumns() * cellsize; 136 for( int i = 0; i <= universe.getcolumns(); i++ ) 137 { 138 Line2D.Double line = new Line2D.Double( i * cellsize, 0, i 139 * cellsize, max ); 140 g2.draw( line ); 141 } 142 } /** 145 * Returns the cell address at the specified coordinates. 146 */ 147 public int getcelladdress( int x, int y ) 148 { 149 int row = y / cellsize; 150 int col = x / cellsize; 151 return universe.getcelladdress( new LocationVector( row, col ) ); 152 } /** 155 * Updates the changes to the universe so that they are displayed. 156 */ 157 public void updatechanges() 158 { 159 ChangeStack stack = universe.getappliedchanges(); 160 while( stack.haschanges() ) 161 { 162 int address = stack.removechange().getcelladdress(); 163 cells[ universe.getrowaddress( address ) ][ universe 164.getColumnAddress( address ) ].updatevalues(); 165 } 166 } /** 169 * Returns a string representation of the underlying universe. 170 */ 171 public String tostring() 172 { 173 return universe.tostring(); 174 } /** 177 * Returns the preferred size of the component. 178 */ 179 public Dimension getpreferredsize() 180 { 181 Dimension dimension = new Dimension( 182 cellsize * universe.getcolumns(), cellsize 183 * universe.getrows() ); 184 return dimension; 185 } 186 Devin Kwok: Dossier 2008 C: The Program: Page 53 of 185

55 187 /** 188 * Returns the preferred size of a scrollable viewport over the component. 189 */ 191 public Dimension getpreferredscrollableviewportsize() 192 { 193 return getpreferredsize(); 194 } /** 197 * Returns the block increment at which the viewport scrolls. 198 */ 200 public int getscrollableblockincrement( Rectangle visiblerect, 201 int orientation, int direction ) 202 { 203 if( orientation == SwingConstants.HORIZONTAL ) 204 return visiblerect.width - cellsize * OVERLAP; 205 else 206 return visiblerect.height - cellsize * OVERLAP; 207 } /** 210 * Returns the unit increment at which the viewport scrolls. 211 */ 213 public int getscrollableunitincrement( Rectangle visiblerect, 214 int orientation, int direction ) 215 { 216 int currentposition; 217 if( orientation == SwingConstants.HORIZONTAL ) 218 currentposition = visiblerect.x; 219 else 220 currentposition = visiblerect.y; int nearesttick = currentposition / cellsize * cellsize; 223 int distance = nearesttick; if( direction < 0 ) 226 distance = currentposition - nearesttick; 227 else 228 distance = nearesttick + cellsize - currentposition; if( distance == 0 ) 231 return cellsize; 232 return distance; 233 } /** 236 * Returns false to show the viewport is scrollable vertically. 237 */ 239 public boolean getscrollabletracksviewportheight() 240 { 241 return false; 242 } /** 245 * Returns false to show the viewport is scrollable horizontally. 246 */ 248 public boolean getscrollabletracksviewportwidth() 249 { Devin Kwok: Dossier 2008 C: The Program: Page 54 of 185

56 250 return false; 251 } /** 254 * Returns the pixel width of cells. 255 */ 256 public int getcellsize() 257 { 258 return cellsize; 259 } /** 262 * Sets the pixel width of cells. 263 */ 264 public void setcellsize( int cellsize ) 265 { 266 if( cellsize < 1 ) 267 throw new IllegalArgumentException( "Cell size less than 1." ); 268 this.cellsize = cellsize; 269 clearall(); 270 } /** 273 * Causes the universe to generate the next generation. 274 */ 276 public void nextgeneration() throws StackOverflowException 277 { 278 universe.nextgeneration(); 279 } /** 282 * Returns the minimum cell pixel width. 283 */ 285 public int getmincellsize() 286 { 287 return MIN_CELL_SIZE; 288 } /** 291 * Returns the maximum cell pixel width. 292 */ 294 public int getmaxcellsize() 295 { 296 return MAX_CELL_SIZE; 297 } /** 300 * Adds a change to the universe and flushes the change. 301 */ 303 public void addchange( Change change ) throws StackOverflowException 304 { 305 universe.addchange( change ); 306 universe.flushchanges(); 307 } /** 310 * Returns the universe properties of a Universe2D object in the form 311 * LocationVector(rows, columns). 312 */ Devin Kwok: Dossier 2008 C: The Program: Page 55 of 185

57 314 public LocationVector getuniverseproperties() 315 { 316 return new LocationVector( universe.getrows(), universe.getcolumns() ); 317 } /** 320 * Default pixel size of cells. 321 */ 322 private static final int DEFAULT_SIZE = 20; /** 325 * Overlap of cells when finding the scrollable block increment. 326 */ 327 private static final int OVERLAP = 2; /** 330 * Maximum pixel size of cells where no border is drawn. 331 */ 332 private static final int NO_BORDER = 2; /** 335 * Minimum pixel cell width. 336 */ 337 private static final int MIN_CELL_SIZE = 1; /** 340 * Maximum pixel cell width. 341 */ 342 private static final int MAX_CELL_SIZE = 50; /** 345 * Current pixel cell width. 346 */ 347 private int cellsize; /** 350 * The underlying Universe2D object. 351 */ 352 private Universe2D universe; /** 355 * Cell graphic objects which store the drawing conditions of each cell. 356 */ 357 private SquareCellGraphic[][] cells; 358 } Devin Kwok: Dossier 2008 C: The Program: Page 56 of 185

58 Class: EmptyComponent 01 package com.gmail.kwok.devin.gui.component; import java.awt.graphics; 04 import java.awt.graphics2d; import javax.swing.jcomponent; /** 09 * An empty component displayed when no universe is loaded. 10 * 11 Devin Kwok 12 * 13 */ 14 public class EmptyComponent extends JComponent 15 { 16 /** 17 * 18 */ 19 private static final long serialversionuid = 1L; /** 22 * Paints the empty component with a message in the center. 23 */ 24 public void paintcomponent( Graphics g ) 25 { 26 Graphics2D g2 = (Graphics2D) g; 27 g2.drawstring( DEFAULT_MESSAGE, this.getwidth() / 2, 28 this.getheight() / 2 ); 29 } /** 32 * Message to display in component. 33 */ 34 private static final String DEFAULT_MESSAGE = "No universe open."; 35 } Devin Kwok: Dossier 2008 C: The Program: Page 57 of 185

59 C.I.vii: Package: com.gmai.kwok.devin.gui.graphics Abstract Class: CellGraphic 001 package com.gmail.kwok.devin.gui.graphics; import java.awt.color; 004 import java.awt.graphics2d; import javax.swing.icon; import com.gmail.kwok.devin.universe.cell.cell; 009 import com.gmail.kwok.devin.util.linkedlist; /** 012 * Defines the graphical aspect of a cell. 013 * 014 Devin Kwok 015 * 016 */ 017 public abstract class CellGraphic 018 { 019 /** 020 * Constructs a new cell graphic object. 021 * 022 cell cell to display. 023 components state graphic components dictating how state values are 024 * displayed. 025 */ 026 public CellGraphic( Cell cell, StateGraphic[] components ) 027 { 028 this.cell = cell; 029 this.states = components; 030 this.iconlist = new LinkedList(); 031 } /** 034 * Draws the cell. 035 * 036 g2 037 */ 038 public abstract void draw( Graphics2D g2 ); /** 041 * Draws the cell without borders. Improves performance. 042 * 043 g2 044 */ 045 public abstract void drawwithoutborders( Graphics2D g2 ); /** 048 * Returns the pixel size of the cell. 049 * 050 pixel size of cell 051 */ 052 public abstract int getcellsize(); /** 055 * Sets the pixel size of the cell. 056 * 057 cellsize pixel size of cell Devin Kwok: Dossier 2008 C: The Program: Page 58 of 185

60 058 */ 059 public abstract void setcellsize( int cellsize ); /** 062 * Updates the cell's coloring to reflect the underlying cell's values. 063 */ 064 public void updatevalues() 065 { 066 double r = 0, g = 0, b = 0; 067 int rcount = 0, gcount = 0, bcount = 0; 068 this.iconlist = new LinkedList(); for( StateGraphic c : states ) 071 { 072 Icon icon = c.geticon(); 073 if( icon!= null ) 074 iconlist.addlast( icon ); Color color = c.getcolor( this.cell.getcelladdress() ); 077 r = r + color.getred(); 078 g = g + color.getgreen(); 079 b = b + color.getblue(); if( color.getred() > 0 ) 082 rcount++; 083 if( color.getgreen() > 0 ) 084 gcount++; 085 if( color.getblue() > 0 ) 086 bcount++; 087 } 088 r = Math.min( Math.max( r / rcount, 0 ), 255 ); 089 g = Math.min( Math.max( g / gcount, 0 ), 255 ); 090 b = Math.min( Math.max( b / bcount, 0 ), 255 ); color = new Color( (int) r, (int) g, (int) b ); 093 } /** 096 * Returns a string representation of the underlying cell. 097 */ 098 public String tostring() 099 { 100 return cell.tostring(); 101 } /** 104 * Underlying cell object. 105 */ 106 private Cell cell; /** 109 * State graphic objects defining how values are displayed. 110 */ 111 protected StateGraphic[] states; /** 114 * Current color of cell. 115 */ 116 protected Color color; /** 119 * List of icons to be drawn on cell. Icons are not currently implemented. 120 */ Devin Kwok: Dossier 2008 C: The Program: Page 59 of 185

61 121 protected LinkedList iconlist; 122 } Devin Kwok: Dossier 2008 C: The Program: Page 60 of 185

62 Class: SquareCellGraphic 001 package com.gmail.kwok.devin.gui.graphics; import java.awt.basicstroke; 004 import java.awt.color; 005 import java.awt.graphics2d; 006 import java.awt.rectangle; import javax.swing.icon; import com.gmail.kwok.devin.universe.cell.cell; 011 import com.gmail.kwok.devin.util.listiterator; /** 014 * Defines the graphical display of a square cell. 015 * 016 Devin Kwok 017 * 018 */ 019 public class SquareCellGraphic extends CellGraphic 020 { /** 023 * Creates a new cell. 024 * 025 cell cell to display. 026 states state graphic components dictating how state values are 027 * displayed. 028 x x coordinate of cell. 029 y y coordinate of cell. 030 size pixel width of cell. 031 */ 032 public SquareCellGraphic( Cell cell, StateGraphic[] states, int x, int y, 033 int size ) 034 { 035 super( cell, states ); 036 this.square = new Rectangle( x, y, size, size ); 037 } /** 040 * Draws the square cell with a dashed black and white border. 041 */ 042 public void draw( Graphics2D g2 ) 043 { 044 g2.setcolor( super.color ); 045 g2.setstroke( new BasicStroke() ); 046 g2.fill( square ); ListIterator iterator = super.iconlist.listiterator(); 049 while( iterator.hasnext() ) 050 { 051 Icon icon = (Icon) iterator.next(); icon.painticon( null, g2, (int) square.getx(), (int) square 054.getY() ); 055 } g2.setcolor( Color.WHITE ); 058 g2.draw( square ); g2.setcolor( Color.BLACK ); Devin Kwok: Dossier 2008 C: The Program: Page 61 of 185

63 061 g2.setstroke( new BasicStroke( 1, BasicStroke.CAP_BUTT, 062 BasicStroke.JOIN_MITER, 1, new float[] { 1 }, 0 ) ); 063 g2.draw( square ); 064 } /** 067 * Draws the square cell without borders. 068 */ 069 public void drawwithoutborders( Graphics2D g2 ) 070 { 071 g2.setcolor( super.color ); 072 g2.fill( square ); ListIterator iterator = super.iconlist.listiterator(); 075 while( iterator.hasnext() ) 076 { 077 Icon icon = (Icon) iterator.next(); icon.painticon( null, g2, (int) square.getx(), (int) square 080.getY() ); 081 } 082 } /** 085 * Returns the size of the cell. 086 */ 088 public int getcellsize() 089 { 090 return square.height; 091 } /** 094 * Sets the size of the cell. 095 */ 097 public void setcellsize( int cellsize ) 098 { 099 square.height = cellsize; 100 square.width = cellsize; 101 } /** 104 * Rectangle defining the location and size of the cell. 105 */ 106 private Rectangle square; 107 } Devin Kwok: Dossier 2008 C: The Program: Page 62 of 185

64 Class: StateGraphic 001 package com.gmail.kwok.devin.gui.graphics; import java.awt.color; import javax.swing.icon; import com.gmail.kwok.devin.universe.universe; 008 import com.gmail.kwok.devin.universe.state.state; 009 import com.gmail.kwok.devin.universe.state.statedefinition; /** 012 * Defines the graphical display of a given state. 013 * 014 Devin Kwok 015 * 016 */ 017 public class StateGraphic 018 { 019 public StateGraphic( StateDefinition definition, Universe universe, 020 boolean isred, boolean isgreen, boolean isblue ) 021 { 022 this.definition = definition; 023 this.state = universe.getstate( definition.getstatekey() ); 024 this.isred = isred; 025 this.isgreen = isgreen; 026 this.isblue = isblue; 027 this.icon = null; 028 setdefaults(); 029 } public StateGraphic( StateDefinition definition, Universe universe, 032 Icon icon ) 033 { 034 this.definition = definition; 035 this.state = universe.getstate( definition.getstatekey() ); 036 this.isred = false; 037 this.isgreen = false; 038 this.isblue = false; 039 this.icon = icon; 040 setdefaults(); 041 } public StateGraphic( StateDefinition definition, Universe universe, 044 boolean isred, boolean isgreen, boolean isblue, double min, 045 double max, double threshold, boolean iscontinuous ) 046 { 047 this( definition, universe, isred, isgreen, isblue ); this.min = min; 050 this.setmax( max ); 051 this.setthreshold( threshold ); 052 this.setcontinuous( iscontinuous ); 053 } public StateGraphic( StateDefinition definition, Universe universe, 056 Icon icon, double min, double max, double threshold, 057 boolean iscontinuous ) 058 { 059 this( definition, universe, icon ); 060 Devin Kwok: Dossier 2008 C: The Program: Page 63 of 185

65 061 this.min = min; 062 this.setmax( max ); 063 this.setthreshold( threshold ); 064 this.setcontinuous( iscontinuous ); 065 } private void setdefaults() 068 { 069 this.iscontinuous = true; 070 this.min = this.definition.getmin(); 071 if( min == Double.MIN_VALUE ) 072 min = DEFAULT_MIN; 073 this.max = this.definition.getmax(); 074 if( max == Double.MAX_VALUE ) 075 max = DEFAULT_MAX; 076 this.threshold = DEFAULT_THRESHOLD; 077 } public Color getcolor( int celladdress ) 080 { 081 int rgbvalue = getshade( state.getvalue( celladdress ) ); 082 int r = 0, g = 0, b = 0; 083 if( isred ) 084 r = rgbvalue; 085 if( isblue ) 086 b = rgbvalue; 087 if( isgreen ) 088 g = rgbvalue; return new Color( r, g, b ); 091 } private int getshade( double value ) 094 { 095 if( iscontinuous ) 096 { 097 if( min >= max ) 098 throw new IllegalArgumentException( 099 "Min equals or exceeds max." ); 100 double range = max - min; 101 double amount = Math.min( Math.max( value - min, min ), range ); 102 return (int) ( amount / range * 254 ) + 1; 103 } if( value >= threshold ) 106 return 255; 107 return 1; 108 } public Icon geticon( int celladdress ) 111 { 112 if( state.getvalue( celladdress ) >= threshold ) 113 return icon; 114 return null; 115 } public String addresstostring( int celladdress ) 118 { 119 return "" + state.tostring( celladdress ); 120 } public boolean isred() 123 { Devin Kwok: Dossier 2008 C: The Program: Page 64 of 185

66 124 return isred; 125 } public void setred( boolean isred ) 128 { 129 this.isred = isred; 130 if( isred ) 131 icon = null; 132 } public boolean isgreen() 135 { 136 return isgreen; 137 } public void setgreen( boolean isgreen ) 140 { 141 this.isgreen = isgreen; 142 if( isgreen ) 143 icon = null; 144 } public boolean isblue() 147 { 148 return isblue; 149 } public void setblue( boolean isblue ) 152 { 153 this.isblue = isblue; 154 if( isblue ) 155 icon = null; 156 } public boolean iscontinuous() 159 { 160 return iscontinuous; 161 } public void setcontinuous( boolean iscontinuous ) 164 { 165 this.iscontinuous = iscontinuous; 166 } public double getthreshold() 169 { 170 return threshold; 171 } public void setthreshold( double threshold ) 174 { 175 this.threshold = threshold; 176 } public double getmin() 179 { 180 return min; 181 } public void setmin( double min ) 184 { 185 if( min > this.max ) 186 throw new IllegalArgumentException( "Minimum exceeds maximum." ); Devin Kwok: Dossier 2008 C: The Program: Page 65 of 185

67 187 if( min < this.definition.getmin() ) 188 throw new IllegalArgumentException( 189 "Minimum less than defined minimum." ); 190 this.min = min; 191 } public double getmax() 194 { 195 return max; 196 } public void setmax( double max ) 199 { 200 if( max > this.min ) 201 throw new IllegalArgumentException( "Minimum exceeds maximum." ); 202 if( max > this.definition.getmax() ) 203 throw new IllegalArgumentException( 204 "Maximum greater than defined maximum." ); 205 this.max = max; 206 } public Icon geticon() 209 { 210 return icon; 211 } public void seticon( Icon icon ) 214 { 215 this.icon = icon; 216 this.isblue = false; 217 this.isgreen = false; 218 this.isred = false; 219 } public State getstate() 222 { 223 return state; 224 } private static final double DEFAULT_MIN = 0; 227 private static final double DEFAULT_MAX = 100; 228 private static final double DEFAULT_THRESHOLD = 10; private State state; 231 private StateDefinition definition; private boolean isred; 234 private boolean isgreen; 235 private boolean isblue; 236 private boolean iscontinuous; 237 private double threshold; 238 private double min; 239 private double max; 240 private Icon icon; 241 } Devin Kwok: Dossier 2008 C: The Program: Page 66 of 185

68 C.I.viii: Package: com.gmai.kwok.devin.gui.tool Interface: Tool 01 package com.gmail.kwok.devin.gui.tool; import java.awt.cursor; 04 import java.awt.event.mouselistener; 05 import java.awt.event.mousemotionlistener; import javax.swing.jpanel; /** 10 * An interface defining a mouse tool which can be used to manipulate the 11 * simulation. 12 * 13 Devin Kwok 14 * 15 */ 16 public interface Tool extends MouseListener, MouseMotionListener 17 { 18 /** 19 * Returns the mouse cursor of the tool. 20 * 21 cursor. 22 */ 23 Cursor getassociatedcursor(); /** 26 * Returns the panel which contains components specific to the tool. 27 * 28 panel. 29 */ 30 JPanel getassociatedpanel(); /** 33 * Default cursor width. 34 */ 35 public static final int CURSOR_WIDTH = 32; /** 38 * Default cursor height. 39 */ 40 public static final int CURSOR_HEIGHT = 32; /** 43 * Default tool name. 44 */ 45 public static final String DEFAULT_TOOL = "No tool"; /** 48 * Drag tool name. 49 */ 50 public static final String DRAG_TOOL = "Drag tool"; /** 53 * Edit tool name. 54 */ 55 public static final String EDIT_TOOL = "Edit tool"; 56 } Devin Kwok: Dossier 2008 C: The Program: Page 67 of 185

69 Class: DefaultTool 01 package com.gmail.kwok.devin.gui.tool; import java.awt.cursor; 04 import java.awt.event.mouseevent; import javax.swing.jpanel; /** 09 * A default tool which does nothing. 10 * 11 Devin Kwok 12 * 13 */ 14 public class DefaultTool implements Tool 15 { 16 /** 17 * Constructs a new default tool. 18 */ 19 public DefaultTool() 20 { 21 } /** 24 * Returns the default cursor. 25 */ 27 public Cursor getassociatedcursor() 28 { 29 return Cursor.getDefaultCursor(); 30 } /** 33 * Returns the default tool panel. 34 */ 36 public JPanel getassociatedpanel() 37 { 38 return new DefaultToolPanel(); 39 } /** 42 * Do nothing methods. 43 */ 44 public void mouseclicked( MouseEvent e ) 45 { 46 } public void mouseentered( MouseEvent e ) 49 { 50 } public void mouseexited( MouseEvent e ) 53 { 54 } public void mousepressed( MouseEvent e ) 57 { 58 } public void mousereleased( MouseEvent e ) Devin Kwok: Dossier 2008 C: The Program: Page 68 of 185

70 61 { 62 } public void mousedragged( MouseEvent e ) 65 { 66 } public void mousemoved( MouseEvent e ) 69 { 70 } 71 } Devin Kwok: Dossier 2008 C: The Program: Page 69 of 185

71 Class: DefaultToolPanel 01 package com.gmail.kwok.devin.gui.tool; import javax.swing.jlabel; 04 import javax.swing.jpanel; /** 07 * A default tool panel displaying "Load a universe to begin...". 08 * 09 Devin Kwok 10 * 11 */ 12 public class DefaultToolPanel extends JPanel 13 { 14 /** 15 * 16 */ 17 private static final long serialversionuid = 1L; /** 20 * Creats the default panel with a label. 21 */ 22 public DefaultToolPanel() 23 { 24 add( label ); 25 } /** 28 * Label to be displayed in the panel. 29 */ 30 private static final JLabel label = new JLabel( 31 "Load a universe to begin..." ); 32 } Devin Kwok: Dossier 2008 C: The Program: Page 70 of 185

72 C.I.ix: Package: com.gmai.kwok.devin.gui.tool.drag Class: DragTool 001 package com.gmail.kwok.devin.gui.tool.drag; import java.awt.cursor; 004 import java.awt.dimension; 005 import java.awt.image; 006 import java.awt.point; 007 import java.awt.toolkit; 008 import java.awt.event.mouseevent; import javax.swing.jpanel; 011 import javax.swing.jviewport; import com.gmail.kwok.devin.gui.resource; 014 import com.gmail.kwok.devin.gui.panel.universepanel; 015 import com.gmail.kwok.devin.gui.tool.tool; /** 018 * A tool which allows the user to change the viewing of the universe component 019 * by clicking and dragging. 020 * 021 Devin Kwok 022 * 023 */ 024 public class DragTool implements Tool 025 { /** 028 * Constructs a new drag tool. 029 * 030 panel universe panel which contains needed functions. 031 */ 032 public DragTool( UniversePanel panel ) 033 { 034 this.panel = panel; 035 createcursor(); 036 } /** 039 * Creates the mouse cursor for this tool. 040 */ 041 private void createcursor() 042 { 043 Toolkit toolkit = Toolkit.getDefaultToolkit(); 044 Image image = toolkit.getimage( Resource.DRAG_ICON ); Dimension bestsize = toolkit.getbestcursorsize( Tool.CURSOR_WIDTH, 047 Tool.CURSOR_HEIGHT ); if( bestsize.getwidth() == 0 ) 050 cursor = Cursor.getDefaultCursor(); 051 else 052 cursor = toolkit.createcustomcursor( image, new Point( 053 HOT_SPOT_X, HOT_SPOT_Y ), "Drag" ); 054 } /** 057 * Records where the mouse is pressed. Devin Kwok: Dossier 2008 C: The Program: Page 71 of 185

73 058 */ 059 public void mousepressed( MouseEvent event ) 060 { 061 xcorner = panel.getscrollpane().getviewport().getviewposition().x; 062 ycorner = panel.getscrollpane().getviewport().getviewposition().y; 063 xonpress = event.getx(); 064 yonpress = event.gety(); 065 } /** 068 * Moves the component in the opposite direction and the same distance as 069 * the mouse moved since it was pressed. This gives the illusion of dragging 070 * the component. 071 */ 072 public void mousereleased( MouseEvent event ) 073 { 074 JViewport viewport = panel.getscrollpane().getviewport(); 075 Point point = new Point( 0, 0 ); if( viewport.getwidth() < viewport.getview().getwidth() ) 078 { 079 int x = event.getx(); 080 point.x = xcorner + xonpress - x; 081 if( point.x < 0 ) 082 point.x = 0; 083 int maxx = viewport.getview().getwidth() - viewport.getwidth(); 084 if( point.x > maxx ) 085 point.x = maxx; 086 } if( viewport.getheight() < viewport.getview().getheight() ) 089 { 090 int y = event.gety(); 091 point.y = ycorner + yonpress - y; 092 if( point.y < 0 ) 093 point.y = 0; 094 int maxy = viewport.getview().getheight() - viewport.getheight(); 095 if( point.y > maxy ) 096 point.y = maxy; 097 } 098 panel.getscrollpane().getviewport().setviewposition( point ); 099 } /** 102 * Returns a new drag tool panel. 103 */ 105 public JPanel getassociatedpanel() 106 { 107 return new DragToolPanel( panel ); 108 } /** 111 * Returns the drag cursor. 112 */ 114 public Cursor getassociatedcursor() 115 { 116 return cursor; 117 } /** 120 * Do nothing methods. Devin Kwok: Dossier 2008 C: The Program: Page 72 of 185

74 121 */ 122 public void mouseclicked( MouseEvent event ) 123 { 124 } public void mousedragged( MouseEvent event ) 127 { 128 } public void mouseentered( MouseEvent event ) 131 { 132 } public void mouseexited( MouseEvent event ) 135 { 136 } public void mousemoved( MouseEvent event ) 139 { 140 } /** 143 * Drag cursor. 144 */ 145 private Cursor cursor; /** 148 * Reference to the universe panel for various functions. 149 */ 150 private UniversePanel panel; /** 153 * X coordinate of mouse when pressed. 154 */ 155 private int xonpress; /** 158 * Y coordinate of mouse when pressed. 159 */ 160 private int yonpress; /** 163 * X coordinate of viewport corner when mouse is pressed. 164 */ 165 private int xcorner; /** 168 * Y coordinate of viewport corner when mouse is pressed. 169 */ 170 private int ycorner; /** 173 * X coordinate of cursor's hot spot, or clicking point. 174 */ 175 private static final int HOT_SPOT_X = CURSOR_WIDTH / 2; /** 178 * Y coordinate of cursor's hot spot, or clicking point. 179 */ 180 private static final int HOT_SPOT_Y = CURSOR_HEIGHT / 2; 181 } Devin Kwok: Dossier 2008 C: The Program: Page 73 of 185

75 Class: DragToolPanel 01 package com.gmail.kwok.devin.gui.tool.drag; import java.awt.event.actionevent; 04 import java.awt.event.actionlistener; import javax.swing.boxlayout; 07 import javax.swing.jcheckbox; 08 import javax.swing.jpanel; 09 import javax.swing.jscrollpane; 10 import javax.swing.border.etchedborder; 11 import javax.swing.border.titledborder; 12 import javax.swing.event.listselectionevent; 13 import javax.swing.event.listselectionlistener; import com.gmail.kwok.devin.gui.statetable; 16 import com.gmail.kwok.devin.gui.graphics.stategraphic; 17 import com.gmail.kwok.devin.gui.panel.universepanel; /** 20 * A panel containing buttons for manipulating the display of the various 21 * states. Currently does nothing (not implemented). 22 * 23 Devin Kwok 24 * 25 */ 26 public class DragToolPanel extends JPanel 27 { 28 /** 29 * 30 */ 31 private static final long serialversionuid = 1L; /** 34 * Constructs a new drag tool panel. 35 * 36 universepanel universe panel which contains needed functions. 37 */ 38 public DragToolPanel( UniversePanel universepanel ) 39 { 40 this.universepanel = universepanel; 41 add( createtable() ); 42 } /** 45 * Creates a state table. 46 * 47 table. 48 */ 49 private JScrollPane createtable() 50 { 51 class StateSelectionListener implements ListSelectionListener 52 { 54 public void valuechanged( ListSelectionEvent e ) 55 { 56 int index = e.getfirstindex(); 57 currentstate = universepanel.getuniversecomponent() 58.getStateGraphics()[ index ]; 59 } 60 } Devin Kwok: Dossier 2008 C: The Program: Page 74 of 185

76 61 62 ListSelectionListener listener = new StateSelectionListener(); 63 StateTable table = new StateTable( universepanel 64.getUniverseComponent().getStateGraphics(), universepanel, 65 listener ); 66 JScrollPane scrollpane = new JScrollPane( table ); 67 scrollpane.setborder( new TitledBorder( new EtchedBorder(), 68 "States in Universe" ) ); 69 return scrollpane; 70 } /** 73 * Universe panel reference for various functions. 74 */ 75 private UniversePanel universepanel; /** 78 * Currently selected state for modification. 79 */ 80 private StateGraphic currentstate; 81 } Devin Kwok: Dossier 2008 C: The Program: Page 75 of 185

77 C.I.x: Package: com.gmai.kwok.devin.gui.frame Class: EditTool 001 package com.gmail.kwok.devin.gui.tool.edit; import java.awt.cursor; 004 import java.awt.dimension; 005 import java.awt.image; 006 import java.awt.point; 007 import java.awt.toolkit; 008 import java.awt.event.mouseevent; import javax.swing.jpanel; import com.gmail.kwok.devin.gui.resource; 013 import com.gmail.kwok.devin.gui.panel.universepanel; 014 import com.gmail.kwok.devin.gui.tool.tool; /** 017 * A tool which allows the user to select a cell and view or modify its values. 018 * 019 Devin Kwok 020 * 021 */ 022 public class EditTool implements Tool 023 { /** 026 * Constructs a new edit tool. 027 * 028 panel universe panel which contains needed functions. 029 */ 030 public EditTool( UniversePanel panel ) 031 { 032 this.panel = panel; 033 this.toolpanel = new EditToolPanel( panel ); 034 createcursor(); 035 } /** 038 * Creates the mouse cursor for this tool. 039 */ 040 private void createcursor() 041 { 042 Toolkit toolkit = Toolkit.getDefaultToolkit(); 043 Image image = toolkit.getimage( Resource.EDIT_ICON ); Dimension bestsize = toolkit.getbestcursorsize( Tool.CURSOR_WIDTH, 046 Tool.CURSOR_HEIGHT ); if( bestsize.getwidth() == 0 ) 049 cursor = Cursor.getDefaultCursor(); 050 else 051 cursor = toolkit.createcustomcursor( image, new Point( 052 HOT_SPOT_X, HOT_SPOT_Y ), "Edit" ); 053 } /** 056 * Returns the edit cursor. 057 */ Devin Kwok: Dossier 2008 C: The Program: Page 76 of 185

78 059 public Cursor getassociatedcursor() 060 { 061 return cursor; 062 } /** 065 * Returns the edit tool panel. 066 */ 068 public JPanel getassociatedpanel() 069 { 070 return toolpanel; 071 } /** 074 * Sets the associated panel to the cell address of the cell that is 075 * clicked. 076 */ 078 public void mouseclicked( MouseEvent e ) 079 { 080 int celladdress = panel.getuniversecomponent().getcelladdress( 081 e.getx(), e.gety() ); 082 toolpanel.setcelladdress( celladdress ); 083 } /** 086 * Do nothing methods. 087 */ 088 public void mouseentered( MouseEvent e ) 089 { 090 } public void mouseexited( MouseEvent e ) 093 { 094 } public void mousepressed( MouseEvent e ) 097 { 098 } public void mousereleased( MouseEvent e ) 101 { 102 } public void mousedragged( MouseEvent e ) 105 { 106 } public void mousemoved( MouseEvent e ) 109 { 110 } /** 113 * Edit cursor. 114 */ 115 private Cursor cursor; /** 118 * Universe panel reference for various functions. 119 */ 120 private UniversePanel panel; Devin Kwok: Dossier 2008 C: The Program: Page 77 of 185

79 /** 123 * Edit tool panel. 124 */ 125 private EditToolPanel toolpanel; /** 128 * X coordinate of cursor's hot spot, or clicking point. 129 */ 130 private static final int HOT_SPOT_X = 0; /** 133 * Y coordinate of cursor's hot spot, or clicking point. 134 */ 135 private static final int HOT_SPOT_Y = 0; } Devin Kwok: Dossier 2008 C: The Program: Page 78 of 185

80 Class: EditToolPanel 01 package com.gmail.kwok.devin.gui.tool.edit; import javax.swing.boxlayout; 04 import javax.swing.jlabel; 05 import javax.swing.jpanel; 06 import javax.swing.jscrollpane; 07 import javax.swing.border.etchedborder; 08 import javax.swing.border.titledborder; 09 import javax.swing.event.listselectionevent; 10 import javax.swing.event.listselectionlistener; import com.gmail.kwok.devin.gui.statetable; 13 import com.gmail.kwok.devin.gui.panel.universepanel; /** 16 * A panel containing a state table for changing the values of individual cells. 17 * 18 Devin Kwok 19 * 20 */ 21 public class EditToolPanel extends JPanel 22 { 23 /** 24 * 25 */ 26 private static final long serialversionuid = 1L; /** 29 * Constructs a new edit tool panel. 30 * 31 universepanel universe panel which contains needed functions. 32 */ 33 public EditToolPanel( UniversePanel universepanel ) 34 { 35 this.universepanel = universepanel; 36 this.setlayout( new BoxLayout( this, BoxLayout.Y_AXIS ) ); 37 label = new JLabel( "No address" ); 38 add( label ); 39 add( createtable() ); 40 } /** 43 * Creates a state table. 44 * 45 table. 46 */ 47 private JScrollPane createtable() 48 { 49 class StateSelectionListener implements ListSelectionListener 50 { 52 public void valuechanged( ListSelectionEvent e ) 53 { } 56 } ListSelectionListener listener = new StateSelectionListener(); 59 table = new StateTable( universepanel.getuniversecomponent() 60.getStateGraphics(), universepanel, listener ); Devin Kwok: Dossier 2008 C: The Program: Page 79 of 185

81 61 JScrollPane scrollpane = new JScrollPane( table ); 62 scrollpane.setborder( new TitledBorder( new EtchedBorder(), 63 "States in Universe" ) ); 64 return scrollpane; 65 } /** 68 * Sets the cell address which the state table will display values of. 69 * 70 celladdress cell address. 71 */ 72 public void setcelladdress( int celladdress ) 73 { 74 table.setcelladdress( celladdress ); 75 label.settext( "Cell address " + celladdress ); 76 table.repaint(); 77 } /** 80 * Universe panel reference for various functions. 81 */ 82 private UniversePanel universepanel; /** 85 * State table. 86 */ 87 private StateTable table; /** 90 * Label showing current cell address. 91 */ 92 private JLabel label; 93 } Devin Kwok: Dossier 2008 C: The Program: Page 80 of 185

82 C.I.xi: Package: com.gmai.kwok.devin.file Class: UniverseReader 001 package com.gmail.kwok.devin.file; import java.io.file; 004 import java.io.ioexception; 005 import java.io.randomaccessfile; import javax.swing.jfilechooser; 008 import javax.swing.joptionpane; 009 import javax.swing.filechooser.filenameextensionfilter; import com.gmail.kwok.devin.gui.resource; 012 import com.gmail.kwok.devin.gui.component.universe2dcomponent; 013 import com.gmail.kwok.devin.gui.component.universecomponent; 014 import com.gmail.kwok.devin.gui.frame.universeframe; 015 import com.gmail.kwok.devin.rulesets.ruleset; 016 import com.gmail.kwok.devin.universe.universe; 017 import com.gmail.kwok.devin.universe.universe2d; 018 import com.gmail.kwok.devin.universe.change.stackoverflowexception; 019 import com.gmail.kwok.devin.universe.state.state; 020 import com.gmail.kwok.devin.universe.state.statedefinition; 021 import com.gmail.kwok.devin.universe.state.bool.booleanstate; 022 import com.gmail.kwok.devin.universe.state.doub.doublestate; 023 import com.gmail.kwok.devin.universe.state.integer.integerstate; /** 026 * 027 * A class for reading universe files. Universe files contain the state data and 028 * some other information about the universe, so that it may be reproduced at a 029 * later date. 030 * 031 Devin Kwok 032 * 033 */ 034 public class UniverseReader 035 { 036 /** 037 * Constructs a new universe reader. 038 * 039 rules rules of current simulation. 040 parentframe parent frame of dialog. 041 */ 042 public UniverseReader( RuleSet rules, UniverseFrame parentframe ) 043 { 044 this.rules = rules; 045 this.parentframe = parentframe; 046 showopendialog(); 047 } /** 050 * Shows a file chooser. 051 */ 052 private void showopendialog() 053 { 054 JFileChooser filechooser = new JFileChooser(); 055 filechooser.setfileselectionmode( JFileChooser.FILES_ONLY ); 056 FileNameExtensionFilter filter = new FileNameExtensionFilter( 057 "Universe Files", Resource.FILE_EXTENSION ); Devin Kwok: Dossier 2008 C: The Program: Page 81 of 185

83 058 filechooser.setfilefilter( filter ); int result = filechooser.showopendialog( parentframe ); if( result == JFileChooser.CANCEL_OPTION ) 063 return; File filename = filechooser.getselectedfile(); if( filename == null filename.getname().equals( "" ) ) 068 { 069 JOptionPane.showMessageDialog( parentframe, "Invalid File Name", 070 "Invalid File Name", JOptionPane.ERROR_MESSAGE ); 071 return; 072 } try 075 { 076 input = new RandomAccessFile( filename, "rw" ); 077 readfile(); 078 setframe(); 079 input.close(); 080 } 081 catch( IncompatibleFormatException e ) 082 { 083 JOptionPane.showMessageDialog( parentframe, "Error opening file", 084 "Format does not match current rules", 085 JOptionPane.ERROR_MESSAGE ); 086 return; 087 } 088 catch( IOException e ) 089 { 090 JOptionPane.showMessageDialog( parentframe, "Error opening file", 091 "Error opening file", JOptionPane.ERROR_MESSAGE ); 092 } 093 catch( StackOverflowException e ) 094 { 095 JOptionPane.showMessageDialog( parentframe, "Error opening file", 096 "Error initializing universe", JOptionPane.ERROR_MESSAGE ); 097 } 098 } /** 101 * Reads the file and constructs the universe. 102 * 103 IOException 104 StackOverflowException 105 */ 106 private void readfile() throws IOException, StackOverflowException, 107 IncompatibleFormatException 108 { 109 input.seek( 0 ); 110 statenumber = input.readint(); 111 universesize = input.readint(); 112 int properties = input.readint(); 113 // assume is universe 2D just for simplicity if( properties!= 2 ) 116 throw new IOException(); 117 int rows = input.readint(); 118 int columns = input.readint(); verifysignature(); Devin Kwok: Dossier 2008 C: The Program: Page 82 of 185

84 constructuniverse( rows, columns ); for( int i = 0; i < universe.getnumberofstates(); i++ ) 125 { 126 if( universe.getstate( i ).getdefinition().ismodifiable() ) 127 readdata( universe.getstate( i ) ); 128 } 129 } /** 132 * Verifies that the file signature matches the requirements of the current 133 * rule set. 134 * 135 IOException 136 IncompatibleFormatException 137 */ 138 private void verifysignature() throws IOException, 139 IncompatibleFormatException 140 { 141 definitions = rules.getstatedefinitions(); if( definitions.length!= statenumber ) 144 throw new IncompatibleFormatException(); for( StateDefinition definition : definitions ) 147 { 148 String s = ""; for( int i = 0; i < Resource.MAX_STRING_LENGTH; i++ ) 151 { 152 char c = input.readchar(); 153 if( c!= '\0' ) 154 s = s + c; 155 } 156 if( definition.ismodifiable() &&!s.equals( definition.gettype() ) ) 157 throw new IncompatibleFormatException(); 158 if(!definition.ismodifiable() &&!s.equals( "" ) ) 159 throw new IncompatibleFormatException(); 160 } 161 } /** 164 * Reads state data and initializes those values. 165 * 166 state state whose data is to be read. 167 IOException 168 StackOverflowException 169 */ 170 private void readdata( State state ) throws IOException, 171 StackOverflowException 172 { 173 String statetype = state.getdefinition().gettype(); 174 if( statetype.equals( StateDefinition.INTEGER ) ) 175 { 176 int[] values = new int[ universesize ]; for( int i = 0; i < universesize; i++ ) 179 { 180 values[ i ] = input.readint(); 181 } ( (IntegerState) state ).initialize( values ); Devin Kwok: Dossier 2008 C: The Program: Page 83 of 185

85 184 } 185 else if( statetype.equals( StateDefinition.DOUBLE ) ) 186 { 187 double[] values = new double[ universesize ]; for( int i = 0; i < universesize; i++ ) 190 { 191 values[ i ] = input.readdouble(); 192 } ( (DoubleState) state ).initialize( values ); 195 } 196 else if( statetype.equals( StateDefinition.BOOLEAN ) ) 197 { 198 boolean[] values = new boolean[ universesize ]; for( int i = 0; i < universesize; i++ ) 201 { 202 values[ i ] = input.readboolean(); 203 } ( (BooleanState) state ).initialize( values ); 206 } 207 else 208 { 209 // Should be one of the above. Do nothing. 210 } 211 universe.flushchanges(); 212 } /** 215 * Constructs the universe object for the simulation. 216 * 217 rows rows in universe. 218 columns columns in universe. 219 */ 220 private void constructuniverse( int rows, int columns ) 221 { 222 universe = new Universe2D( definitions, rules.getindependentrules(), 223 rows, columns ); 224 universe.setdefaultboundary(); 225 } /** 228 * Sets the universe frame to show the constructed universe. 229 */ 230 private void setframe() 231 { 232 UniverseComponent component = new Universe2DComponent( 233 (Universe2D) universe, rules.getdefaultgraphics( universe ) ); 234 parentframe.setcomponent( component ); 235 } /** 238 * Number of states in universe. 239 */ 240 private int statenumber; /** 243 * Size of universe. 244 */ 245 private int universesize; 246 Devin Kwok: Dossier 2008 C: The Program: Page 84 of 185

86 247 /** 248 * Current rules of simulation. 249 */ 250 private RuleSet rules; /** 253 * Input file. 254 */ 255 private RandomAccessFile input; /** 258 * Universe object (which is created by this object). 259 */ 260 private Universe universe; /** 263 * State definitions retrieved from current rules. 264 */ 265 private StateDefinition[] definitions; /** 268 * Parent frame of dialog. 269 */ 270 private UniverseFrame parentframe; 271 } Devin Kwok: Dossier 2008 C: The Program: Page 85 of 185

87 Class: UniverseWriter 001 package com.gmail.kwok.devin.file; import java.io.file; 004 import java.io.ioexception; 005 import java.io.randomaccessfile; import javax.swing.jfilechooser; 008 import javax.swing.jframe; 009 import javax.swing.joptionpane; 010 import javax.swing.filechooser.filenameextensionfilter; import com.gmail.kwok.devin.gui.resource; 013 import com.gmail.kwok.devin.universe.state.state; 014 import com.gmail.kwok.devin.universe.state.statedefinition; 015 import com.gmail.kwok.devin.universe.state.bool.booleanstate; 016 import com.gmail.kwok.devin.universe.state.doub.doublestate; 017 import com.gmail.kwok.devin.universe.state.integer.integerstate; 018 import com.gmail.kwok.devin.util.locationvector; /** 021 * A class for writing universe files. Universe files contain the state data and 022 * some other information about the universe, so that it may be reproduced at a 023 * later date. 024 * 025 Devin Kwok 026 * 027 */ 028 public class UniverseWriter 029 { 030 /** 031 * Constructs a new universe writer. 032 * 033 states states of universe 034 universeproperties location vector storing universe properties 035 * (changes depending on the universe type). 036 parentframe parent frame to display dialogue in. 037 */ 038 public UniverseWriter( State[] states, LocationVector universeproperties, 039 JFrame parentframe ) 040 { 041 this.parentframe = parentframe; 042 this.states = states; 043 this.universeproperties = universeproperties; 044 this.size = states[ 0 ].getsize(); showsavedialog(); 047 } /** 050 * Shows a file chooser. 051 */ 052 private void showsavedialog() 053 { 054 JFileChooser filechooser = new JFileChooser(); 055 filechooser.setfileselectionmode( JFileChooser.FILES_ONLY ); 056 FileNameExtensionFilter filter = new FileNameExtensionFilter( 057 "Universe Files", Resource.FILE_EXTENSION ); 058 filechooser.setfilefilter( filter ); int result = filechooser.showsavedialog( parentframe ); Devin Kwok: Dossier 2008 C: The Program: Page 86 of 185

88 if( result == JFileChooser.CANCEL_OPTION ) 063 return; File file = filechooser.getselectedfile(); 066 File filename = new File( file.getpath() + "." Resource.FILE_EXTENSION ); if( filename == null filename.getname().equals( "" ) ) 070 { 071 JOptionPane.showMessageDialog( parentframe, "Invalid File Name", 072 "Invalid File Name", JOptionPane.ERROR_MESSAGE ); 073 return; 074 } try 077 { 078 output = new RandomAccessFile( filename, "rw" ); 079 writefile(); 080 output.close(); 081 } 082 catch( IOException e ) 083 { 084 JOptionPane.showMessageDialog( parentframe, "Error saving file", 085 "Error saving file", JOptionPane.ERROR_MESSAGE ); 086 } 087 } /** 090 * Writes the file. 091 * 092 IOException 093 */ 094 private void writefile() throws IOException 095 { 096 writesignature(); for( int i = 0; i < states.length; i++ ) 099 { 100 if( states[ i ].getdefinition().ismodifiable() ) 101 { 102 writevalues( states[ i ] ); 103 } 104 } 105 } /** 108 * Writes the signature which denotes the size of the universe and the 109 * states stored within. 110 * 111 IOException 112 */ 113 private void writesignature() throws IOException 114 { 115 output.seek( 0 ); 116 output.writeint( states.length ); 117 output.writeint( size ); 118 output.writeint( universeproperties.getlength() ); 119 for( int i = 0; i < universeproperties.getlength(); i++ ) 120 { 121 output.writeint( universeproperties.getvalue( i ) ); 122 } 123 Devin Kwok: Dossier 2008 C: The Program: Page 87 of 185

89 124 writestatetypes(); 125 } /** 128 * Writes the names of the states within as part of the signature. 129 * 130 IOException 131 */ 132 private void writestatetypes() throws IOException 133 { 134 for( State state : states ) 135 { 136 StringBuffer buffer; 137 if( state.getdefinition().ismodifiable() ) 138 buffer = new StringBuffer( state.gettype() ); 139 else 140 buffer = new StringBuffer( Resource.MAX_STRING_LENGTH ); 141 buffer.setlength( Resource.MAX_STRING_LENGTH ); 142 output.writechars( buffer.tostring() ); 143 } 144 } /** 147 * Writes the values of each state. 148 * 149 state state whose values are to be written. 150 IOException 151 */ 152 private void writevalues( State state ) throws IOException 153 { 154 if( state.gettype().equals( StateDefinition.INTEGER ) ) 155 { 156 IntegerState intstate = (IntegerState) state; for( int i = 0; i < size; i++ ) 159 { 160 int value = intstate.getintegervalue( i ); 161 output.writeint( value ); 162 } 163 } 164 else if( state.gettype().equals( StateDefinition.DOUBLE ) ) 165 { 166 DoubleState doubstate = (DoubleState) state; for( int i = 0; i < size; i++ ) 169 { 170 double value = doubstate.getvalue( i ); 171 output.writedouble( value ); 172 } 173 } 174 else if( state.gettype().equals( StateDefinition.BOOLEAN ) ) 175 { 176 BooleanState boolstate = (BooleanState) state; for( int i = 0; i < size; i++ ) 179 { 180 boolean value = boolstate.getbooleanvalue( i ); 181 output.writeboolean( value ); 182 } 183 } 184 else 185 { 186 // Should be one of the above. Do nothing. Devin Kwok: Dossier 2008 C: The Program: Page 88 of 185

90 187 } 188 } /** 191 * Size of universe. 192 */ 193 private int size; /** 196 * States within universe. 197 */ 198 private State[] states; /** 201 * Output file. 202 */ 203 private RandomAccessFile output; /** 206 * Properties of universe. 207 */ 208 private LocationVector universeproperties; /** 211 * Parent frame of dialog. 212 */ 213 private JFrame parentframe; 214 } Devin Kwok: Dossier 2008 C: The Program: Page 89 of 185

91 Class: IncompatibleFormatException 01 package com.gmail.kwok.devin.file; import java.io.ioexception; /** 06 * An exception class for when a file format does not have the same states as 07 * required by the current rule set. 08 * 09 Devin Kwok 10 * 11 */ 12 public class IncompatibleFormatException extends IOException 13 { 14 /** 15 * 16 */ 17 private static final long serialversionuid = 1L; /** 20 * Constructs a new IncompatibleFormatException. 21 */ 22 public IncompatibleFormatException() 23 { 24 } /** 27 * Constructs a new IncompatibleFormatException. 28 * 29 message message to be displayed. 30 */ 31 public IncompatibleFormatException( String message ) 32 { 33 super( message ); 34 } 35 } Devin Kwok: Dossier 2008 C: The Program: Page 90 of 185

92 C.I.xii: Package: com.gmai.kwok.devin.rulesets Interface: RuleSet 01 package com.gmail.kwok.devin.rulesets; import com.gmail.kwok.devin.gui.graphics.stategraphic; 04 import com.gmail.kwok.devin.universe.universe; 05 import com.gmail.kwok.devin.universe.rule.independent.independentrulelist; 06 import com.gmail.kwok.devin.universe.state.statedefinition; /** 09 * A temporary interface for handling sets of rules for running simulations. 10 * Used by the program to create universes. 11 * 12 Devin Kwok 13 * 14 */ 15 public interface RuleSet 16 { 17 /** 18 * Returns a list of independent rules. 19 * 20 independent rules. 21 */ 22 IndependentRuleList getindependentrules(); /** 25 * Returns an array of state definitions. 26 * 27 state definitions. 28 */ 29 StateDefinition[] getstatedefinitions(); /** 32 * Returns the default state graphic objects for the simulation. Currently 33 * these are THE state graphic objects because there is no means by which 34 * the user may modify them. 35 * 36 u universe to create the objects for. 37 array of state graphics. 38 */ 39 StateGraphic[] getdefaultgraphics( Universe u ); /** 42 * Returns the universe type. Needed for file handling in the future when 43 * multiple implementations are used. 44 * 45 String denoting the universe type required by these rules. 46 */ 47 String getuniversetype(); 48 } Devin Kwok: Dossier 2008 C: The Program: Page 91 of 185

93 Class: GameOfLifeRuleSet 001 package com.gmail.kwok.devin.rulesets; import com.gmail.kwok.devin.gui.graphics.stategraphic; 004 import com.gmail.kwok.devin.universe.universe; 005 import com.gmail.kwok.devin.universe.universe2d; 006 import com.gmail.kwok.devin.universe.cell.cellcollection; 007 import com.gmail.kwok.devin.universe.change.change; 008 import com.gmail.kwok.devin.universe.rule.dependent.dependentrule; 009 import com.gmail.kwok.devin.universe.rule.dependent.dependentrulelist; 010 import com.gmail.kwok.devin.universe.rule.independent.independentrule; 011 import com.gmail.kwok.devin.universe.rule.independent.independentrulelist; 012 import com.gmail.kwok.devin.universe.state.statedefinition; 013 import com.gmail.kwok.devin.universe.state.bool.booleandefinition; 014 import com.gmail.kwok.devin.universe.state.integer.integerdefinition; /** 017 * A set of rules for playing John Conway's Game of Life. 018 * 019 Devin Kwok 020 * 021 */ 022 public class GameOfLifeRuleSet implements RuleSet 023 { 024 /** 025 * Returns the independent rule list. 026 */ 028 public IndependentRuleList getindependentrules() 029 { 030 IndependentRule[] rule = { new GameOfLifeRule0() }; 031 return new IndependentRuleList( rule ); 032 } /** 035 * This rule determines whether a cell lives, dies, or is born. 036 * 037 Devin Kwok 038 * 039 */ 040 private class GameOfLifeRule0 implements IndependentRule 041 { 042 public Change getchange( CellCollection collection ) 043 { 044 double live = collection.celliterator().nextcell().getvalue( 0 ); 045 double neighbors = collection.celliterator().nextcell().getvalue( ); 047 double changevalue = 0; if( live == 1 && ( neighbors < 2 neighbors > 3 ) ) 050 changevalue = -1; 051 if( live == 0 && neighbors == 3 ) 052 changevalue = 1; return new Change( 0, changevalue ); 055 } public int getinputneighbourhood() 059 { 060 return 0; Devin Kwok: Dossier 2008 C: The Program: Page 92 of 185

94 061 } 062 } /** 065 * Returns the state definitions. 066 */ 068 public StateDefinition[] getstatedefinitions() 069 { 070 StateDefinition livedefinition = new BooleanDefinition( 0, 071 getgameoflifelist(), true ); 072 StateDefinition neighboursdefinition = new IntegerDefinition( 1, 073 new DependentRuleList(), false, 0, 0, 8 ); StateDefinition[] definitions = { livedefinition, 076 neighboursdefinition }; 077 return definitions; 078 } /** 081 * Returns the list of dependent rules. 082 * 083 dependent rules. 084 */ 085 public DependentRuleList getgameoflifelist() 086 { 087 DependentRule[] rules = new DependentRule[ 2 ]; rules[ 0 ] = new LifeRule0(); 090 rules[ 1 ] = new LifeRule1(); return new DependentRuleList( rules ); 093 } /** 096 * This rule modifies the neighborhood count when a cell is born or dies. 097 * 098 Devin Kwok 099 * 100 */ 101 private class LifeRule0 extends DependentRule 102 { 103 public Change getchange( CellCollection collection ) 104 { 105 Change change = super.getdistributedchange(); 106 return new Change( 1, change.getchangevalue() ); 107 } public int getoutputneighbourhood() 111 { 112 // TODO Auto-generated method stub 113 return 1; 114 } public int getinputneighbourhood() 118 { 119 // TODO Auto-generated method stub 120 return -1; 121 } 122 } 123 Devin Kwok: Dossier 2008 C: The Program: Page 93 of 185

95 124 /** 125 * This rule counters the previous rule so that the centre cell's 126 * neighbourhood count does not change. 127 * 128 Devin Kwok 129 * 130 */ 131 private class LifeRule1 extends DependentRule 132 { public Change getchange( CellCollection collection ) 135 { 136 Change change = super.getdistributedchange(); 137 return new Change( 1, change.getchangevalue() * -1 ); 138 } public int getinputneighbourhood() 142 { 143 // TODO Auto-generated method stub 144 return -1; 145 } public int getoutputneighbourhood() 149 { 150 // TODO Auto-generated method stub 151 return 0; 152 } 153 } /** 156 * Returns the state graphics objects, where live and dead cells are denoted 157 * by white and black and neighbours are not displayed. 158 */ 159 public StateGraphic[] getdefaultgraphics( Universe u ) 160 { 161 StateDefinition[] definitions = this.getstatedefinitions(); 162 StateGraphic[] graphic = new StateGraphic[ definitions.length ]; graphic[ 0 ] = new StateGraphic( definitions[ 0 ], u, true, true, 165 true ); 166 graphic[ 0 ].setcontinuous( false ); 167 graphic[ 0 ].setthreshold( 1 ); graphic[ 1 ] = new StateGraphic( definitions[ 1 ], u, false, false, 170 false ); return graphic; 173 } /** 176 * Returns the universe type as Universe2D. 177 */ 178 public String getuniversetype() 179 { 180 return Universe2D.UNIVERSE_2D; 181 } 182 } Devin Kwok: Dossier 2008 C: The Program: Page 94 of 185

96 C.I.xiii: Package: com.gmai.kwok.devin.universe Abstract Class: Universe 001 package com.gmail.kwok.devin.universe; import com.gmail.kwok.devin.universe.boundary.boundaryhandler; 004 import com.gmail.kwok.devin.universe.boundary.defaultboundary; 005 import com.gmail.kwok.devin.universe.cell.cell; 006 import com.gmail.kwok.devin.universe.cell.cellcollection; 007 import com.gmail.kwok.devin.universe.cell.celliterator; 008 import com.gmail.kwok.devin.universe.change.change; 009 import com.gmail.kwok.devin.universe.change.changestack; 010 import com.gmail.kwok.devin.universe.change.stackoverflowexception; 011 import com.gmail.kwok.devin.universe.rule.independent.independentrule; 012 import com.gmail.kwok.devin.universe.rule.independent.independentruleiterator; 013 import com.gmail.kwok.devin.universe.rule.independent.independentrulelist; 014 import com.gmail.kwok.devin.universe.state.state; 015 import com.gmail.kwok.devin.universe.state.statedefinition; 016 import com.gmail.kwok.devin.util.locationvector; /** 019 * A universe object defines the states and rules associated with the universe. 020 * It also handles the calculation of the next generation in the simulation, and 021 * any changes to be made. The universe object does not define how the universe 022 * is implemented: the number of dimensions, shape, and boundary handling is 023 * handled in subclasses. 024 * 025 Devin Kwok 026 * 027 */ 028 public abstract class Universe implements CellCollection, DefaultBoundary 029 { 030 /** 031 * Constructs a new universe with the given state definitions and 032 * independent rule list. 033 * 034 state keys of state definitions must match their index in the state 035 * definition array. 036 definitions array of state definitions. 037 list list of independent rules. 038 size number of cells in universe. 039 */ 040 public Universe( StateDefinition[] definitions, IndependentRuleList list, 041 int size ) 042 { 043 this.definitions = definitions; 044 this.states = new State[ definitions.length ]; 045 this.list = list; 046 this.changestack = new ChangeStack( this.states.length, size ); 047 this.appliedchanges = new ChangeStack( this.states.length, size ); 048 } /** 051 * Clears the contents of every cell in the universe. Must be called by 052 * constructor. 053 * 054 state keys of state definitions must match their index in the state 055 * definition array. Throws an IllegalArgumentException otherwise. 056 */ Devin Kwok: Dossier 2008 C: The Program: Page 95 of 185

97 058 public void clearall() 059 { 060 for( int i = 0; i < this.definitions.length; i++ ) 061 { 062 StateDefinition definition = this.definitions[ i ]; 063 if( definition.getstatekey()!= i ) 064 throw new IllegalArgumentException( 065 "State keys do not match position." ); states[ i ] = definition.constructstate( this ); 068 } 069 } /** 072 * Gets the value of a specified state at a specified cell address. 073 * 074 statekey integer key referring to the state. 075 celladdress integer address of cell. 076 value at the given state and cell address. 077 */ 078 public double getvalue( int statekey, int celladdress ) 079 { 080 return states[ statekey ].getvalue( celladdress ); 081 } /** 084 * Sets the value of a specified state and cell address to a specified 085 * value. 086 * 087 statekey integer key referring to the state. 088 celladdress integer address of cell. 089 newvalue new value to be setat the given state and cell address. 090 */ 091 public void setvalue( int statekey, int celladdress, double newvalue ) 092 { 093 this.states[ statekey ].setvalue( celladdress, newvalue ); 094 } /** 097 * Returns neighbours for a given cell. The locales of the neighbours 098 * depends on the implementation of the universe. For all addresses, when 099 * neighbours is 0 the universe must return the cell at the specified 100 * address. If the neighbour count is less than 0, no cells are returned. 101 * 102 celladdress address of centre cell. 103 neighbours number of neighbours to return. If equal to 0, returns 104 * the cell at the specified address. 105 cell collection containing neighbours. 106 */ 107 public abstract CellCollection getneighbours( int celladdress, 108 int neighbours ); /** 111 * Gets a cell at a specified cell address. 112 * 113 celladdress integer address of cell. 114 cell at the given address. 115 */ 116 public abstract Cell getcell( int celladdress ); /** 119 * Calculates the next generation of the simulation. The universe iterates 120 * through each independent rule, and each rule is then applied to every Devin Kwok: Dossier 2008 C: The Program: Page 96 of 185

98 121 * cell in the universe according to the order returned by the universe's 122 * cell iterator. After doing so, the universe flushes its change queue and 123 * applies all changes until none remain. 124 */ 125 public void nextgeneration() throws StackOverflowException 126 { 127 IndependentRuleIterator ruleiterator = list.ruleiterator(); while( ruleiterator.hasnext() ) 130 { 131 IndependentRule rule = ruleiterator.nextrule(); 132 CellIterator celliterator = this.celliterator(); while( celliterator.hasnextcell() ) 135 { 136 Cell cell = celliterator.nextcell(); 137 CellCollection collection = this.getneighbours( cell 138.getCellAddress(), rule.getinputneighbourhood() ); 139 Change newchange = rule.getchange( collection ); if( newchange!= null ) 142 { 143 CellCollection newcollection = this.getneighbours( cell 144.getCellAddress(), 0 ); 145 newcollection.addchangeforall( newchange ); 146 } 147 } 148 } this.flushchanges(); 151 } /** 154 * Applies all changes in the change queue. Refreshes states after. 155 */ 156 public void flushchanges() throws StackOverflowException 157 { 158 while( changestack.haschanges() ) 159 { 160 Change change = changestack.removechange(); 161 appliedchanges.addchange( change ); 162 this.applychange( change ); 163 } for( State state : states ) 166 { 167 state.refresh(); 168 } 169 } /** 172 * Applies a change to the universe. 173 * 174 change the change to be applied. 175 */ 176 private void applychange( Change change ) 177 { 178 this.states[ change.getstatekey() ].applychange( change ); 179 } /** 182 * Adds a change to the universe's change stack. 183 * Devin Kwok: Dossier 2008 C: The Program: Page 97 of 185

99 184 change change to be added to queue. 185 StackOverflowException 186 */ 187 public void addchange( Change change ) throws StackOverflowException 188 { 189 changestack.addchange( change ); 190 this.states[ change.getstatekey() ].distributechange( change ); 191 } /** 194 * Implemented from CellCollection. Applies a change to every cell in the 195 * universe, using the universe's iterator. 196 */ 197 public void addchangeforall( Change change ) 198 throws StackOverflowException 199 { 200 CellIterator iterator = this.celliterator(); 201 while( iterator.hasnextcell() ) 202 { 203 iterator.nextcell().addchangeforall( change ); 204 } 205 } /** 208 * Returns a change stack of the changes that have already been applied. 209 * Used to update the display components * 211 change stack. 212 */ 213 public ChangeStack getappliedchanges() 214 { 215 return appliedchanges; 216 } /** 219 * Sets the contents of a cell to their default value. 220 * <= cell address < universe.getsize(). 222 celladdress address of cell to set. 223 */ 224 public void clearcell( int celladdress ) 225 { 226 for( State state : states ) 227 { 228 state.setvalue( celladdress, state.getdefinition() 229.getDefaultValue() ); 230 } 231 } /** 234 * Returns the number of states in the universe. 235 * 236 integer representing the number of states. 237 */ 238 public int getnumberofstates() 239 { 240 return states.length; 241 } /** 244 * Returns the state at the given state key. 245 * 246 statekey integer key of state. Devin Kwok: Dossier 2008 C: The Program: Page 98 of 185

100 247 state at the given integer key. 248 */ 249 public State getstate( int statekey ) 250 { 251 return states[ statekey ]; 252 } /** 255 * Returns the current boundary handler for the universe. 256 * 257 boundary handler. 258 */ 259 public BoundaryHandler getboundaryhandler() 260 { 261 return boundaryhandler; 262 } /** 265 * Sets the current boundary handler for the universe. 266 * 267 handler boundary handler. 268 */ 269 protected void setboundaryhandler( BoundaryHandler handler ) 270 { 271 this.boundaryhandler = handler; 272 } /** 275 * Sets the default boundary handler. 276 */ 277 public void setdefaultboundary() 278 { 279 this.setboundaryhandler( new DefaultHandler( this ) ); 280 } /** 283 * The default boundary handler. Causes all out of bounds cells to exhibit 284 * their default values. 285 * 286 Devin Kwok 287 * 288 */ 289 private class DefaultHandler implements BoundaryHandler 290 { 291 public DefaultHandler( Universe universe ) 292 { 293 this.universe = universe; 294 } public Cell getoutofboundcell( LocationVector celllocation ) 298 { 299 return new Cell( universe, -1 ); 300 } private Universe universe; 303 } /** 306 * Boundary handler for universe. 307 */ 308 private BoundaryHandler boundaryhandler; 309 Devin Kwok: Dossier 2008 C: The Program: Page 99 of 185

101 310 /** 311 * Array of state definitions which the universe uses to define its states. 312 */ 313 private StateDefinition[] definitions; /** 316 * Array of states which the universe uses to store the values of different 317 * states for its cells. 318 */ 319 private State[] states; /** 322 * List of independent rules which is traversed whenever nextgeneration() is 323 * called. 324 */ 325 private IndependentRuleList list; /** 328 * A change stack which organizes and stores changes to be applied to the 329 * universe. 330 */ 331 private ChangeStack changestack; /** 334 * A change stack which contains changes already applied to the universe. 335 * Used by the graphics aspect to update the screen depiction. 336 */ 337 private ChangeStack appliedchanges; 338 } Devin Kwok: Dossier 2008 C: The Program: Page 100 of 185

102 Class: Universe1D 001 package com.gmail.kwok.devin.universe; import java.util.nosuchelementexception; import com.gmail.kwok.devin.universe.boundary.boundaryhandler; 006 import com.gmail.kwok.devin.universe.boundary.defaultboundary; 007 import com.gmail.kwok.devin.universe.boundary.wrappingboundary; 008 import com.gmail.kwok.devin.universe.cell.cell; 009 import com.gmail.kwok.devin.universe.cell.cellcollection; 010 import com.gmail.kwok.devin.universe.cell.celliterator; 011 import com.gmail.kwok.devin.universe.cell.celllist; 012 import com.gmail.kwok.devin.universe.rule.independent.independentrulelist; 013 import com.gmail.kwok.devin.universe.state.statedefinition; 014 import com.gmail.kwok.devin.util.locationvector; /** 017 * A 1 dimensional universe with neighbours defined as adjacent cells to either 018 * side. 019 * 020 Devin Kwok 021 * 022 */ 023 public class Universe1D extends Universe implements DefaultBoundary, 024 WrappingBoundary 025 { /** 028 * Constructs a new 1D universe. 029 * 030 definitions state definitions. 031 list independent rules. 032 size size of universe. 033 */ 034 public Universe1D( StateDefinition[] definitions, 035 IndependentRuleList list, int size ) 036 { 037 super( definitions, list, size ); 038 universe1d = new Cell[ size ]; 039 clearall(); 040 } /** 043 * Clears all cells to default values. 044 */ 045 public void clearall() 046 { 047 super.clearall(); 048 for( int i = 0; i < universe1d.length; i++ ) 049 universe1d[ i ] = new Cell( this, i ); 050 } /** 053 * Returns the cell collection of neighbours. The parameter neighbours is 054 * the number of cells to either side of the cell specified by the cell 055 * address:<br> 056 * [2][1][0][1][2] 057 */ 059 public CellCollection getneighbours( int celladdress, int neighbours ) 060 { Devin Kwok: Dossier 2008 C: The Program: Page 101 of 185

103 061 if( neighbours < -1 ) 062 return null; CellList collection = new CellList(); 065 collection.addlast( this.getcell( celladdress ) ); for( int i = 1; i <= neighbours; i++ ) 068 { 069 collection.addlast( this.getcell( celladdress + i ) ); 070 collection.addlast( this.getcell( celladdress - i ) ); 071 } return collection; 074 } /** 077 * Returns a cell iterator for the universe. 078 */ 080 public CellIterator celliterator() 081 { 082 return new Universe1DIterator(); 083 } /** 086 * Returns the universe size. 087 */ 089 public int getsize() 090 { 091 return universe1d.length; 092 } /** 095 * Returns the cell at the given cell address. 096 */ 098 public Cell getcell( int celladdress ) 099 { 100 try 101 { 102 return universe1d[ celladdress ]; 103 } 104 catch( ArrayIndexOutOfBoundsException e ) 105 { 106 return super.getboundaryhandler().getoutofboundcell( 107 new LocationVector( celladdress ) ); 108 } 109 } /** 112 * Sets the boundary handler as a wrapping boundary. 113 */ 115 public void setwrappingboundary() 116 { 117 super.setboundaryhandler( new WrappingHandler() ); 118 } /** 121 * Returns a string representation of the universe. 122 */ 123 public String tostring() Devin Kwok: Dossier 2008 C: The Program: Page 102 of 185

104 124 { 125 Strin g s = ""; 126 for( int i = 0; i < universe1d.length; i++ ) 127 { 128 s = s + universe1d[ i ].tostring() + ", "; 129 } 130 s = s.substring( 0, s.length() - 2 ) + "\n"; 131 return s; 132 } /** 135 * A 1D array stores the cells of the universe. 136 */ 137 private Cell[] universe1d; /** 140 * Universe iterator. 141 * 142 Devin Kwok 143 * 144 */ 145 private class Universe1DIterator implements CellIterator 146 { 147 /** 148 * Constructs a new universe iterator. 149 */ 150 public Universe1DIterator() 151 { 152 position = 0; 153 } /** 156 * Returns true if there are further cells. 157 */ 159 public boolean hasnextcell() 160 { 161 return position < universe1d.length; 162 } /** 165 * Returns the next cell. 166 */ 168 public Cell nextcell() 169 { 170 if(!hasnextcell() ) 171 throw new NoSuchElementException(); 172 position++; 173 return universe1d[ position - 1 ]; 174 } /** 177 * Current index position of iterator. 178 */ 179 private int position; 180 } /** 183 * A wrapping boundary handler which loops out of bounds cells to the 184 * opposite end, much as if the universe were circular. 185 * 186 Devin Kwok Devin Kwok: Dossier 2008 C: The Program: Page 103 of 185

105 187 * 188 */ 189 private class WrappingHandler implements BoundaryHandler 190 { 192 public Cell getoutofboundcell( LocationVector celllocation ) 193 { 194 int address = celllocation.getvalue( 0 ); 195 if( celllocation.getvalue( 0 ) < 0 ) 196 return getcell( address + getsize() ); 197 return getcell( address - getsize() ); 198 } 199 } 200 } Devin Kwok: Dossier 2008 C: The Program: Page 104 of 185

106 Class: Universe2D 001 package com.gmail.kwok.devin.universe; import com.gmail.kwok.devin.universe.boundary.defaultboundary; 004 import com.gmail.kwok.devin.universe.cell.cell; 005 import com.gmail.kwok.devin.universe.cell.cellcollection; 006 import com.gmail.kwok.devin.universe.cell.celliterator; 007 import com.gmail.kwok.devin.universe.cell.celllist; 008 import com.gmail.kwok.devin.universe.rule.independent.independentrulelist; 009 import com.gmail.kwok.devin.universe.state.statedefinition; 010 import com.gmail.kwok.devin.util.locationvector; /** 013 * A universe which is implemented as a 2 dimensional array of square cells. 014 * Neighbourhoods are defined by the Moore neighbourhood method. 015 * 016 Devin Kwok 017 * 018 */ 019 public class Universe2D extends Universe implements DefaultBoundary 020 { 021 /** 022 * Constructs a new 2D universe. 023 * 024 definitions state definitions. 025 list independent rules. 026 rows number of rows. 027 columns number of columns. 028 */ 029 public Universe2D( StateDefinition[] definitions, 030 IndependentRuleList list, int rows, int columns ) 031 { 032 super( definitions, list, rows * columns ); 033 this.rows = rows; 034 this.columns = columns; 035 universe2d = new Cell[ rows ][ columns ]; clearall(); 038 } /** 041 * Clears all cells to default values. 042 */ 043 public void clearall() 044 { 045 super.clearall(); for( int i = 0; i < rows; i++ ) 048 { 049 for( int j = 0; j < columns; j++ ) 050 { 051 universe2d[ i ][ j ] = new Cell( this, this 052.getCellAddress( new LocationVector( i, j ) ) ); 053 } 054 } 055 } /** 058 * Returns a cell list with the given neighbours around a single cell. The 059 * radius of the neighbourhood is the number of cells from the center cell 060 * to the edge of the neighbourhood. Neighbours are ordered by counting from Devin Kwok: Dossier 2008 C: The Program: Page 105 of 185

107 061 * the top left cell clockwise, starting at r = 0 and continuing. Example of 062 * neighbourhood radius 2: <br> 063 * [09][10][11][12][13]<br> 064 * [24][01][02][03][14]<br> 065 * [23][08][00][04][15]<br> 066 * [22][07][06][05][16]<br> 067 * [21][20][19][18][17]<br> 068 * 069 celladdress address of center cell 070 neighbours radius of neighbourhood. 071 CellCollection containing neighbours in the above order 072 */ 074 public CellCollection getneighbours( int celladdress, int neighbours ) 075 { 076 if( neighbours < 0 ) 077 return null; 078 CellList list = new CellList(); 079 list.addlast( this.getcell( celladdress ) ); int row = this.getrowaddress( celladdress ); 082 int col = this.getcolumnaddress( celladdress ); for( int i = 1; i <= neighbours; i++ ) 085 { 086 row--; 087 col--; 088 int side = i * 2; 089 for( int j = 0; j < side; j++ ) 090 { 091 list.addlast( this.getcell( new LocationVector( row, col ) ) ); 092 col++; 093 } for( int j = 0; j < side; j++ ) 096 { 097 list.addlast( this.getcell( new LocationVector( row, col ) ) ); 098 row++; 099 } for( int j = 0; j < side; j++ ) 102 { 103 list.addlast( this.getcell( new LocationVector( row, col ) ) ); 104 col--; 105 } for( int j = 0; j < side; j++ ) 108 { 109 list.addlast( this.getcell( new LocationVector( row, col ) ) ); 110 row--; 111 } 112 } return list; 115 } /** 118 * Returns the cell address at the location vector in the form of (row, 119 * column). 120 */ 121 public int getcelladdress( LocationVector location ) 122 { 123 if( withinbounds( location ) ) Devin Kwok: Dossier 2008 C: The Program: Page 106 of 185

108 124 return location.getvalue( 0 ) * columns + location.getvalue( 1 ); 125 return -1; 126 } /** 129 * Returns true if the location vector is within bounds. 130 * 131 location location vector in the form (row, column) 132 true if within bounds. 133 */ 134 public boolean withinbounds( LocationVector location ) 135 { 136 int row = location.getvalue( 0 ); 137 int col = location.getvalue( 1 ); 138 if( 0 <= row && row < rows && 0 <= col && col < columns ) 139 return true; 140 return false; 141 } /** 144 * Returns the row address of the specified cell address. 145 * 146 celladdress address of cell. 147 row index. 148 */ 149 public int getrowaddress( int celladdress ) 150 { 151 return celladdress / rows; 152 } /** 155 * Returns the column address of the specified cell address. 156 * 157 celladdress address of cell. 158 column index. 159 */ 160 public int getcolumnaddress( int celladdress ) 161 { 162 return celladdress % rows; 163 } /** 166 * Returns the size of the universe. 167 */ 168 public int getsize() 169 { 170 return rows * columns; 171 } /** 174 * Returns the cell at the given cell address. 175 */ 177 public Cell getcell( int celladdress ) 178 { 179 return universe2d[ getrowaddress( celladdress ) ][ getcolumnaddress( celladdress ) ]; 180 } /** 183 * Returns the cell at the given location vector. 184 * 185 location location vector in the form (row, column) Devin Kwok: Dossier 2008 C: The Program: Page 107 of 185

109 186 cell at the given coordinates. 187 */ 188 public Cell getcell( LocationVector location ) 189 { 190 try 191 { 192 return universe2d[ location.getvalue( 0 ) ][ location 193.getValue( 1 ) ]; 194 } 195 catch( ArrayIndexOutOfBoundsException e ) 196 { 197 return super.getboundaryhandler().getoutofboundcell( location ); 198 } 199 } /** 202 * Returns the number of rows in the universe. 203 * 204 rows. 205 */ 206 public int getrows() 207 { 208 return rows; 209 } /** 212 * Returns the number of columns in the universe. 213 * 214 columns. 215 */ 216 public int getcolumns() 217 { 218 return columns; 219 } /** 222 * Returns a cell iterator for the universe. 223 */ 224 public CellIterator celliterator() 225 { 226 return new Universe2DMooreIterator(); 227 } /** 230 * Returns a string representation of the universe. 231 */ 232 public String tostring() 233 { 234 String s = ""; 235 for( int i = 0; i < rows; i++ ) 236 { 237 for( int j = 0; j < columns; j++ ) 238 { 239 s = s + universe2d[ i ][ j ].tostring() + ", "; 240 } s = s.substring( 0, s.length() - 2 ) + "\n"; 243 } 244 return s; 245 } /** 248 * 2D array of cells in the universe. Devin Kwok: Dossier 2008 C: The Program: Page 108 of 185

110 249 */ 250 private Cell[][] universe2d; /** 253 * Number of rows in the universe. 254 */ 255 private int rows; /** 258 * Number of columns in the universe. 259 */ 260 private int columns; /** 263 * String identifier of this class. Used for future file handling. 264 */ 265 public static final String UNIVERSE_2D = "u2d"; /** 268 * Universe iterator. 269 * 270 Devin Kwok 271 * 272 */ 273 private class Universe2DMooreIterator implements CellIterator 274 { 275 /** 276 * Constructs a new universe iterator. 277 */ 278 public Universe2DMooreIterator() 279 { 280 col = -1; 281 row = 0; 282 } /** 285 * Returns true if there are further cells. 286 */ 288 public boolean hasnextcell() 289 { 290 return!( row == rows - 1 && col == columns - 1 ); 291 } /** 294 * Returns the next cell. 295 */ 297 public Cell nextcell() 298 { 299 col++; 300 if( col == columns ) 301 { 302 row++; 303 col = 0; 304 } 305 return universe2d[ row ][ col ]; 306 } /** 309 * Current row index of iterator. 310 */ 311 private int row; Devin Kwok: Dossier 2008 C: The Program: Page 109 of 185

111 /** 314 * Current column index of iterator. 315 */ 316 private int col; 317 } 318 } Devin Kwok: Dossier 2008 C: The Program: Page 110 of 185

112 Folder test: Test Class: Universe2DTest 001 package com.gmail.kwok.devin.universe; import com.gmail.kwok.devin.universe.cell.cellcollection; 004 import com.gmail.kwok.devin.universe.cell.celliterator; 005 import com.gmail.kwok.devin.universe.change.change; 006 import com.gmail.kwok.devin.universe.change.stackoverflowexception; 007 import com.gmail.kwok.devin.universe.rule.independent.independentrulelisttest; 008 import com.gmail.kwok.devin.universe.state.statedefinition; 009 import com.gmail.kwok.devin.universe.state.statedefinitiontest; 010 import com.gmail.kwok.devin.util.locationvector; import junit.framework.testcase; public class Universe2DTest extends TestCase 015 { 016 private static final int SIDE_LENGTH = 50; 017 private static final int ADDRESS = 6; 018 private static final int STEPS = 5; 019 private static final int NEIG HBOURS = 2; 020 private static final boolean doprint = true; 021 private static final int[][] startpattern = { // <br> 022 /* */{ 0, 1, 0, 0, 0 }, // <br> 023 { 0, 0, 1, 0, 0 }, // <br> 024 { 1, 1, 1, 0, 0 }, // <br> 025 { 0, 0, 0, 0, 0 }, // <br> 026 { 0, 0, 0, 0, 0 } }; public static void main( String[] args ) 029 { 030 Universe2D u = get2duniverse( getdefinitions() ); CellCollection collection = u.getneighbours( ADDRESS, NEIGHBOURS ); 033 CellIterator iterator = collection.celliterator(); 034 while( iterator.hasnextcell() ) 035 { 036 System.out.println( iterator.nextcell() ); 037 } if( doprint ) 040 System.out.println( "Initialized...\n" + u.tostring() ); 041 applystartpattern( u ); 042 if( doprint ) 043 System.out.println( "Start Pattern...\n" + u.tostring() ); long elapsedtime = 0; 046 for( int i = 0; i < STEPS; i++ ) 047 { 048 System.out.println( "Generation " + i ); 049 elapsedtime = elapsedtime + nextgeneration( u ); 050 } 051 System.out.println( "Elapsed time for calculating generations: " elapsedtime ); 053 } public static long nextgeneration( Universe u ) 056 { 057 long a = System.currentTimeMillis(); 058 try 059 { 060 u.nextgeneration(); Devin Kwok: Dossier 2008 C: The Program: Page 111 of 185

113 061 } 062 catch( StackOverflowException e ) 063 { 064 // TODO Auto-generated catch block 065 e.printstacktrace(); 066 } 067 a = System.currentTimeMillis() - a; 068 if( doprint ) 069 System.out.println( u.tostring() ); 070 return a; 071 } public static Universe2D get2duniverse( StateDefinition[] definitions ) 074 { 075 IndependentRuleListTest indtest = new IndependentRuleListTest(); 076 Universe2D u = new Universe2D( definitions, indtest 077.getGameOfLifeRules(), SIDE_LENGTH, SIDE_LENGTH ); 078 u.setdefaultboundary(); 079 return u; 080 } public static StateDefinition[] getdefinitions() 083 { 084 StateDefinitionTest test = new StateDefinitionTest(); 085 return test.getgameoflifedefinitions(); 086 } public static void applystartpattern( Universe2D u ) 089 { 090 for( int i = 0; i < startpattern.length; i++ ) 091 { 092 for( int j = 0; j < startpattern[0].length; j++ ) 093 { 094 try 095 { 096 u.addchange( new Change( 0, u 097.getCellAddress( new LocationVector( i, j ) ), 098 startpattern[ i ][ j ] ) ); 099 } 100 catch( StackOverflowException e ) 101 { 102 // TODO Auto-generated catch block 103 e.printstacktrace(); 104 } 105 } 106 } try 109 { 110 u.flushchanges(); 111 } 112 catch( StackOverflowException e ) 113 { 114 // TODO Auto-generated catch block 115 e.printstacktrace(); 116 } 117 } 118 } Devin Kwok: Dossier 2008 C: The Program: Page 112 of 185

114 C.I.xiv: Package: com.gmai.kwok.devin.universe.boundary Interface: BoundaryHandler 01 package com.gmail.kwok.devin.universe.boundary; import com.gmail.kwok.devin.universe.cell.cell; 04 import com.gmail.kwok.devin.util.locationvector; /** 07 * A boundary handler is an object which allows the universe to define how 08 * finite bounds are dealt with by the calculation of generations. 09 * 10 Devin Kwok 11 * 12 */ 13 public interface BoundaryHandler 14 { 15 /** 16 * Gets the out of bounds cell. 17 * 18 celllocation vector denoting cell's location. 19 cell cell. 20 */ 21 Cell getoutofboundcell( LocationVector celllocation ); 22 } Devin Kwok: Dossier 2008 C: The Program: Page 113 of 185

115 Interface: DefaultBoundary 01 package com.gmail.kwok.devin.universe.boundary; /** 04 * An interface which allows the universe to define a boundary of cells where 05 * any out of bounds addresses return default values. 06 * 07 Devin Kwok 08 * 09 */ 10 public interface DefaultBoundary 11 { 12 /** 13 * Sets the universe's boundary handler as the default boundary handler. 14 * */ 17 public void setdefaultboundary(); 18 } Devin Kwok: Dossier 2008 C: The Program: Page 114 of 185

116 Interface: WrappingBoundary 01 package com.gmail.kwok.devin.universe.boundary; public interface WrappingBoundary 04 { 05 /** 06 * Sets the universe's boundary handler as the default boundary handler. 07 * */ 10 public void setwrappingboundary(); 11 } Devin Kwok: Dossier 2008 C: The Program: Page 115 of 185

117 C.I.xv: Package: com.gmai.kwok.devin.universe.cell Class: Cell 001 package com.gmail.kwok.devin.universe.cell; import java.util.nosuchelementexception; import com.gmail.kwok.devin.universe.universe; 006 import com.gmail.kwok.devin.universe.change.change; 007 import com.gmail.kwok.devin.universe.change.stackoverflowexception; /** 010 * A cell is an object encapsulating the various state values at a finite 011 * position in the encompassing universe. The cell contains appropriate 012 * references to the actual values stored in the state objects of the universe. 013 * 014 Devin Kwok 015 * 016 */ 017 public class Cell implements CellCollection 018 { /** 021 * Constructs a new cell with its enclosing universe and integer address. 022 * 023 universe universe which the cell exists within. 024 celladdress integer address of cell. 025 */ 026 public Cell( Universe universe, int celladdress ) 027 { 028 this.universe = universe; 029 this.celladdress = celladdress; 030 } /** 033 * Returns the address of the cell. 034 * 035 integer address of cell. 036 */ 037 public int getcelladdress() 038 { 039 return celladdress; 040 } /** 043 * Sets the address of the cell. If the address is -1 the cell returns the 044 * state's default values. 045 * 046 cell address is smaller than the universe size and not less than celladdress integer address of cell. 048 */ 049 public void setcelladdress( int celladdress ) 050 { 051 if( celladdress < -1 celladdress >= universe.getsize() ) 052 throw new IllegalArgumentException( "Cell address out of bounds." ); 053 this.celladdress = celladdress; 054 } /** 057 * Returns the cell's value at the given state. Devin Kwok: Dossier 2008 C: The Program: Page 116 of 185

118 058 * 059 statekey integer key referring to the state. 060 value at the given state. 061 */ 062 public double getvalue( int statekey ) 063 { 064 return universe.getvalue( statekey, celladdress ); 065 } /** 068 * Sets the cell's value at the given state. 069 * 070 statekey integer key referring to the state. 071 value value to set at the given state. 072 */ 073 public void setvalue( int statekey, double value ) 074 { 075 universe.setvalue( statekey, celladdress, value ); 076 } /** 079 * Changes the value at the given state. 080 * 081 change change to be applied. 082 StackOverflowException 083 */ 084 public void changevalue( Change change ) throws StackOverflowException 085 { 086 change.setcelladdress( this.celladdress ); 087 universe.addchange( change ); 088 } /** 091 * Inherited from CellCollection. Functions the same as changevalue(change). 092 * 093 StackOverflowException 094 */ 095 public void addchangeforall( Change change ) 096 throws StackOverflowException 097 { 098 this.changevalue( change ); 099 } /** 102 * Implemented from CellCollection. Always returns */ 104 public int getsize() 105 { 106 return 1; 107 } /** 110 * Returns an iterator for the collection. 111 */ 112 public CellIterator celliterator() 113 { 114 return new SingleIterator( this ); 115 } /** 118 * Clears the contents at this cell. 119 */ Devin Kwok: Dossier 2008 C: The Program: Page 117 of 185

119 121 public void clearall() 122 { 123 universe.clearcell( this.celladdress ); 124 } /** 127 * Returns a string representation of this cell. 128 */ 129 public String tostring() 130 { 131 String s = this.celladdress + "{"; 132 for( int i = 0; i < universe.getnumberofstates(); i++ ) 133 { 134 s = s + universe.getstate( i ).tostring( this.celladdress ) ", "; 136 } 137 s = s.substring( 0, s.length() - 2 ) + "}"; 138 for( int i = s.length(); i < CELL_STRING_LENGTH; i++ ) 139 s = s + " "; 140 StringBuffer buffer = new StringBuffer( s ); 141 buffer.setlength( CELL_STRING_LENGTH ); return buffer.tostring(); 144 } 145 /** 146 * Reference to the cell's associated universe object from where the cell 147 * retrieves appropriate values. 148 */ 149 private Universe universe; /** 152 * Integer address of cell. 153 */ 154 private int celladdress; /** 157 * Length of string representation. 158 */ 159 private static final int CELL_STRING_LENGTH = 8; /** 162 * A cell iterator for a single cell. 163 * 164 Devin Kwok 165 * 166 */ 167 private class SingleIterator implements CellIterator 168 { 169 /** 170 * Constructs a new iterator. 171 * 172 cell 173 */ 174 public SingleIterator( Cell cell ) 175 { 176 next = true; 177 this.cell = cell; 178 } /** 181 * Returns true if the stored cell has not been traversed yet. 182 */ 183 public boolean hasnextcell() Devin Kwok: Dossier 2008 C: The Program: Page 118 of 185

120 184 { 185 return next; 186 } /** 189 * Returns the stored cell. 190 */ 191 public Cell nextcell() 192 { 193 if(!next ) 194 throw new NoSuchElementException(); 195 next = false; 196 return cell; 197 } /** 200 * True if the cell has not been traversed, false otherwise. 201 */ 202 private boolean next; /** 205 * Cell to be traversed. 206 */ 207 private Cell cell; 208 } 209 } Devin Kwok: Dossier 2008 C: The Program: Page 119 of 185

121 Interface: CellCollection 01 package com.gmail.kwok.devin.universe.cell; import com.gmail.kwok.devin.universe.change.change; 04 import com.gmail.kwok.devin.universe.change.stackoverflowexception; /** 07 * A cell collection is any object which contains a number of cells or 08 * references to cells, which can be traversed by the use of a cell iterator. 09 * The collection can also have a change applied to it. 10 * 11 Devin Kwok 12 * 13 */ 14 public interface CellCollection 15 { 16 /** 17 * Returns the number of cells in the collection. 18 * 19 integer representing the number of cells. 20 */ 21 int getsize(); /** 24 * Creates a change object for every cell in this cell collection. These are 25 * then fed into the universe's change queue. 26 * 27 change change to be applied 28 StackOverflowException 29 */ 30 void addchangeforall( Change change ) throws StackOverflowException; /** 33 * Sets every cell in the collection to its default values. 34 */ 35 void clearall(); /** 38 * Returns an appropriate cell iterator for the type. 39 * 40 CellIterator for the cell collection. 41 */ 42 CellIterator celliterator(); 43 } Devin Kwok: Dossier 2008 C: The Program: Page 120 of 185

122 Interface: CellIterator 01 package com.gmail.kwok.devin.universe.cell; /** 04 * A list iterator which can traverse any object implementing the interface 05 * CellCollection, starting from the first element and continuing to the end. 06 * Does not allow for the insertion or removal of cells. 07 * 08 Devin Kwok 09 * 10 */ 11 public interface CellIterator 12 { 13 /** 14 * Returns the next cell in the collection. 15 * 16 next cell to be traversed. 17 */ 18 Cell nextcell(); /** 21 * Returns true if the collection has another cell to retrieve. 22 * 23 true if the collection has further cells. 24 */ 25 boolean hasnextcell(); 26 } Devin Kwok: Dossier 2008 C: The Program: Page 121 of 185

123 Class: CellList 001 package com.gmail.kwok.devin.universe.cell; import com.gmail.kwok.devin.universe.change.change; 004 import com.gmail.kwok.devin.universe.change.stackoverflowexception; 005 import com.gmail.kwok.devin.util.linkedlist; 006 import com.gmail.kwok.devin.util.listiterator; /** 009 * A list which contains cell objects. Uses a linked list to store the actual 010 * elements but implements CellCollection. 011 * 012 Devin Kwok 013 * 014 */ 015 public class CellList implements CellCollection 016 { 017 /** 018 * Constructs a new cell list. 019 */ 020 public CellList() 021 { 022 list = new LinkedList(); 023 } /** 026 * Constructs a new cell list from the given array. 027 * 028 cells array of cells to be contained in the list. 029 */ 030 public CellList( Cell[] cells ) 031 { 032 list = new LinkedList( cells ); 033 } /** 036 * Adds a cell to the beginning of the list. 037 * 038 cell cell to be added. 039 */ 040 public void addfirst( Cell cell ) 041 { 042 list.addfirst( cell ); 043 } /** 046 * Adds a cell to the end of the list. 047 * 048 cell cell to be added. 049 */ 050 public void addlast( Cell cell ) 051 { 052 list.addlast( cell ); 053 } /** 056 * Changes all cells in the list by iterating through every cell and 057 * applying applychangetoall(change) to each cell. 058 * 059 StackOverflowException 060 */ Devin Kwok: Dossier 2008 C: The Program: Page 122 of 185

124 061 public void addchangeforall( Change change ) 062 throws StackOverflowException 063 { 064 CellIterator iterator = celliterator(); while( iterator.hasnextcell() ) 067 { 068 Cell cell = iterator.nextcell(); 069 cell.addchangeforall( change ); 070 } 071 } /** 074 * Returns the number of elements in the list. 075 */ 076 public int getsize() 077 { 078 return list.getsize(); 079 } /** 082 * Returns an iterator. 083 */ 084 public CellIterator celliterator() 085 { 086 return new CellListIterator(); 087 } /** 090 * Clears the contents of every cell in the list. 091 */ 093 public void clearall() 094 { 095 CellIterator iterator = celliterator(); while( iterator.hasnextcell() ) 098 { 099 iterator.nextcell().clearall(); 100 } 101 } /** 104 * An iterator for the cell list. 105 * 106 Devin Kwok 107 * 108 */ 109 private class CellListIterator implements CellIterator 110 { /** 113 * Constructs a new iterator. 114 */ 115 public CellListIterator() 116 { 117 iterator = list.listiterator(); 118 } /** 121 * Adds a cell to the list at the specified position. 122 */ 123 public void addcell( Cell cell ) Devin Kwok: Dossier 2008 C: The Program: Page 123 of 185

125 124 { 125 iterator.add( cell ); 126 } /** 129 * Removes a cell to the list at the specified position. 130 */ 131 public Cell removecell() 132 { 133 return (Cell) iterator.remove(); 134 } /** 137 * Returns true if the list has another cell. 138 */ 139 public boolean hasnextcell() 140 { 141 return iterator.hasnext(); 142 } /** 145 * Returns the next cell in the list. 146 */ 147 public Cell nextcell() 148 { 149 return (Cell) iterator.next(); 150 } /** 153 * List iterator from linked list. 154 */ 155 private ListIterator iterator; 156 } /** 159 * Linked list containing actual cells. 160 */ 161 private LinkedList list; 162 } Devin Kwok: Dossier 2008 C: The Program: Page 124 of 185

126 C.I.xvi: Package: com.gmai.kwok.devin.universe.change Class: Change 001 package com.gmail.kwok.devin.universe.change; /** 004 * A change object defines some change, in the form of a value to be added, to 005 * be made to a given state for a given cell, represented by its address. 006 * 007 Devin Kwok 008 * 009 */ 010 public class Change 011 { /** 014 * Constructs a new change with a given state key and change value. The 015 * address of the change is ignored. 016 * 017 statekey integer key referring to the state to be changed. 018 changevalue summative value of the change as type double. 019 */ 020 public Change( int statekey, double changevalue ) 021 { 022 this.statekey = statekey; 023 this.celladdress = -1; 024 this.changevalue = changevalue; 025 } /** 028 * Constructs a new change with a given state key, change value, and cell 029 * address. 030 * 031 state key may not be below cell address may not be below statekey integer key referring to the state to be changed. 034 celladdress integer address of cell to apply change to. 035 changevalue summative value of the change as type double. 036 */ 037 public Change( int statekey, int celladdress, double changevalue ) 038 { 039 this.statekey = statekey; 040 this.celladdress = celladdress; 041 this.changevalue = changevalue; 042 } /** 045 * Returns the state key of the state where the change is to be applied. 046 * 047 integer key referring to the state to be changed. 048 */ 049 public int getstatekey() 050 { 051 return statekey; 052 } /** 055 * Sets the state key of the state where the change is to be applied. 056 * 057 state key may not be below -1. Devin Kwok: Dossier 2008 C: The Program: Page 125 of 185

127 058 statekey integer key referring to the state to be changed. 059 */ 060 public void setstatekey( int statekey ) 061 { 062 this.statekey = statekey; 063 } /** 066 * Returns the address of the cell to which the change will be applied. 067 * 068 integer address of cell to apply change to. 069 */ 070 public int getcelladdress() 071 { 072 return celladdress; 073 } /** 076 * Sets the address of the cell to which the change will be applied. 077 * 078 cell address may not be below celladdress integer address of cell to apply change to. 080 */ 081 public void setcelladdress( int celladdress ) 082 { 083 this.celladdress = celladdress; 084 } /** 087 * Returns the value of the actual change to be applied. 088 * 089 double value of the change. 090 */ 091 public double getchangevalue() 092 { 093 return changevalue; 094 } /** 097 * Sets the value of the actual change to be applied. 098 * 099 changevalue double value of the change. 100 */ 101 public void setchangevalue( double changevalue ) 102 { 103 this.changevalue = changevalue; 104 } /** 107 * Clones the change. 108 */ 109 public Change clone() 110 { 111 return new Change( this.statekey, this.celladdress, this.changevalue ); 112 } /** 115 * Integer key of the state which the change is applied to. 116 */ 117 private int statekey; /** 120 * Integer address for cell to change. Devin Kwok: Dossier 2008 C: The Program: Page 126 of 185

128 121 */ 122 private int celladdress; /** 125 * Double value of change, which is summative, and thus is added to the 126 * appropriate value. 127 */ 128 private double changevalue; 129 } Devin Kwok: Dossier 2008 C: The Program: Page 127 of 185

129 Class: ChangeStack 001 package com.gmail.kwok.devin.universe.change; import java.util.nosuchelementexception; import com.gmail.kwok.devin.util.linkedlist; /** 008 * A stack of changes to be applied, which is held by a universe object. Changes 009 * are placed in the stack, where they are reconciled (similar changes are put 010 * together) into one change per cell, and then may be retrieved by the 011 * universe. The change stack is implemented in a hash table format, using the 012 * cell address and state key to group changes, for maximum speed searching for 013 * redundancy. The stack also has a linked list of hash table references for 014 * rapid removal of changes. The stack follows the first in first out property 015 * due to the ease with which this is done with a linked list. However, the 016 * order of the cell addresses from which changes are removed does not matter.<br> 017 * The size of the change queue is set at to prevent excessively large 018 * universes or universes with infinite loops from running. 019 * 020 Devin Kwok 021 * 022 */ 023 public class ChangeStack 024 { 025 /** 026 * Constructs a new change stack with the number of states and cells in the 027 * universe. 028 * 029 states number of states. 030 size number of cells. 031 */ 032 public ChangeStack( int states, int size ) 033 { 034 this.hashtable = new Change[ states * size ]; 035 this.stack = new LinkedList(); 036 this.states = states; 037 this.size = size; 038 resetall(); 039 } /** 042 * Resets all changes in the change stack. 043 */ 044 public void resetall() 045 { 046 for( int i = 0; i < states; i++ ) 047 { 048 for( int j = 0; j < size; j++ ) 049 { 050 hashtable[ j + i * size ] = new Change( i, j, 0 ); 051 } 052 } 053 } /** 056 * Returns true if the stack contains changes. 057 * 058 true if stack contains changes. 059 */ 060 public boolean haschanges() Devin Kwok: Dossier 2008 C: The Program: Page 128 of 185

130 061 { 062 if( stack.hasfirst() ) 063 return true; 064 return false; 065 } /** 068 * Adds a change to the stack. 069 * 070 change change to be added. 071 */ 072 public void addchange( Change change ) throws StackOverflowException 073 { 074 if( change.getchangevalue() == 0 change.getcelladdress() < 0 ) 075 return; if( stack.getsize() > DEFAULT_LIMIT ) 078 throw new StackOverflowException(); int hash = change.getcelladdress() + change.getstatekey() * size; 081 Change oldchange = hashtable[ hash ]; 082 double value = oldchange.getchangevalue(); oldchange.setchangevalue( value + change.getchangevalue() ); if( value == 0 ) 087 stack.addfirst( new Integer( hash ) ); 088 } /** 091 * Removes a change from the stack. 092 * 093 change that was removed. 094 */ 095 public Change removechange() 096 { 097 if(!haschanges() ) 098 throw new NoSuchElementException(); 099 int hash = (Integer) stack.removefirst(); 100 Change change = hashtable[ hash ].clone(); 101 hashtable[ hash ].setchangevalue( 0 ); 102 return change; 103 } /** 106 * Hash table of changes. 107 */ 108 private Change[] hashtable; /** 111 * Linked list containing integer references to where changes are in the 112 * hash table. 113 */ 114 private LinkedList stack; /** 117 * Number of states in the universe. 118 */ 119 private int states; /** 122 * Number of cells in the universe. 123 */ Devin Kwok: Dossier 2008 C: The Program: Page 129 of 185

131 124 private int size; /** 127 * The absolute maximum number of changes the stack may hold. This limit 128 * prevents an infinite loop from occurring. 129 */ 130 private static final int DEFAULT_LIMIT = ; 131 } Devin Kwok: Dossier 2008 C: The Program: Page 130 of 185

132 Class: StackOverflowException 01 package com.gmail.kwok.devin.universe.change; /** 04 * An exception which is thrown when the change stack exceeds its maximum number 05 * of elements. This helps reduce the possibility of an infinite loop or some 06 * other simulation error from occurring. 07 * 08 Devin Kwok 09 * 10 */ 11 public class StackOverflowException extends Exception 12 { 13 /** 14 * 15 */ 16 private static final long serialversionuid = 1L; /** 19 * Constructs a new StackOverflowException. 20 */ 21 public StackOverflowException() 22 { 23 } /** 26 * Constructs a new StackOverflowException with the specified message. 27 * 28 message message of exception. 29 */ 30 public StackOverflowException( String message ) 31 { 32 super( message ); 33 } 34 } Devin Kwok: Dossier 2008 C: The Program: Page 131 of 185

133 C.I.xvii: Package: com.gmai.kwok.devin.universe.rule Interface: Rule 01 package com.gmail.kwok.devin.universe.rule; import com.gmail.kwok.devin.universe.cell.cellcollection; 04 import com.gmail.kwok.devin.universe.change.change; /** 07 * The rule interface defines objects which do some action when a generation is 08 * calculated for the universe. The rule object takes in information in the form 09 * of a CellCollection, and returns the change to be made in the form of a 10 * Change object which is applied to a neighbourhood. The state and universe 11 * objects take responsibility of distributing and placing changes into the 12 * change queue. 13 * 14 Devin Kwok 15 * 16 */ 17 public abstract interface Rule 18 { 19 /** 20 * Gets an integer representing the neighbourhood from which cells will be 21 * provided when getchange(cellcollection) is called. 22 * 23 integer value defining neighbours, as according to the universe 24 * implementation 25 */ 26 int getinputneighbourhood(); /** 29 * Gets the value of the change calculated by the rule object. 30 * 31 collection CellCollection containing the input cells 32 change to be fed to the change queue 33 */ 34 Change getchange( CellCollection collection ); 35 } Devin Kwok: Dossier 2008 C: The Program: Page 132 of 185

134 C.I.xviii: Package: com.gmai.kwok.devin.universe.rule.dependent Abstract Class: DependentRule 01 package com.gmail.kwok.devin.universe.rule.dependent; import com.gmail.kwok.devin.universe.change.change; 04 import com.gmail.kwok.devin.universe.rule.rule; /** 07 * A rule which is dependent on some change to operate. It is called whenever 08 * its associated state changes value. 09 * 10 Devin Kwok 11 * 12 */ 13 public abstract class DependentRule implements Rule 14 { 15 /** 16 * Gets an integer representing the neighbourhood to which changes will be 17 * applied. 18 * 19 integer value defining neighbours, as according to the universe 20 * implementation 21 */ 22 public abstract int getoutputneighbourhood(); /** 25 * Sets the change on which this rule is to operate. 26 * 27 distributedchange change whose value may be used in calculations. 28 */ 29 public void setdistributedchange( Change distributedchange ) 30 { 31 this.change = distributedchange; 32 } /** 35 * Returns the change on which this rule is to operate. 36 * 37 distributedchange change whose value may be used in calculations. 38 */ 39 public Change getdistributedchange() 40 { 41 return change; 42 } /** 45 * Change whose value may be used in calculations. 46 */ 47 private Change change; 48 } Devin Kwok: Dossier 2008 C: The Program: Page 133 of 185

135 Class: DependentRuleList 01 package com.gmail.kwok.devin.universe.rule.dependent; import com.gmail.kwok.devin.util.linkedlist; /** 06 * A linked list of dependent rules that can be traversed forwards from the 07 * first rule only. 08 * 09 Devin Kwok 10 * 11 */ 12 public class DependentRuleList 13 { 14 /** 15 * Constructs a new list. 16 */ 17 public DependentRuleList() 18 { 19 list = new LinkedList(); 20 } /** 23 * Constructs a new list from a given array of dependent rules. 24 * 25 rules array of dependent rules. 26 */ 27 public DependentRuleList( DependentRule[] deprules ) 28 { 29 list = new LinkedList( deprules ); 30 } /** 33 * Returns an iterator for the list. 34 * 35 dependent rule iterator. 36 */ 37 public DependentRuleIterator ruleiterator() 38 { 39 return new DependentRuleIterator( list ); 40 } /** 43 * A linked list containing the actual objects in the dependent rule list. 44 */ 45 private LinkedList list; 46 } Devin Kwok: Dossier 2008 C: The Program: Page 134 of 185

136 Class: DependentRuleIterator 01 package com.gmail.kwok.devin.universe.rule.dependent; import com.gmail.kwok.devin.util.linkedlist; 04 import com.gmail.kwok.devin.util.listiterator; /** 07 * Iterates through a list of dependent rules. 08 * 09 Devin Kwok 10 * 11 */ 12 public class DependentRuleIterator 13 { 14 /** 15 * Creates a new dependent rule iterator from a given list. 16 * 17 list linked list containing the dependent rules. 18 */ 19 public DependentRuleIterator( LinkedList list ) 20 { 21 iterator = list.listiterator(); 22 } /** 25 * Adds a rule to the list at the iterator's current position. 26 * 27 deprule dependent rule to be added. 28 */ 29 public void add( DependentRule deprule ) 30 { 31 iterator.add( deprule ); 32 } /** 35 * Returns true if the list has further dependent rules. 36 * 37 true if the list iterator contains further elements. 38 */ 39 public boolean hasnext() 40 { 41 return iterator.hasnext(); 42 } /** 45 * Returns the next dependent rule after the iterator's current position. 46 * 47 dependent rule which was traversed by iterator. 48 */ 49 public DependentRule nextrule() 50 { 51 return (DependentRule) iterator.next(); 52 } /** 55 * Removes the dependent rule at the iterator's current position. 56 * 57 dependent rule which was removed. 58 */ 59 public DependentRule remove() 60 { Devin Kwok: Dossier 2008 C: The Program: Page 135 of 185

137 61 return (DependentRule) iterator.remove(); 62 } /** 65 * List iterator of linked list. 66 */ 67 private ListIterator iterator; 68 } Devin Kwok: Dossier 2008 C: The Program: Page 136 of 185

138 C.I.xix: Package: com.gmai.kwok.devin.universe.rule.independent Interface: IndependentRule 01 package com.gmail.kwok.devin.universe.rule.independent; import com.gmail.kwok.devin.universe.rule.rule; /** 06 * A rule which is utilized only by the universe object to calculate the next 07 * generation. It takes information from each cell of the current generation and 08 * changes apply to the next generation. The rules are stored in a list fashion 09 * in the universe, and according to the order in the list, each rule is called 10 * for every cell in the universe. The output neighbourhood is always a single 11 * cell. Currently this interface only serves to clarify the difference in name 12 * between dependent and independent rules. 13 * 14 Devin Kwok 15 * 16 */ 17 public interface IndependentRule extends Rule 18 { } Devin Kwok: Dossier 2008 C: The Program: Page 137 of 185

139 Class: IndependentRuleList 01 package com.gmail.kwok.devin.universe.rule.independent; import com.gmail.kwok.devin.util.linkedlist; /** 06 * A linked list of independent rules that can be traversed forwards from the 07 * first rule only. 08 * 09 Devin Kwok 10 * 11 */ 12 public class IndependentRuleList 13 { 14 /** 15 * Constructs a new list. 16 */ 17 public IndependentRuleList() 18 { 19 list = new LinkedList(); 20 } /** 23 * Constructs a new list from a given array of independent rules. 24 * 25 rules array of independent rules. 26 */ 27 public IndependentRuleList( IndependentRule[] deprules ) 28 { 29 list = new LinkedList( deprules ); 30 } /** 33 * Returns an iterator for the list. 34 * 35 independent rule iterator. 36 */ 37 public IndependentRuleIterator ruleiterator() 38 { 39 return new IndependentRuleIterator( list ); 40 } /** 43 * A linked list containing the actual objects in the independent rule list. 44 */ 45 private LinkedList list; 46 } Devin Kwok: Dossier 2008 C: The Program: Page 138 of 185

140 Class: IndependentRuleIterator 01 package com.gmail.kwok.devin.universe.rule.independent; import com.gmail.kwok.devin.util.linkedlist; 04 import com.gmail.kwok.devin.util.listiterator; /** 07 * Iterates through a list of independent rules. 08 * 09 Devin Kwok 10 * 11 */ 12 public class IndependentRuleIterator 13 { 14 /** 15 * Creates a new independent rule iterator from a given list. 16 * 17 list linked list containing the independent rules. 18 */ 19 public IndependentRuleIterator( LinkedList list ) 20 { 21 iterator = list.listiterator(); 22 } /** 25 * Adds a rule to the list at the iterator's current position. 26 * 27 deprule independent rule to be added. 28 */ 29 public void add( IndependentRule deprule ) 30 { 31 iterator.add( deprule ); 32 } /** 35 * Returns true if the list has further independent rules. 36 * 37 true if the list iterator contains further elements. 38 */ 39 public boolean hasnext() 40 { 41 return iterator.hasnext(); 42 } /** 45 * Returns the next independent rule after the iterator's current position. 46 * 47 independent rule which was traversed by iterator. 48 */ 49 public IndependentRule nextrule() 50 { 51 return (IndependentRule) iterator.next(); 52 } /** 55 * Removes the independent rule at the iterator's current position. 56 * 57 independent rule which was removed. 58 */ 59 public IndependentRule remove() 60 { Devin Kwok: Dossier 2008 C: The Program: Page 139 of 185

141 61 return (IndependentRule) iterator.remove(); 62 } /** 65 * List iterator of linked list. 66 */ 67 private ListIterator iterator; 68 } Devin Kwok: Dossier 2008 C: The Program: Page 140 of 185

142 C.I.xx: Package: com.gmai.kwok.devin.universe.state Class: StateDefinition 001 package com.gmail.kwok.devin.universe.state; import com.gmail.kwok.devin.universe.universe; 004 import com.gmail.kwok.devin.universe.rule.dependent.dependentruleiterator; 005 import com.gmail.kwok.devin.universe.rule.dependent.dependentrulelist; /** 008 * A state definition object contains the information necessary to define a 009 * state within the universe. It contains information about the type of data 010 * contained within the state, the state's default value, the dependent rules 011 * which depend on the state for change, and whether the state's values may be 012 * directly modified by the use of the set method. 013 * 014 Devin Kwok 015 * 016 */ 017 public abstract class StateDefinition 018 { 019 /** 020 * Constructs a state definition with a given key, default value, and 021 * dependent rule list. The state by default holds double values with no 022 * maximum and minimum bounds. 023 * 024 statekey integer key of the state. 025 list list of dependent rules. 026 ismodifiable if true, the state can be modified by the set method. 027 * If false, the state will not change as a result of calling the set 028 * method. 029 */ 030 public StateDefinition( int statekey, DependentRuleList list, 031 boolean ismodifiable ) 032 { 033 this.statekey = statekey; 034 this.list = list; 035 this.ismodifiable = ismodifiable; 036 } /** 039 * Returns the state's key. 040 * 041 integer key referring to the state. 042 */ 043 public int getstatekey() 044 { 045 return statekey; 046 } /** 049 * Sets the state's key. 050 * 051 state key must be greater than 0. Throws IllegalArgumentException 052 * otherwise. 053 statekey integer key referring to the state. 054 */ 055 public void setstatekey( int statekey ) 056 { 057 if( statekey < 0 ) Devin Kwok: Dossier 2008 C: The Program: Page 141 of 185

143 058 throw new IllegalArgumentException( "State key less than 0." ); 059 this.statekey = statekey; 060 } /** 063 * Returns whether the state is modifiable by the set method. 064 * 065 true if the state is modifiable by the set method. 066 */ 067 public boolean ismodifiable() 068 { 069 return ismodifiable; 070 } /** 073 * Sets whether the state is modifiable by the set method. 074 * 075 ismodifiable if true, the state may be modified by the set method. 076 */ 077 public void setmodifiable( boolean ismodifiable ) 078 { 079 this.ismodifiable = ismodifiable; 080 } /** 083 * Returns an iterator for the dependent rules of the state. 084 * 085 dependent rule iterator. 086 */ 087 public DependentRuleIterator dependentruleiterator() 088 { 089 return list.ruleiterator(); 090 } /** 093 * Constructs the appropriate state object which the state definition 094 * defines for the given universe. 095 * 096 universe universe to construct state for. 097 state object which matches the appropriate state definition. 098 */ 099 public abstract State constructstate( Universe universe ); /** 102 * Returns the default value of the state. 103 * 104 default value of state. 105 */ 106 public abstract double getdefaultvalue(); /** 109 * Sets the default value of the state. 110 * 111 defaultvalue default value of state. 112 */ 113 public abstract void setdefaultvalue( double defaultvalue ); /** 116 * Returns the minimum value for the state, as a double value. 117 * 118 minimum value. 119 */ 120 public abstract double getmin(); Devin Kwok: Dossier 2008 C: The Program: Page 142 of 185

144 /** 123 * Sets the minimum value for the state, as a double value. 124 * 125 min minimum value. 126 */ 127 public abstract void setmin( double min ); /** 130 * Returns the maximum value for the state, as a double value. 131 * 132 maximum value. 133 */ 134 public abstract double getmax(); /** 137 * Sets the maximum value for the state, as a double value. 138 * 139 max maximum value. 140 */ 141 public abstract void setmax( double max ); /** 144 * Returns true if the given value is within the minimum and maximum bounds 145 * set by the state definition. 146 * 147 value value to be tested. 148 true if minimum <= value <= maximum. 149 */ 150 public abstract boolean withinbounds( double value ); /** 153 * Limits the value so that it is guaranteed to be within bounds. If the 154 * value is not within bounds the nearest of the minimum and maximum values 155 * is returned. 156 * 157 value value to be limited. 158 if the value is within bounds, the value itself. Otherwise either 159 * the minimum or maxiumum value. 160 */ 161 public abstract double limitvalue( double value ); /** 164 * Returns an integer which represents the type of state definition the 165 * class is. 166 * 167 integer which corresponds to the definition of static final 168 * fields in the state definition class. 169 */ 170 public abstract String gettype(); /** 173 * String which boolean states and state definitions return. 174 */ 175 public static final String BOOLEAN = "Boolean"; /** 178 * String which integer states and state definitions return. 179 */ 180 public static final String INTEGER = "Integer"; /** 183 * String which double states and state definitions return. Devin Kwok: Dossier 2008 C: The Program: Page 143 of 185

145 184 */ 185 public static final String DOUBLE = "Double"; /** 188 * Integer key of state. Used by cell and universe objects to locate the 189 * state in the universe's array of states. Must not be less than */ 191 private int statekey; /** 194 * If true, the state may be directly modified by the set method. Otherwise, 195 * the state may only be indirectly modified by the changevalue method, or 196 * in other words by the results of dependent rules. 197 */ 198 private boolean ismodifiable; /** 201 * List of rules dependent on a change to this state to be activated. 202 */ 203 private DependentRuleList list; 204 } Devin Kwok: Dossier 2008 C: The Program: Page 144 of 185

146 Class: State 001 package com.gmail.kwok.devin.universe.state; import com.gmail.kwok.devin.universe.universe; 004 import com.gmail.kwok.devin.universe.cell.cellcollection; 005 import com.gmail.kwok.devin.universe.change.change; 006 import com.gmail.kwok.devin.universe.change.stackoverflowexception; 007 import com.gmail.kwok.devin.universe.rule.dependent.dependentrule; 008 import com.gmail.kwok.devin.universe.rule.dependent.dependentruleiterator; /** 011 * A state object contains all the information of a universe. The state is 012 * defined by a StateDefinition object, which determines what the state contains 013 * and can do. The state object is where actual values are accessed and 014 * modified. 015 * 016 Devin Kwok 017 * 018 */ 019 public abstract class State 020 { /** 023 * Constructs a new state with a given universe and definition. 024 * 025 definition state definition which defines various aspects of the 026 * state. 027 universe universe where the state object retrieves information and 028 * applies changes to. 029 */ 030 public State( StateDefinition definition, Universe universe ) 031 { 032 this.definition = definition; 033 this.universe = universe; 034 } /** 037 * Clears all values in the state to the state's default value. 038 */ 039 public abstract void clearall(); /** 042 * Returns the state's value at the given cell address. If the cell address 043 * contained in the change is -1, the state's default value must be 044 * returned. 045 * 046 celladdress integer address of cell 047 value at the given cell address 048 */ 049 public abstract double getvalue( int celladdress ); /** 052 * Sets the state's value at the given cell address. Will not set the 053 * state's value if the state definition's field ismodifiable is false. 054 * Throws an IllegalArgumentException if the new value is out of bounds. 055 * 056 statedefinition.min <= newvalue <= statedefinition.max 057 celladdress integer address of cell 058 newvalue new value to set at the given address 059 */ 060 public void setvalue( int celladdress, double newvalue ) Devin Kwok: Dossier 2008 C: The Program: Page 145 of 185

147 061 { 062 Change change = new Change( this.definition.getstatekey(), 063 celladdress, newvalue - getvalue( celladdress ) ); 064 applychange( change ); 065 } /** 068 * Refreshes the values contained in the state to the new values that were 069 * calculated in the generation. Called at the end of the universe's 070 * nextgeneration method. 071 */ 072 public abstract void refresh(); /** 075 * Returns the state's state definition. 076 * 077 state definition of state. 078 */ 079 public StateDefinition getdefinition() 080 { 081 return definition; 082 } /** 085 * Adds a change to the universe's change stack. 086 * 087 change change to be added. 088 StackOverflowException 089 */ 090 public void addchange( Change change ) throws StackOverflowException 091 { 092 universe.addchange( change ); 093 } /** 096 * Applies the change by summing the value at the given cell address with 097 * the value supplied in the change object. 098 * 099 change change to be applied. 100 */ 101 public abstract void applychange( Change change ); /** 104 * Distributes the change to the state definition's dependent rules. 105 * 106 change Change to be distributed 107 StackOverflowException 108 */ 109 public Change distributechange( Change change ) 110 throws StackOverflowException 111 { 112 DependentRuleIterator iterator = definition.dependentruleiterator(); while( iterator.hasnext() ) 115 { 116 DependentRule rule = iterator.nextrule(); 117 rule.setdistributedchange( change ); CellCollection collection = universe.getneighbours( change 120.getCellAddress(), rule.getinputneighbourhood() ); 121 Change newchange = rule.getchange( collection ); if( newchange!= null ) Devin Kwok: Dossier 2008 C: The Program: Page 146 of 185

148 124 { 125 CellCollection newcollection = universe.getneighbours( change 126.getCellAddress(), rule.getoutputneighbourhood() ); 127 newcollection.addchangeforall( newchange ); 128 } 129 } 130 return change; 131 } /** 134 * Limits a change so that it will not fall beyond the state definition's 135 * limits. This is necessary to prevent user entered changes from causing 136 * issues in the simulation. 137 * 138 ch change to be limited. 139 new change with limited value. 140 */ 141 public Change limitchange( Change ch ) 142 { 143 Change change = new Change( ch.getstatekey(), ch.getcelladdress(), ch 144.getChangeValue() ); 145 double limitedvalue = this.definition.limitvalue( ch.getchangevalue() getvalue( ch.getcelladdress() ) ); 147 change 148.setChangeValue( limitedvalue getvalue( ch.getcelladdress() ) ); 150 return change; 151 } /** 154 * Returns a string which represents the type of state the class is. 155 * 156 String which corresponds to the definition of static final fields 157 * in the state definition class. 158 */ 159 public abstract String gettype(); /** 162 * Returns the number of values in the state. 163 * 164 size which is equivalent to universe size. 165 */ 166 public abstract int getsize(); /** 169 * Returns a string representation of the state at the given cell address. 170 * 171 celladdress cell address. 172 string representing the value at the given address. 173 */ 174 public abstract String tostring( int celladdress ); /** 177 * The state's definition. Contains the attributes of the state. 178 */ 179 private StateDefinition definition; /** 182 * Universe to which this state belongs. 183 */ 184 private Universe universe; 185 } Devin Kwok: Dossier 2008 C: The Program: Page 147 of 185

149 Class: UnmodifiableStateException 01 package com.gmail.kwok.devin.universe.state; /** 04 * Thrown if something attempts to modify an unmodifiable state. 05 * 06 Devin Kwok 07 * 08 */ 09 public class UnmodifiableStateException extends RuntimeException 10 { 11 /** 12 * 13 */ 14 private static final long serialversionuid = 1L; /** 17 * Creates a new UnmodifiableStateException. 18 */ 19 public UnmodifiableStateException() 20 { 21 } /** 24 * Creates a new UnmodifiableStateException. 25 * 26 message message of exception. 27 */ 28 public UnmodifiableStateException( String message ) 29 { 30 super( message ); 31 } 32 } Devin Kwok: Dossier 2008 C: The Program: Page 148 of 185

150 C.I.xxi: Package: com.gmai.kwok.devin. universe.state.bool Class: BooleanState 001 package com.gmail.kwok.devin.universe.state.bool; import java.util.arrays; import com.gmail.kwok.devin.universe.universe; 006 import com.gmail.kwok.devin.universe.change.change; 007 import com.gmail.kwok.devin.universe.change.stackoverflowexception; 008 import com.gmail.kwok.devin.universe.state.state; 009 import com.gmail.kwok.devin.universe.state.statedefinition; 010 import com.gmail.kwok.devin.universe.state.unmodifiablestateexception; /** 013 * A state containing boolean values. 014 * 015 Devin Kwok 016 * 017 */ 018 public class BooleanState extends State 019 { 020 /** 021 * Constructs a new boolean state. 022 * 023 definition the state's state definition. 024 universe universe state is associated with. 025 */ 026 public BooleanState( StateDefinition definition, Universe universe ) 027 { 028 super( definition, universe ); 029 values = new boolean[ universe.getsize() ]; 030 newvalues = new boolean[ universe.getsize() ]; 031 clearall(); 032 } /** 035 * Sets the state to contain the specified values. Also updates dependent 036 * rules. 037 * 038 values the values to initialize the state with. 039 */ 040 public void initialize( boolean[] values ) throws StackOverflowException 041 { 042 if( values.length!= this.values.length ) 043 throw new IllegalArgumentException( 044 "Array length does not match universe size." ); if(!this.getdefinition().ismodifiable() ) 047 throw new UnmodifiableStateException( 048 "Cannot set values to unmodifiable state" ); for( int i = 0; i < values.length; i++ ) 051 { 052 int value = 0; 053 if( values[ i ] ) 054 value = 1; 055 super.addchange( new Change( this.getdefinition().getstatekey(), 056 i, value - this.getdefinition().getdefaultvalue() ) ); 057 } Devin Kwok: Dossier 2008 C: The Program: Page 149 of 185

151 058 } /** 061 * Clears all values in the state to the state's default value. 062 */ 064 public void clearall() 065 { 066 boolean fillvalue; 067 if( super.getdefinition().getdefaultvalue() > 0 ) 068 fillvalue = true; 069 else 070 fillvalue = false; 071 Arrays.fill( values, fillvalue ); 072 Arrays.fill( newvalues, fillvalue ); 073 } /** 076 * Returns the value at the specified cell address. 077 */ 079 public double getvalue( int celladdress ) 080 { 081 if( celladdress == -1 ) 082 return super.getdefinition().getdefaultvalue(); 083 if( values[ celladdress ] ) 084 return 1; 085 return 0; 086 } /** 089 * Applies a change by summing its value with the value contained in the 090 * state. The result is limited so that it is within the boundaries of the 091 * state. If the result is greater than 0 the result is recorded as true, 092 * and otherwise as false. The change is applied to the array which records 093 * the next generation, and is cumulative (if multiple changes are applied 094 * to a value, they are summed together. 095 */ 097 public void applychange( Change change ) 098 { 099 double newvalue = change.getchangevalue(); 100 if( newvalues[ change.getcelladdress() ] ) 101 newvalue++; if( super.getdefinition().limitvalue( newvalue ) > 0 ) 104 newvalues[ change.getcelladdress() ] = true; 105 else 106 newvalues[ change.getcelladdress() ] = false; 107 } /** 110 * Copies the next generation's array to the current generation. 111 */ 113 public void refresh() 114 { 115 values = Arrays.copyOf( newvalues, newvalues.length ); 116 } /** 119 * Returns the value StateDefinition.BOOLEAN; 120 */ Devin Kwok: Dossier 2008 C: The Program: Page 150 of 185

152 122 public String gettype() 123 { 124 return StateDefinition.BOOLEAN; 125 } /** 128 * Returns the boolean value at the specified cell address. 129 * 130 celladdress address of cell. 131 boolean value. 132 */ 133 public boolean getbooleanvalue( int celladdress ) 134 { 135 if( celladdress == -1 ) 136 { 137 BooleanDefinition definition = (BooleanDefinition) super 138.getDefinition(); 139 return definition.getbooleandefaultvalue(); 140 } 141 return values[ celladdress ]; 142 } /** 145 * Returns a string representation of this state. 146 */ 147 public String tostring() 148 { 149 String s = "State " + super.getdefinition().getstatekey() ": Boolean {"; 151 for( boolean i : values ) 152 { 153 s = s + getboolean( i ) + ", "; 154 } 155 return s.substring( 0, s.length() - 2 ) + "}"; 156 } /** 159 * Returns a string representation of a boolean value. 160 * 161 value boolean value. 162 string representation. "T" if true, and "F" if false. 163 */ 164 private String getboolean( boolean value ) 165 { 166 if( value ) 167 return "T"; 168 return "F"; 169 } /** 172 * Returns the number of values in the state. 173 */ 175 public int getsize() 176 { 177 return values.length; 178 } /** 181 * Returns a string representation of the state at the given cell address. 182 */ Devin Kwok: Dossier 2008 C: The Program: Page 151 of 185

153 184 public String tostring( int celladdress ) 185 { 186 // TODO Auto-generated method stub 187 return "" + getboolean( getbooleanvalue( celladdress ) ); 188 } /** 191 * Values contained in the state. The values are arranged by cell address. 192 * The calling of the set method applies changes to this array. 193 */ 194 private boolean[] values; /** 197 * Array of values which are of the next generation. All changes are applied 198 * to this array. 199 */ 200 private boolean[] newvalues; 201 } Devin Kwok: Dossier 2008 C: The Program: Page 152 of 185

154 Class: BooleanDefinition 001 package com.gmail.kwok.devin.universe.state.bool; import com.gmail.kwok.devin.universe.universe; 004 import com.gmail.kwok.devin.universe.rule.dependent.dependentrulelist; 005 import com.gmail.kwok.devin.universe.state.state; 006 import com.gmail.kwok.devin.universe.state.statedefinition; /** 009 * A state definition for a state containing boolean values. 010 * 011 Devin Kwok 012 * 013 */ 014 public class BooleanDefinition extends StateDefinition 015 { 016 /** 017 * Constructs a new boolean state definition. 018 */ 019 public BooleanDefinition( int statekey, DependentRuleList list, 020 boolean ismodifiable ) 021 { 022 super( statekey, list, ismodifiable ); 023 this.defaultvalue = false; 024 } /** 027 * Constructs a new boolean state definition. 028 * 029 defaultvalue default value of the state. 030 */ 031 public BooleanDefinition( int statekey, DependentRuleList list, 032 boolean ismodifiable, double defaultvalue ) 033 { 034 super( statekey, list, ismodifiable ); 035 setdefaultvalue( defaultvalue ); 036 } /** 039 * Constructs a boolean state. 040 */ 042 public State constructstate( Universe universe ) 043 { 044 return new BooleanState( this, universe ); 045 } /** 048 * Returns the state's default value. 049 */ 051 public double getdefaultvalue() 052 { 053 if( defaultvalue ) 054 return 1; 055 return 0; 056 } /** 059 * Sets the state's default value. If the supplied double parameter is 060 * greater than 0, the default value is true. Otherwise, it is false. Devin Kwok: Dossier 2008 C: The Program: Page 153 of 185

155 061 */ 063 public void setdefaultvalue( double defaultvalue ) 064 { 065 if( defaultvalue > 0 ) 066 this.defaultvalue = true; 067 else 068 this.defaultvalue = false; 069 } /** 072 * Returns the maximum value, which is always 1 for a boolean value. 073 */ 075 public double getmax() 076 { 077 return 1; 078 } /** 081 * Returns the minimum value, which is always 0 for a boolean value. 082 */ 084 public double getmin() 085 { 086 return 0; 087 } /** 090 * The boolean definition has fixed maximum and minimum values. Thus, when 091 * setmax is called an UnsupportedOperationException is thrown. 092 */ 094 public void setmax( double max ) 095 { 096 throw new UnsupportedOperationException(); 097 } /** 100 * The boolean definition has fixed maximum and minimum values. Thus, when 101 * setmin is called an UnsupportedOperationException is thrown. 102 */ 104 public void setmin( double min ) 105 { 106 throw new UnsupportedOperationException(); 107 } /** 110 * Returns true if 0 <= value <= */ 113 public boolean withinbounds( double value ) 114 { 115 if( value < 0 value > 1 ) 116 return false; 117 return true; 118 } /** 121 * If the parameter value is greater than 0, returns true. Otherwise returns 122 * false. 123 */ Devin Kwok: Dossier 2008 C: The Program: Page 154 of 185

156 125 public double limitvalue( double value ) 126 { 127 if( value > 0 ) 128 return 1; 129 else 130 return 0; 131 } /** 134 * Returns the value StateDefinition.BOOLEAN; 135 */ 137 public String gettype() 138 { 139 return StateDefinition.BOOLEAN; 140 } /** 143 * Returns the default value of the state as a boolean value. 144 * 145 default value. 146 */ 147 public boolean getbooleandefaultvalue() 148 { 149 return defaultvalue; 150 } /** 153 * Default value of state. 154 */ 155 private boolean defaultvalue; 156 } Devin Kwok: Dossier 2008 C: The Program: Page 155 of 185

157 C.I.xxii: Package: com.gmai.kwok.devin. universe.state.integer Class: IntegerDefinition 001 package com.gmail.kwok.devin.universe.state.integer; import com.gmail.kwok.devin.universe.universe; 004 import com.gmail.kwok.devin.universe.rule.dependent.dependentrulelist; 005 import com.gmail.kwok.devin.universe.state.state; 006 import com.gmail.kwok.devin.universe.state.statedefinition; /** 009 * A state definition for a state containing integer values. 010 * 011 Devin Kwok 012 * 013 */ 014 public class IntegerDefinition extends StateDefinition 015 { 016 /** 017 * Constructs a new integer state definition. 018 */ 019 public IntegerDefinition( int statekey, DependentRuleList list, 020 boolean ismodifiable ) 021 { 022 super( statekey, list, ismodifiable ); 023 this.min = Integer.MIN_VALUE; 024 this.max = Integer.MAX_VALUE; 025 this.defaultvalue = 0; 026 } /** 029 * Constructs a new integer state definition. 030 * 031 defaultvalue default value of the state. 032 */ 033 public IntegerDefinition( int statekey, DependentRuleList list, 034 boolean ismodifiable, double defaultvalue ) 035 { 036 super( statekey, list, ismodifiable ); 037 this.min = Integer.MIN_VALUE; 038 this.max = Integer.MAX_VALUE; 039 setdefaultvalue( defaultvalue ); 040 } /** 043 * Constructs a new integer definition. 044 * 045 statekey integer key of state. 046 list dependent rule list. 047 ismodifiable whether state is modifiable. 048 defaultvalue default value of state. 049 min minimum value of state. 050 max maximum value of state. 051 */ 052 public IntegerDefinition( int statekey, DependentRuleList list, 053 boolean ismodifiable, double defaultvalue, double min, double max ) 054 { 055 super( statekey, list, ismodifiable ); 056 this.min = (int) min; 057 this.setmax( max ); Devin Kwok: Dossier 2008 C: The Program: Page 156 of 185

158 058 setdefaultvalue( defaultvalue ); 059 } /** 062 * Constructs an integer state. 063 */ 065 public State constructstate( Universe universe ) 066 { 067 return new IntegerState( this, universe ); 068 } /** 071 * Returns the state's default value. 072 */ 074 public double getdefaultvalue() 075 { 076 return defaultvalue; 077 } /** 080 * Sets the state's default value. Values exceeding the definition limits 081 * throw an IllegalArgumentException. 082 */ 084 public void setdefaultvalue( double defaultvalue ) 085 { 086 if(!withinbounds( (int) defaultvalue ) ) 087 throw new IllegalArgumentException( 088 "Default value is out of bounds." ); 089 this.defaultvalue = (int) defaultvalue; 090 } /** 093 * Returns the minimum value. 094 */ 096 public double getmin() 097 { 098 return min; 099 } /** 102 * Sets the minimum value. 103 */ 105 public void setmin( double min ) 106 { 107 if( (int) min > this.max ) 108 throw new IllegalArgumentException( "Minimum is out of bounds." ); 109 this.min = (int) min; 110 } /** 113 * Returns the maximum value. 114 */ 116 public double getmax() 117 { 118 return max; 119 } 120 Devin Kwok: Dossier 2008 C: The Program: Page 157 of 185

159 121 /** 122 * Sets the maximum value. 123 */ 125 public void setmax( double max ) 126 { 127 if( ( int ) max < this.min ) 128 throw new IllegalArgumentException( "Maximum is out of bounds." ); 129 this.max = (int) max; 130 } /** 133 * Returns true if min <= value <= max. 134 */ 136 public boolean withinbounds( double value ) 137 { 138 if( value < min value > max ) 139 return false; 140 return true; 141 } /** 144 * If the parameter exceeds the definition limits, the limiting value is 145 * returned. 146 */ 148 public double limitvalue( double value ) 149 { 150 if( value > max ) 151 return max; 152 if( value < min ) 153 return min; 154 return (int) value; 155 } /** 158 * Returns the value StateDefinition.INTEGER; 159 */ 161 public String gettype() 162 { 163 return StateDefinition.INTEGER; 164 } /** 167 * Returns the integer default value. 168 * 169 default value as an integer. 170 */ 171 public int getintegerdefaultvalue() 172 { 173 return defaultvalue; 174 } /** 177 * Minimum value. 178 */ 179 private int min; /** 182 * Maximum value. 183 */ Devin Kwok: Dossier 2008 C: The Program: Page 158 of 185

160 184 private int max; /** 187 * Default value of state. 188 */ 189 private int defaultvalue; 190 } Devin Kwok: Dossier 2008 C: The Program: Page 159 of 185

161 Class: IntegerState 001 package com.gmail.kwok.devin.universe.state.integer; import java.util.arrays; import com.gmail.kwok.devin.universe.universe; 006 import com.gmail.kwok.devin.universe.change.change; 007 import com.gmail.kwok.devin.universe.change.stackoverflowexception; 008 import com.gmail.kwok.devin.universe.state.state; 009 import com.gmail.kwok.devin.universe.state.statedefinition; 010 import com.gmail.kwok.devin.universe.state.unmodifiablestateexception; /** 013 * A state containing integer values. 014 * 015 Devin Kwok 016 * 017 */ 018 public class IntegerState extends State 019 { /** 022 * Constructs a new integer state. 023 * 024 definition the state's state definition. 025 universe universe state is associated with. 026 */ 027 public IntegerState( StateDefinition definition, Universe universe ) 028 { 029 super( definition, universe ); 030 values = new int[ universe.getsize() ]; 031 newvalues = new int[ universe.getsize() ]; 032 clearall(); 033 } /** 036 * Sets the state to contain the specified values. Also updates dependent 037 * rules. 038 * 039 values the values to initialize the state with. 040 */ 041 public void initialize( int[] values ) throws StackOverflowException 042 { 043 if( values.length!= this.values.length ) 044 throw new IllegalArgumentException( 045 "Array length does not match universe size." ); if(!this.getdefinition().ismodifiable() ) 048 throw new UnmodifiableStateException( 049 "Cannot set values to unmodifiable state" ); for( int i = 0; i < values.length; i++ ) 052 { 053 super 054.addChange( new Change( this.getdefinition() 055.getStateKey(), i, values[ i ] this.getdefinition().getdefaultvalue() ) ); 057 } 058 } /** Devin Kwok: Dossier 2008 C: The Program: Page 160 of 185

162 061 * Clears all values in the state to the state's default value. 062 */ 064 public void clearall() 065 { 066 Arrays.fill( values, (int) super.getdefinition().getdefaultvalue() ); 067 Arrays 068.fill( newvalues, (int) super.getdefinition() 069.getDefaultValue() ); 070 } /** 073 * Returns the value at the specified cell address. 074 */ 076 public double getvalue( int celladdress ) 077 { 078 if( celladdress == -1 ) 079 return super.getdefinition().getdefaultvalue(); 080 return values[ celladdress ]; 081 } /** 084 * Applies a change by summing its value with the value contained in the 085 * state. The result is limited so that it is within the boundaries of the 086 * state. The change is applied to the array which records the next 087 * generation, and is cumulative (if multiple changes are applied to a 088 * value, they are summed together. 089 */ 091 public void applychange( Change change ) 092 { 093 double newvalue = newvalues[ change.getcelladdress() ] change.getchangevalue(); newvalues[ change.getcelladdress() ] = (int) super.getdefinition() 097.limitValue( newvalue ); 098 } /** 101 * Returns the value StateDefinition.INTEGER; 102 */ 104 public String gettype() 105 { 106 return StateDefinition.INTEGER; 107 } /** 110 * Copies the next generation's array to the current generation. 111 */ 113 public void refresh() 114 { 115 values = Arrays.copyOf( newvalues, newvalues.length ); 116 } /** 119 * Returns the integer value at the specified cell address. 120 * 121 celladdress address of cell. 122 integer value. 123 */ Devin Kwok: Dossier 2008 C: The Program: Page 161 of 185

163 124 public int getintegervalue( int celladdress ) 125 { 126 if( celladdress == -1 ) 127 return (int) super.getdefinition().getdefaultvalue(); return values[ celladdress ]; 130 } /** 133 * Returns a string representation of the state. 134 */ 135 public String tostring() 136 { 137 String s = "State " + super.getdefinition().getstatekey() ": Integer {"; 139 for( int i : values ) 140 { 141 s = s + i + ", "; 142 } 143 return s.substring( 0, s.length() - 2 ) + "}"; 144 } /** 147 * Returns the number of values in the state. 148 */ 150 public int getsize() 151 { 152 return values.length; 153 } /** 156 * Returns a string representation of the state at the given cell address. 157 */ 158 public String tostring( int celladdress ) 159 { 160 return "" + getintegervalue( celladdress ); 161 } /** 164 * Values contained in the state. The values are arranged by cell address. 165 * The calling of the set method applies changes to this array. 166 */ 167 private int[] values; /** 170 * Array of values which are of the next generation. All changes are applied 171 * to this array. 172 */ 173 private int[] newvalues; 174 } Devin Kwok: Dossier 2008 C: The Program: Page 162 of 185

164 C.I.xxiii: Package: com.gmai.kwok.devin.universe.state.doub Class: DoubleDefinition 001 package com.gmail.kwok.devin.universe.state.doub; import com.gmail.kwok.devin.universe.universe; 004 import com.gmail.kwok.devin.universe.rule.dependent.dependentrulelist; 005 import com.gmail.kwok.devin.universe.state.state; 006 import com.gmail.kwok.devin.universe.state.statedefinition; /** 009 * A state definition for a state containing double values. 010 * 011 Devin Kwok 012 * 013 */ 014 public class DoubleDefinition extends StateDefinition 015 { 016 /** 017 * Constructs a new double state definition. 018 */ 019 public DoubleDefinition( int statekey, DependentRuleList list, 020 boolean ismodifiable ) 021 { 022 super( statekey, list, ismodifiable ); 023 this.min = Double.MIN_VALUE; 024 this.max = Double.MAX_VALUE; 025 this.defaultvalue = 0; 026 } /** 029 * Constructs a new double state definition. 030 * 031 defaultvalue default value of the state. 032 */ 033 public DoubleDefinition( int statekey, DependentRuleList list, 034 boolean ismodifiable, double defaultvalue ) 035 { 036 super( statekey, list, ismodifiable ); 037 this.min = Double.MIN_VALUE; 038 this.max = Double.MAX_VALUE; 039 setdefaultvalue( defaultvalue ); 040 } /** 043 * Constructs a new double definition. 044 * 045 statekey integer key of state. 046 list dependent rule list. 047 ismodifiable whether state is modifiable. 048 defaultvalue default value of state. 049 min minimum value of state. 050 max maximum value of state. 051 */ 052 public DoubleDefinition( int statekey, DependentRuleList list, 053 boolean ismodifiable, double defaultvalue, double min, double max ) 054 { 055 super( statekey, list, ismodifiable ); 056 this.min = min; 057 this.setmax( max ); Devin Kwok: Dossier 2008 C: The Program: Page 163 of 185

165 058 setdefaultvalue( defaultvalue ); 059 } /** 062 * Constructs a double state. 063 */ 065 public State constructstate( Universe universe ) 066 { 067 return new DoubleState( this, universe ); 068 } /** 071 * Returns the state's default value. 072 */ 074 public double getdefaultvalue() 075 { 076 return defaultvalue; 077 } /** 080 * Sets the state's default value. Values exceeding the definition limits 081 * throw an IllegalArgumentException. 082 */ 084 public void setdefaultvalue( double defaultvalue ) 085 { 086 if(!withinbounds( (int) defaultvalue ) ) 087 throw new IllegalArgumentException( 088 "Default value is out of bounds." ); 089 this.defaultvalue = (int) defaultvalue; 090 } /** 093 * Returns the minimum value. 094 */ 096 public double getmin() 097 { 098 return min; 099 } /** 102 * Sets the minimum value. 103 */ 105 public void setmin( double min ) 106 { 107 if( min > this.max ) 108 throw new IllegalArgumentException( "Minimum is out of bounds." ); 109 this.min = min; 110 } /** 113 * Returns the maximum value. 114 */ 116 public double getmax() 117 { 118 return max; 119 } 120 Devin Kwok: Dossier 2008 C: The Program: Page 164 of 185

166 121 /** 122 * Sets the maximum value. 123 */ 125 public void setmax( double max ) 126 { 127 if( max < this.min ) 128 throw new IllegalArgumentException( "Maximum is out of bounds." ); 129 this.max = max; 130 } /** 133 * Returns true if min <= value <= max. 134 */ 136 public boolean withinbounds( double value ) 137 { 138 if( value < min value > max ) 139 return false; 140 return true; 141 } /** 144 * If the parameter exceeds the definition limits, the limiting value is 145 * returned. 146 */ 148 public double limitvalue( double value ) 149 { 150 if( value > max ) 151 return max; 152 if( value < min ) 153 return min; 154 return value; 155 } /** 158 * Returns the value StateDefinition.DOUBLE; 159 */ 161 public String gettype() 162 { 163 return StateDefinition.DOUBLE; 164 } /** 167 * Minimum value. 168 */ 169 private double min; /** 172 * Maximum value. 173 */ 174 private double max; /** 177 * Default value of state. 178 */ 179 private double defaultvalue; 180 } Devin Kwok: Dossier 2008 C: The Program: Page 165 of 185

167 Class: DoubleState 001 package com.gmail.kwok.devin.universe.state.doub; import java.util.arrays; import com.gmail.kwok.devin.universe.universe; 006 import com.gmail.kwok.devin.universe.change.change; 007 import com.gmail.kwok.devin.universe.change.stackoverflowexception; 008 import com.gmail.kwok.devin.universe.state.state; 009 import com.gmail.kwok.devin.universe.state.statedefinition; 010 import com.gmail.kwok.devin.universe.state.unmodifiablestateexception; /** 013 * A state containing double values. 014 * 015 Devin Kwok 016 * 017 */ 018 public class DoubleState extends State 019 { /** 022 * Constructs a new double state. 023 * 024 definition the state's state definition. 025 universe universe state is associated with. 026 */ 027 public DoubleState( StateDefinition definition, Universe universe ) 028 { 029 super( definition, universe ); 030 values = new double[ universe.getsize() ]; 031 newvalues = new double[ universe.getsize() ]; 032 clearall(); 033 } /** 036 * Sets the state to contain the specified values. Also updates dependent 037 * rules. 038 * 039 values the values to initialize the state with. 040 */ 041 public void initialize( double[] values ) throws StackOverflowException 042 { 043 if( values.length!= this.values.length ) 044 throw new IllegalArgumentException( 045 "Array length does not match universe size." ); if(!this.getdefinition().ismodifiable() ) 048 throw new UnmodifiableStateException( 049 "Cannot set values to unmodifiable state" ); for( int i = 0; i < values.length; i++ ) 052 { 053 super 054.addChange( new Change( this.getdefinition() 055.getStateKey(), i, values[ i ] this.getdefinition().getdefaultvalue() ) ); 057 } 058 } /** Devin Kwok: Dossier 2008 C: The Program: Page 166 of 185

168 061 * Clears all values in the state to the state's default value. 062 */ 064 public void clearall() 065 { 066 Arrays.fill( values, super.getdefinition().getdefaultvalue() ); 067 Arrays.fill( newvalues, super.getdefinition().getdefaultvalue() ); 068 } /** 071 * Returns the value at the specified cell address. 072 */ 074 public double getvalue( int celladdress ) 075 { 076 if( celladdress == -1 ) 077 return super.getdefinition().getdefaultvalue(); 078 return values[ celladdress ]; 079 } /** 082 * Applies a change by summing its value with the value contained in the 083 * state. The result is limited so that it is within the boundaries of the 084 * state. The change is applied to the array which records the next 085 * generation, and is cumulative (if multiple changes are applied to a 086 * value, they are summed together. 087 */ 089 public void applychange( Change change ) 090 { 091 double newvalue = newvalues[ change.getcelladdress() ] change.getchangevalue(); newvalues[ change.getcelladdress() ] = super.getdefinition() 095.limitValue( newvalue ); 096 } /** 099 * Copies the next generation's array to the current generation. 100 */ 102 public void refresh() 103 { 104 values = Arrays.copyOf( newvalues, newvalues.length ); 105 } /** 108 * Returns the value StateDefinition.DOUBLE; 109 */ 111 public String gettype() 112 { 113 return StateDefinition.DOUBLE; 114 } /** 117 * Returns a string representation of this state. 118 */ 119 public String tostring() 120 { 121 String s = "State " + super.getdefinition().getstatekey() ": Double {"; 123 for( double i : values ) Devin Kwok: Dossier 2008 C: The Program: Page 167 of 185

169 124 { 125 s = s + i + ", "; 126 } 127 return s.substring( 0, s.length() - 2 ) + "}"; 128 } /** 131 * Returns the number of values in the state. 132 */ 134 public int getsize() 135 { 136 return values.length; 137 } /** 140 * Returns a string representation of the state at the given cell address. 141 */ 143 public String tostring( int celladdress ) 144 { 145 // TODO Auto-generated method stub 146 return "" + getvalue( celladdress ); 147 } /** 150 * Values contained in the state. The values are arranged by cell address. 151 * The calling of the set method applies changes to this array. 152 */ 153 private double[] values; /** 156 * Array of values which are of the next generation. All changes are applied 157 * to this array. 158 */ 159 private double[] newvalues; 160 } Devin Kwok: Dossier 2008 C: The Program: Page 168 of 185

170 C.I.xxiv: Package: com.gmai.kwok.devin.util Class: LinkedList 001 package com.gmail.kwok.devin.util; import java.util.nosuchelementexception; /** 006 * A linked list of objects that can be traversed forwards from the first one 007 * only. 008 * 009 Devin Kwok 010 * 011 */ 012 public class LinkedList 013 { 014 /** 015 * Constructs a new linked list with no elements. 016 */ 017 public LinkedList() 018 { 019 first = null; 020 size = 0; 021 } /** 024 * Constructs a new linked list from an array. The list retains the order 025 * that the objects held in the array. 026 * 027 objects array of objects to be placed in list. 028 */ 029 public LinkedList( Object[] objects ) 030 { 031 for( int i = objects.length - 1; i >= 0; i-- ) 032 { 033 addfirst( objects[ i ] ); 034 } 035 size = objects.length; 036 } /** 039 * Tests whether the list has at least one element. 040 * 041 true if the list contains an element. 042 */ 043 public boolean hasfirst() 044 { 045 if( first == null ) 046 return false; 047 return true; 048 } /** 051 * Adds an object to the beginning of the list. 052 * 053 object object to be added. 054 */ 055 public void addfirst( Object object ) 056 { 057 Node newnode = new Node(); Devin Kwok: Dossier 2008 C: The Program: Page 169 of 185

171 058 newnode.object = object; 059 newnode.next = first; 060 first = newnode; 061 if( size == 0 ) 062 last = newnode; 063 size++; 064 } /** 067 * Returns the first object in the list. 068 * 069 first object in list. 070 */ 071 public Object getfirst() 072 { 073 if( first == null ) 074 throw new NoSuchElementException(); return first.object; 077 } /** 080 * Removes the first object in the list. 081 * 082 first object in list. 083 */ 084 public Object removefirst() 085 { 086 if( first == null ) 087 throw new NoSuchElementException(); Object object = first.object; 090 first = first.next; 091 size--; 092 if( size == 0 ) 093 last = null; 094 return object; 095 } /** 098 * Adds an object to the end of the list. 099 * 100 object object to be added. 101 */ 102 public void addlast( Object object ) 103 { 104 if( first == null ) 105 { 106 addfirst( object ); 107 return; 108 } 109 Node newnode = new Node(); 110 newnode.object = object; 111 newnode.next = null; 112 last.next = newnode; 113 last = newnode; 114 size++; 115 } /** 118 * Returns the last object in the list. 119 * 120 last object in list. Devin Kwok: Dossier 2008 C: The Program: Page 170 of 185

172 121 */ 122 public Object getlast() 123 { 124 if( last == null ) 125 throw new NoSuchElementException(); return last.object; 128 } /** 131 * Removes the last object in the list. 132 * 133 last object in list. 134 */ 135 public Object removelast() 136 { 137 if( last == null ) 138 throw new NoSuchElementException(); if( last == first ) 141 return removefirst(); 142 Object object = last.object; Node current = first; 145 while( current.next!= last ) 146 { 147 current = current.next; 148 } 149 current.next = null; 150 last = current; 151 size--; 152 return object; 153 } /** 156 * Returns a list iterator for the list. 157 * 158 list iterator for list. 159 */ 160 public ListIterator listiterator() 161 { 162 return new ObjectListIterator(); 163 } /** 166 * Returns the number of elements in the list. 167 * 168 number of elements in list. 169 */ 170 public int getsize() 171 { 172 return size; 173 } /** 176 * Reference to first node in list. 177 */ 178 private Node first; /** 181 * Reference to last node in list. 182 */ 183 private Node last; Devin Kwok: Dossier 2008 C: The Program: Page 171 of 185

173 /** 186 * Integer representing the number of elements in the list. 187 */ 188 private int size; /** 191 * The Node class contains objects in the list. 192 * 193 Devin Kwok 194 * 195 */ 196 private class Node 197 { 198 /** 199 * The object stored in the node. 200 */ 201 public Object object; /** 204 * The next node in the linked list. 205 */ 206 public Node next; 207 } /** 210 * A list iterator for the linked list. 211 * 212 Devin Kwok 213 * 214 */ 215 private class ObjectListIterator implements ListIterator 216 { 217 /** 218 * Creates a new list iterator. 219 */ 220 public ObjectListIterator() 221 { 222 current = null; 223 previous = null; 224 } /** 227 * Returns the next object in the list. 228 */ 229 public Object next() 230 { 231 if(!hasnext() ) 232 throw new NoSuchElementException(); previous = current; 235 if( current == null ) 236 current = first; 237 else 238 current = current.next; return current.object; 241 } /** 244 * Returns true if the list has elements remaining. 245 */ 246 public boolean hasnext() Devin Kwok: Dossier 2008 C: The Program: Page 172 of 185

174 247 { 248 if( current == null ) 249 return first!= null; 250 else 251 return current.next!= null; 252 } /** 255 * Adds an object to the list at the specified position. 256 */ 257 public void add( Object object ) 258 { 259 if( current == null ) 260 { 261 addfirst( object ); 262 current = first; 263 } 264 else 265 { 266 Node newnode = new Node(); 267 newnode.object = object; 268 newnode.next = current.next; 269 current.next = newnode; 270 current = newnode; 271 size++; 272 } 273 } /** 276 * Removes an object at the specified position. 277 */ 278 public Object remove() 279 { 280 if( previous == current ) 281 throw new IllegalStateException(); if( current == first ) 284 return removefirst(); Object object = current.object; 287 previous.next = current.next; 288 current = previous; 289 size--; 290 return object; 291 } /** 294 * Current node which the iterator has traversed most recently. 295 */ 296 private Node current; /** 299 * Node which was traversed prior to the current node. 300 */ 301 private Node previous; 302 } 303 } Devin Kwok: Dossier 2008 C: The Program: Page 173 of 185

175 Interface: ListIterator 01 package com.gmail.kwok.devin.util; /** 04 * An interface defining the properties of a list iterator. The list iterator 05 * can traverse a list in order and add or remove elements along the list. 06 * 07 Devin Kwok 08 * 09 */ 10 public interface ListIterator 11 { 12 /** 13 * Contains another rule. 14 * 15 true if there is another object. 16 */ 17 boolean hasnext(); /** 20 * Returns the next object. 21 * 22 object that was traversed. 23 */ 24 Object next(); /** 27 * Adds a object to the collection at the iterator's current location. 28 * 29 object object to be added. 30 */ 31 void add( Object object ); /** 34 * Removes the object at the iterator's current location. Cannot be called 35 * consecutively. 36 * 37 object that was removed. 38 */ 39 Object remove(); 40 } Devin Kwok: Dossier 2008 C: The Program: Page 174 of 185

176 Class: LocationVector 001 package com.gmail.kwok.devin.util; /** 004 * A vector which allows different universe implements to specify the 005 * coordinates of a cell. 006 * 007 Devin Kwok 008 * 009 */ 010 public class LocationVector 011 { 012 /** 013 * Constructs a new location vector with a default number of elements. 014 */ 015 public LocationVector() 016 { 017 values = new int[ DEFAULT ]; 018 } /** 021 * Constructs a new location vector with a single integer value. 022 * 023 a integer value. 024 */ 025 public LocationVector( int a ) 026 { 027 values = new int[ 1 ]; 028 values[ 0 ] = a; 029 } /** 032 * Constructs a new location vector with two integer values. 033 * 034 a integer value. 035 b integer value. 036 */ 037 public LocationVector( int a, int b ) 038 { 039 values = new int[ 2 ]; 040 values[ 0 ] = a; 041 values[ 1 ] = b; 042 } /** 045 * Constructs a new location vector with three integer values. 046 * 047 a integer value. 048 b integer value. 049 c integer value. 050 */ 051 public LocationVector( int a, int b, int c ) 052 { 053 values = new int[ 3 ]; 054 values[ 0 ] = a; 055 values[ 1 ] = b; 056 values[ 2 ] = c; 057 } /** Devin Kwok: Dossier 2008 C: The Program: Page 175 of 185

177 060 * Constructs a new location vector from the given integer array. 061 * 062 values array of integer values. 063 */ 064 public LocationVector( int[] values ) 065 { 066 this.values = values; 067 } /** 070 * Returns the value at the given integer key. 071 * 072 key integer key. 073 integer value at the key. 074 */ 075 public int getvalue( int key ) 076 { 077 return values[ key ]; 078 } /** 081 * Sets the value at the given integer key. 082 * 083 key integer key. 084 value integer to set value at. 085 */ 086 public void setvalue( int key, int value ) 087 { 088 values[ key ] = value; 089 } /** 092 * Returns the number of elements in the vector. 093 * 094 number of elements. 095 */ 096 public int getlength() 097 { 098 return values.length; 099 } /** 102 * Default number of elements in the vector. 103 */ 104 private static final int DEFAULT = 5; /** 107 * Array of integer values in the vector. 108 */ 109 private int[] values; 110 } Devin Kwok: Dossier 2008 C: The Program: Page 176 of 185

178 C.II: Usability Figure C.1: The entire dossier program. There are two toolbars, one above and one to the left of the simulation window in the center. The menu bar is on top. Figure C.2: This is the file menu in the menu bar. Notice how some items cannot be selected until a universe is loaded. Devin Kwok: Dossier 2008 C: The Program: Page 177 of 185

179 Figure C.3: This is one of two dialog boxes shown when creating a new universe. Figure C.4: This is the file chooser which allows the user to select a file to open. The file chooser has a filter which prevents the user from selecting files with the wrong extension. Figure C.5: This is the help window which appears when the user selects Help and Contents from the menu bar. It is scrollable and displaying a HTML file. Devin Kwok: Dossier 2008 C: The Program: Page 178 of 185

180 Figure C.6: This is the tool bar on top of the simulation window. The two leftmost buttons control the simulation. The two rightmost buttons are tools. The cursor which the mouse assumes is identical to the icons shown on the two tool buttons. The green arrow button (run button) becomes a red square once the simulation is running. Figure C.7:A small window containing information about the program. Appears when the user selects Help and About. Figure C.8: A dialog box which appears when the user selects Simulation and Speed. Lets the user toggle between the two types of speed control and select a speed using the spinner. The spinner automaticially limits the user from entering extreme values. Figure C.9: A dialog box which appears when the user selects View and Zoom. Lets the user select the zoom using the spinner. The spinner automatically limits the user from entering extreme values. Devin Kwok: Dossier 2008 C: The Program: Page 179 of 185

181 Figure C.10: A table displaying states, and their values at a cell selected by the edit tool. The user can edit modifiable states by entering a value into the table as shown. Other features: When the user selects the drag tool, the user may drag the mouse over the simulation window to move the viewing area. When the user selects the edit tool, the user may select any cell in the viewing area by clicking, and that cell s information will be displayed in a table in the toolbar to the left of the simulating window. Devin Kwok: Dossier 2008 C: The Program: Page 180 of 185

182 C.III: Handling Error Figure C.1 and C.2: When creating a new universe the number of rows must be greater than 0. Otherwise an error prompt is displayed. The source code below is from class FileMenu in package com.gmail.kwok.devin.gui.frame.menu, method createnewitem(). The menu listener creates the two dialog boxes within a try block which attempts to parse the proper integer values. The listener then proceeds to create a new universe and universe component. However, if an exception is thrown the catch statement causes errors in input to display an error dialog. 063 class MenuItemListener implements ActionListener 064 { 065 public void actionperformed( ActionEvent event ) 066 { 067 try 068 { 069 int rows = Integer.parseInt( JOptionPane.showInputDialog( 070 frame, "Enter universe rows:" ) ); 071 if( rows < 1 ) 072 throw new NumberFormatException(); 073 int columns = Integer.parseInt( JOptionPane 074.showInputDialog( frame, 075 "Enter universe columns:" ) ); 076 if( columns < 1 ) 077 throw new NumberFormatException(); Universe universe = new Universe2D( frame.getrules() 080.getStateDefinitions(), frame.getrules() 081.getIndependentRules(), rows, columns ); 082 universe.setdefaultboundary(); UniverseComponent component = new Universe2DComponent( 085 (Universe2D) universe, frame.getrules() 086.getDefaultGraphics( universe ) ); 087 frame.setcomponent( component ); 088 } 089 catch( NumberFormatException e ) 090 { Devin Kwok: Dossier 2008 C: The Program: Page 181 of 185

183 091 JOptionPane.showMessageDialog( frame, 092 "Integer value > 0 required", "Error", 093 JOptionPane.ERROR_MESSAGE ); 094 } 095 } 096 } Figure C.3 and C.4: When opening a universe the file must be a valid.uni file. Otherwise, the program shows an error dialog. The source code below is from the class UniverseReader in package com.gmail.kwok.devin.file, method showopendialog(). The try block surrounds the actual reading of the file, and if an exception occurs because the file contains the wrong kinds of data, an error dialog is displayed. 074 try 075 { 076 input = new RandomAccessFile( filename, "rw" ); 077 readfile(); 078 setframe(); 079 input.close(); 080 } 081 catch( IOException e ) 082 { 083 JOptionPane.showMessageDialog( parentframe, "Error opening file", 084 "Error opening file", JOptionPane.ERROR_MESSAGE ); 085 } Devin Kwok: Dossier 2008 C: The Program: Page 182 of 185

184 Figure C.5, C.6, and C.7: When opening the help file, the HTML help file must be in the proper location. Otherwise an error dialog is shown and the help window is empty. The source code below is from the class HelpFrame in package com.gmail.kwok.devin.gui.frame.menu.dialog, method sethelpfile(). The try block surrounds the opening of the URL, and an if/else statement detects if the file cannot be found. An error dialog is supplied for each condition. 51 private void sethelpfile( JEditorPane editorpane, UniverseFrame frame ) 52 { 53 URL url = this.getclass().getresource( Resource.HELP_CONTENTS ); 54 if( url!= null ) 55 { 56 try 57 { 58 editorpane.setpage( url ); 59 } 60 catch( IOException ioexception ) 61 { 62 JOptionPane.showMessageDialog( frame, "Bad URL", "Bad URL", 63 JOptionPane.ERROR_MESSAGE ); 64 } 65 } 66 else 67 { 68 JOptionPane.showMessageDialog( frame, "File Not Found", 69 "File Not Found", JOptionPane.ERROR_MESSAGE ); 70 } 71 } Devin Kwok: Dossier 2008 C: The Program: Page 183 of 185

185 Figure C.8: Unfortunately, the custom exception StackOverflowException is currently almost impossible to cause. However, the custom exception IncompatibleFormatException can be thrown when a file is not written properly to simulate attempting to read a file with different rules than currently specified by the simulation. The source code below is from the class UniverseReader in package com.gmail.kwok.devin.file, method showopendialog(). The try block surrounds the file reading, and when an IncompatibleFormatException is thrown a slightly different error message is displayed. 074 try 075 { 076 input = new RandomAccessFile( filename, "rw" ); 077 readfile(); 078 setframe(); 079 input.close(); 080 } 081 catch( IncompatibleFormatException e ) 082 { 083 JOptionPane.showMessageDialog( parentframe, "Error opening file", 084 "Format does not match current rules", 085 JOptionPane.ERROR_MESSAGE ); 086 return; 087 } The following is where the exception is thrown, in the same class but method verifysignature(). The if statements test to see whether the header of the file matches the one required by the current set of rules. 156 if( definition.ismodifiable() &&!s.equals( definition.gettype() ) ) 157 throw new IncompatibleFormatException(); 158 if(!definition.ismodifiable() &&!s.equals( "" ) ) 159 throw new IncompatibleFormatException(); The following is the exception itself, class IncompatibleFormatException in package com.gmail.kwok.devin.file: Devin Kwok: Dossier 2008 C: The Program: Page 184 of 185

PROGRAMMING DESIGN USING JAVA (ITT 303) Unit 7

PROGRAMMING DESIGN USING JAVA (ITT 303) Unit 7 PROGRAMMING DESIGN USING JAVA (ITT 303) Graphical User Interface Unit 7 Learning Objectives At the end of this unit students should be able to: Build graphical user interfaces Create and manipulate buttons,

More information

Handout 14 Graphical User Interface (GUI) with Swing, Event Handling

Handout 14 Graphical User Interface (GUI) with Swing, Event Handling Handout 12 CS603 Object-Oriented Programming Fall 15 Page 1 of 12 Handout 14 Graphical User Interface (GUI) with Swing, Event Handling The Swing library (javax.swing.*) Contains classes that implement

More information

Swing UI. Powered by Pentalog. by Vlad Costel Ungureanu for Learn Stuff

Swing UI. Powered by Pentalog. by Vlad Costel Ungureanu for Learn Stuff Swing UI by Vlad Costel Ungureanu for Learn Stuff User Interface Command Line Graphical User Interface (GUI) Tactile User Interface (TUI) Multimedia (voice) Intelligent (gesture recognition) 2 Making the

More information

PIC 20A GUI with swing

PIC 20A GUI with swing PIC 20A GUI with swing Ernest Ryu UCLA Mathematics Last edited: November 22, 2017 Hello swing Let s create a JFrame. import javax. swing.*; public class Test { public static void main ( String [] args

More information

Goals. Lecture 7 More GUI programming. The application. The application D&D 12. CompSci 230: Semester JFrame subclass: ListOWords

Goals. Lecture 7 More GUI programming. The application. The application D&D 12. CompSci 230: Semester JFrame subclass: ListOWords Goals By the end of this lesson, you should: Lecture 7 More GUI programming 1. Be able to write Java s with JTextField, JList, JCheckBox and JRadioButton components 2. Be able to implement a ButtonGroup

More information

1.1 GUI. JFrame. import java.awt.*; import javax.swing.*; public class XXX extends JFrame { public XXX() { // XXX. init() main() public static

1.1 GUI. JFrame. import java.awt.*; import javax.swing.*; public class XXX extends JFrame { public XXX() { // XXX. init() main() public static 18 7 17 1 1.1 GUI ( ) GUI ( ) JFrame public class XXX extends JFrame { public XXX() { // XXX // init()... // ( )... init() main() public static public class XXX extends JFrame { public XXX() { // setsize(,

More information

PART 23. Java GUI Advanced JList Component. more items.

PART 23. Java GUI Advanced JList Component. more items. PART 23 Java GUI Advanced 23.1 JList Component JList is a component that displays a list of objects. It allows the user to select one or more items. import java.awt.color; import java.awt.eventqueue; import

More information

Graphical User Interfaces in Java - SWING

Graphical User Interfaces in Java - SWING Graphical User Interfaces in Java - SWING Graphical User Interfaces (GUI) Each graphical component that the user can see on the screen corresponds to an object of a class Component: Window Button Menu...

More information

Example: Building a Java GUI

Example: Building a Java GUI Steven Zeil October 25, 2013 Contents 1 Develop the Model 3 2 Develop the layout of those elements 4 3 Add listeners to the elements 12 4 Implement custom drawing 15 1 The StringArt Program To illustrate

More information

Based on slides by Prof. Burton Ma

Based on slides by Prof. Burton Ma Based on slides by Prof. Burton Ma 1 TV - on : boolean - channel : int - volume : int + power(boolean) : void + channel(int) : void + volume(int) : void Model View Controller RemoteControl + togglepower()

More information

Part I: Learn Common Graphics Components

Part I: Learn Common Graphics Components OOP GUI Components and Event Handling Page 1 Objectives 1. Practice creating and using graphical components. 2. Practice adding Event Listeners to handle the events and do something. 3. Learn how to connect

More information

Advanced Java Unit 6: Review of Graphics and Events

Advanced Java Unit 6: Review of Graphics and Events Advanced Java Unit 6: Review of Graphics and Events This is a review of the basics of writing a java program that has a graphical interface. To keep things simple, all of the graphics programs will follow

More information

AP CS Unit 11: Graphics and Events

AP CS Unit 11: Graphics and Events AP CS Unit 11: Graphics and Events This packet shows how to create programs with a graphical interface in a way that is consistent with the approach used in the Elevens program. Copy the following two

More information

GUI (Graphic User Interface) Programming. Part 2 (Chapter 8) Chapter Goals. Events, Event Sources, and Event Listeners. Listeners

GUI (Graphic User Interface) Programming. Part 2 (Chapter 8) Chapter Goals. Events, Event Sources, and Event Listeners. Listeners GUI (Graphic User Interface) Programming Part 2 (Chapter 8) Chapter Goals To understand the Java event model To install action and mouse event listeners To accept input from buttons, text fields, and the

More information

Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written.

Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written. SOLUTION HAND IN Answers Are Recorded on Question Paper QUEEN'S UNIVERSITY SCHOOL OF COMPUTING CISC212, FALL TERM, 2006 FINAL EXAMINATION 7pm to 10pm, 19 DECEMBER 2006, Jeffrey Hall 1 st Floor Instructor:

More information

Chapter 8. Java continued. CS Hugh Anderson s notes. Page number: 264 ALERT. MCQ test next week. This time. This place.

Chapter 8. Java continued. CS Hugh Anderson s notes. Page number: 264 ALERT. MCQ test next week. This time. This place. Chapter 8 Java continued CS3283 - Hugh Anderson s notes. Page number: 263 ALERT MCQ test next week This time This place Closed book CS3283 - Hugh Anderson s notes. Page number: 264 ALERT Assignment #2

More information

Java continued. Chapter 8 ALERT ALERT. Last week. MCQ test next week. This time. This place. Closed book. Assignment #2 is for groups of 3

Java continued. Chapter 8 ALERT ALERT. Last week. MCQ test next week. This time. This place. Closed book. Assignment #2 is for groups of 3 Chapter 8 Java continued MCQ test next week This time This place Closed book ALERT CS3283 - Hugh Anderson s notes. Page number: 263 CS3283 - Hugh Anderson s notes. Page number: 264 ALERT Last week Assignment

More information

Example: Building a Java GUI

Example: Building a Java GUI Steven Zeil October 25, 2013 Contents 1 Develop the Model 2 2 Develop the layout of those elements 3 3 Add listeners to the elements 9 4 Implement custom drawing 12 1 The StringArt Program To illustrate

More information

Graphic User Interfaces. - GUI concepts - Swing - AWT

Graphic User Interfaces. - GUI concepts - Swing - AWT Graphic User Interfaces - GUI concepts - Swing - AWT 1 What is GUI Graphic User Interfaces are used in programs to communicate more efficiently with computer users MacOS MS Windows X Windows etc 2 Considerations

More information

Building Graphical User Interfaces. GUI Principles

Building Graphical User Interfaces. GUI Principles Building Graphical User Interfaces 4.1 GUI Principles Components: GUI building blocks Buttons, menus, sliders, etc. Layout: arranging components to form a usable GUI Using layout managers. Events: reacting

More information

17 GUI API: Container 18 Hello world with a GUI 19 GUI API: JLabel 20 GUI API: Container: add() 21 Hello world with a GUI 22 GUI API: JFrame: setdefau

17 GUI API: Container 18 Hello world with a GUI 19 GUI API: JLabel 20 GUI API: Container: add() 21 Hello world with a GUI 22 GUI API: JFrame: setdefau List of Slides 1 Title 2 Chapter 13: Graphical user interfaces 3 Chapter aims 4 Section 2: Example:Hello world with a GUI 5 Aim 6 Hello world with a GUI 7 Hello world with a GUI 8 Package: java.awt and

More information

SampleApp.java. Page 1

SampleApp.java. Page 1 SampleApp.java 1 package msoe.se2030.sequence; 2 3 /** 4 * This app creates a UI and processes data 5 * @author hornick 6 */ 7 public class SampleApp { 8 private UserInterface ui; // the UI for this program

More information

CSCI 201L Midterm Written Summer % of course grade

CSCI 201L Midterm Written Summer % of course grade CSCI 201L Summer 2016 10% of course grade 1. Abstract Classes and Interfaces Give two differences between an interface and an abstract class in which all of the methods are abstract. (0.5% + 0.5%) 2. Serialization

More information

Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written.

Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written. HAND IN Answers Are Recorded on Question Paper QUEEN'S UNIVERSITY SCHOOL OF COMPUTING CISC124, WINTER TERM, 2009 FINAL EXAMINATION 7pm to 10pm, 18 APRIL 2009, Dunning Hall Instructor: Alan McLeod If the

More information

Programming graphics

Programming graphics Programming graphics Need a window javax.swing.jframe Several essential steps to use (necessary plumbing ): Set the size width and height in pixels Set a title (optional), and a close operation Make it

More information

Building Graphical User Interfaces. Overview

Building Graphical User Interfaces. Overview Building Graphical User Interfaces 4.1 Overview Constructing GUIs Interface components GUI layout Event handling 2 1 GUI Principles Components: GUI building blocks. Buttons, menus, sliders, etc. Layout:

More information

Page 1 of 16. Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written.

Page 1 of 16. Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written. Page 1 of 16 SOLUTION HAND IN Answers Are Recorded on Question Paper QUEEN'S UNIVERSITY SCHOOL OF COMPUTING CISC212, FALL TERM, 2005 FINAL EXAMINATION 9am to 12noon, 19 DECEMBER 2005 Instructor: Alan McLeod

More information

Window Interfaces Using Swing Objects

Window Interfaces Using Swing Objects Chapter 12 Window Interfaces Using Swing Objects Event-Driven Programming and GUIs Swing Basics and a Simple Demo Program Layout Managers Buttons and Action Listeners Container Classes Text I/O for GUIs

More information

CS 251 Intermediate Programming GUIs: Event Listeners

CS 251 Intermediate Programming GUIs: Event Listeners CS 251 Intermediate Programming GUIs: Event Listeners Brooke Chenoweth University of New Mexico Fall 2017 What is an Event Listener? A small class that implements a particular listener interface. Listener

More information

Overview. Building Graphical User Interfaces. GUI Principles. AWT and Swing. Constructing GUIs Interface components GUI layout Event handling

Overview. Building Graphical User Interfaces. GUI Principles. AWT and Swing. Constructing GUIs Interface components GUI layout Event handling Overview Building Graphical User Interfaces Constructing GUIs Interface components GUI layout Event handling 4.1 GUI Principles AWT and Swing Components: GUI building blocks. Buttons, menus, sliders, etc.

More information

Introduction to the JAVA UI classes Advanced HCI IAT351

Introduction to the JAVA UI classes Advanced HCI IAT351 Introduction to the JAVA UI classes Advanced HCI IAT351 Week 3 Lecture 1 17.09.2012 Lyn Bartram lyn@sfu.ca About JFC and Swing JFC Java TM Foundation Classes Encompass a group of features for constructing

More information

COMP16121 Sample Code Lecture 1

COMP16121 Sample Code Lecture 1 COMP16121 Sample Code Lecture 1 Sean Bechhofer, University of Manchester, Manchester, UK sean.bechhofer@manchester.ac.uk 1 SimpleFrame 1 import javax.swing.jframe; 2 3 public class SimpleFrame { 4 5 /*

More information

CS 251 Intermediate Programming GUIs: Components and Layout

CS 251 Intermediate Programming GUIs: Components and Layout CS 251 Intermediate Programming GUIs: Components and Layout Brooke Chenoweth University of New Mexico Fall 2017 import javax. swing.*; Hello GUI public class HelloGUI extends JFrame { public HelloGUI ()

More information

CSE 143. Event-driven Programming and Graphical User Interfaces (GUIs) with Swing/AWT

CSE 143. Event-driven Programming and Graphical User Interfaces (GUIs) with Swing/AWT CSE 143 Event-driven Programming and Graphical User Interfaces (GUIs) with Swing/AWT slides created by Marty Stepp based on materials by M. Ernst, S. Reges, D. Notkin, R. Mercer, Wikipedia http://www.cs.washington.edu/331/

More information

Dr. Hikmat A. M. AbdelJaber

Dr. Hikmat A. M. AbdelJaber Dr. Hikmat A. M. AbdelJaber GUI are event driven (i.e. when user interacts with a GUI component, the interaction (event) derives the program to perform a task). Event: click button, type in text field,

More information

Datenbank-Praktikum. Universität zu Lübeck Sommersemester 2006 Lecture: Swing. Ho Ngoc Duc 1

Datenbank-Praktikum. Universität zu Lübeck Sommersemester 2006 Lecture: Swing. Ho Ngoc Duc 1 Datenbank-Praktikum Universität zu Lübeck Sommersemester 2006 Lecture: Swing Ho Ngoc Duc 1 Learning objectives GUI applications Font, Color, Image Running Applets as applications Swing Components q q Text

More information

class BankFilter implements Filter { public boolean accept(object x) { BankAccount ba = (BankAccount) x; return ba.getbalance() > 1000; } }

class BankFilter implements Filter { public boolean accept(object x) { BankAccount ba = (BankAccount) x; return ba.getbalance() > 1000; } } 9.12) public interface Filter boolean accept(object x); Describes any class whose objects can measure other objects. public interface Measurer double measure(object anobject); This program tests the use

More information

Swing. Component overview. Java UI, summer semester 2017/2018 1

Swing. Component overview. Java UI, summer semester 2017/2018 1 Swing Component overview 1 Label class JLabel for displaying short text image both 2 Buttons many kinds of buttons all of them extends AbstractButton regular button (JButton) "click" button toggle button

More information

Window Interfaces Using Swing Objects

Window Interfaces Using Swing Objects Chapter 12 Window Interfaces Using Swing Objects Event-Driven Programming and GUIs Swing Basics and a Simple Demo Program Layout Managers Buttons and Action Listeners Container Classes Text I/O for GUIs

More information

Java Graphical User Interfaces AWT (Abstract Window Toolkit) & Swing

Java Graphical User Interfaces AWT (Abstract Window Toolkit) & Swing Java Graphical User Interfaces AWT (Abstract Window Toolkit) & Swing Rui Moreira Some useful links: http://java.sun.com/docs/books/tutorial/uiswing/toc.html http://www.unix.org.ua/orelly/java-ent/jfc/

More information

Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written.

Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written. HAND IN Answers Are Recorded on Question Paper QUEEN'S UNIVERSITY SCHOOL OF COMPUTING CISC212, FALL TERM, 2006 FINAL EXAMINATION 7pm to 10pm, 19 DECEMBER 2006, Jeffrey Hall 1 st Floor Instructor: Alan

More information

Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written.

Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written. Solution HAND IN Answers Are Recorded on Question Paper QUEEN'S UNIVERSITY SCHOOL OF COMPUTING CISC212, FALL TERM, 2007 FINAL EXAMINATION 7pm to 10pm, 10 DECEMBER 2007, Jeffery Hall Instructor: Alan McLeod

More information

Java GUI Design: the Basics

Java GUI Design: the Basics Java GUI Design: the Basics Daniel Brady July 25, 2014 What is a GUI? A GUI is a graphical user interface, of course. What is a graphical user interface? A graphical user interface is simply a visual way

More information

Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written.

Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written. SOLUTION HAND IN Answers Are Recorded on Question Paper QUEEN'S UNIVERSITY SCHOOL OF COMPUTING CISC124, WINTER TERM, 2009 FINAL EXAMINATION 7pm to 10pm, 18 APRIL 2009, Dunning Hall Instructor: Alan McLeod

More information

(listener)... MouseListener, ActionLister. (adapter)... MouseAdapter, ActionAdapter. java.awt AWT Abstract Window Toolkit GUI

(listener)... MouseListener, ActionLister. (adapter)... MouseAdapter, ActionAdapter. java.awt AWT Abstract Window Toolkit GUI 51 6!! GUI(Graphical User Interface) java.awt javax.swing (component) GUI... (container) (listener)... MouseListener, ActionLister (adapter)... MouseAdapter, ActionAdapter 6.1 GUI(Graphics User Interface

More information

SINGLE EVENT HANDLING

SINGLE EVENT HANDLING SINGLE EVENT HANDLING Event handling is the process of responding to asynchronous events as they occur during the program run. An event is an action that occurs externally to your program and to which

More information

encompass a group of features for building Graphical User Interfaces (GUI).

encompass a group of features for building Graphical User Interfaces (GUI). Java GUI (intro) JFC Java Foundation Classes encompass a group of features for building Graphical User Interfaces (GUI). javax.swing.* used for building GUIs. Some basic functionality is already there

More information

Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written.

Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written. HAND IN Answers Are Recorded on Question Paper QUEEN'S UNIVERSITY SCHOOL OF COMPUTING CISC212, FALL TERM, 2007 FINAL EXAMINATION 7pm to 10pm, 10 DECEMBER 2007, Jeffery Hall Instructor: Alan McLeod If the

More information

Graphical User Interfaces 2

Graphical User Interfaces 2 Graphical User Interfaces 2 CSCI 136: Fundamentals CSCI 136: Fundamentals of Computer of Science Computer II Science Keith II Vertanen Keith Vertanen Copyright 2011 Extending JFrame Dialog boxes Overview

More information

Building Java Programs Bonus Slides

Building Java Programs Bonus Slides Building Java Programs Bonus Slides Graphical User Interfaces Copyright (c) Pearson 2013. All rights reserved. Graphical input and output with JOptionPane JOptionPane An option pane is a simple dialog

More information

Graphical User Interface (GUI) components in Java Applets. With Abstract Window Toolkit (AWT) we can build an applet that has the basic GUI

Graphical User Interface (GUI) components in Java Applets. With Abstract Window Toolkit (AWT) we can build an applet that has the basic GUI CBOP3203 Graphical User Interface (GUI) components in Java Applets. With Abstract Window Toolkit (AWT) we can build an applet that has the basic GUI components like button, text input, scroll bar and others.

More information

Hanley s Survival Guide for Visual Applications with NetBeans 2.0 Last Updated: 5/20/2015 TABLE OF CONTENTS

Hanley s Survival Guide for Visual Applications with NetBeans 2.0 Last Updated: 5/20/2015 TABLE OF CONTENTS Hanley s Survival Guide for Visual Applications with NetBeans 2.0 Last Updated: 5/20/2015 TABLE OF CONTENTS Glossary of Terms 2-4 Step by Step Instructions 4-7 HWApp 8 HWFrame 9 Never trust a computer

More information

package As7BattleShip;

package As7BattleShip; package As7BattleShip; Program: BattleshipBoard.java Author: Kevin Nider Date: 11/18/12 Description: Assignment 7: Runs the battleship game Input: ship placement board files and computer player type Output:

More information

Lecture 28. Exceptions and Inner Classes. Goals. We are going to talk in more detail about two advanced Java features:

Lecture 28. Exceptions and Inner Classes. Goals. We are going to talk in more detail about two advanced Java features: Lecture 28 Exceptions and Inner Classes Goals We are going to talk in more detail about two advanced Java features: Exceptions supply Java s error handling mechanism. Inner classes ease the overhead of

More information

Java: Graphical User Interfaces (GUI)

Java: Graphical User Interfaces (GUI) Chair of Software Engineering Carlo A. Furia, Marco Piccioni, and Bertrand Meyer Java: Graphical User Interfaces (GUI) With material from Christoph Angerer The essence of the Java Graphics API Application

More information

Chapter 6: Graphical User Interfaces

Chapter 6: Graphical User Interfaces Chapter 6: Graphical User Interfaces CS 121 Department of Computer Science College of Engineering Boise State University April 21, 2015 Chapter 6: Graphical User Interfaces CS 121 1 / 36 Chapter 6 Topics

More information

Systems Programming. Bachelor in Telecommunication Technology Engineering Bachelor in Communication System Engineering Carlos III University of Madrid

Systems Programming. Bachelor in Telecommunication Technology Engineering Bachelor in Communication System Engineering Carlos III University of Madrid Systems Programming Bachelor in Telecommunication Technology Engineering Bachelor in Communication System Engineering Carlos III University of Madrid Leganés, 21st of March, 2014. Duration: 75 min. Full

More information

Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written.

Proctors are unable to respond to queries about the interpretation of exam questions. Do your best to answer exam questions as written. QUEEN'S UNIVERSITY SCHOOL OF COMPUTING HAND IN Answers Are Recorded on Question Paper CMPE212, FALL TERM, 2012 FINAL EXAMINATION 18 December 2012, 2pm Instructor: Alan McLeod If the instructor is unavailable

More information

Assignment #3 (Due 4/4/2017)

Assignment #3 (Due 4/4/2017) Assignment #3 (Due 4/4/2017) As a follow up to Assignment #2, modify the CheckingAccount class to add the following instance members: an array (self-expanding type) or ArrayList of Transaction objects

More information

CSCI 201L Midterm Written SOLUTION Summer % of course grade

CSCI 201L Midterm Written SOLUTION Summer % of course grade CSCI 201L SOLUTION Summer 2016 10% of course grade 1. Abstract Classes and Interfaces Give two differences between an interface and an abstract class in which all of the methods are abstract. (0.5% + 0.5%)

More information

Chapter 13 Lab Advanced GUI Applications Lab Objectives. Introduction. Task #1 Creating a Menu with Submenus

Chapter 13 Lab Advanced GUI Applications Lab Objectives. Introduction. Task #1 Creating a Menu with Submenus Chapter 13 Lab Advanced GUI Applications Lab Objectives Be able to add a menu to the menu bar Be able to use nested menus Be able to add scroll bars, giving the user the option of when they will be seen.

More information

Chapter 13 Lab Advanced GUI Applications

Chapter 13 Lab Advanced GUI Applications Gaddis_516907_Java 4/10/07 2:10 PM Page 113 Chapter 13 Lab Advanced GUI Applications Objectives Be able to add a menu to the menu bar Be able to use nested menus Be able to add scroll bars, giving the

More information

FirstSwingFrame.java Page 1 of 1

FirstSwingFrame.java Page 1 of 1 FirstSwingFrame.java Page 1 of 1 2: * A first example of using Swing. A JFrame is created with 3: * a label and buttons (which don t yet respond to events). 4: * 5: * @author Andrew Vardy 6: */ 7: import

More information

Java Programming Lecture 6

Java Programming Lecture 6 Java Programming Lecture 6 Alice E. Fischer Feb 15, 2013 Java Programming - L6... 1/32 Dialog Boxes Class Derivation The First Swing Programs: Snow and Moving The Second Swing Program: Smile Swing Components

More information

public void mouseexited (MouseEvent e) setminute(getminute()+increment); 11.2 public void mouseclicked (MouseEvent e) int x = e.getx(), y = e.gety();

public void mouseexited (MouseEvent e) setminute(getminute()+increment); 11.2 public void mouseclicked (MouseEvent e) int x = e.getx(), y = e.gety(); 11 The Jav aawt Part I: Mouse Events 11.1 public void mouseentered (MouseEvent e) setminute(getminute()+increment); 53 public void mouseexited (MouseEvent e) setminute(getminute()+increment); 11.2 public

More information

User interfaces and Swing

User interfaces and Swing User interfaces and Swing Overview, applets, drawing, action listening, layout managers. APIs: java.awt.*, javax.swing.*, classes names start with a J. Java Lectures 1 2 Applets public class Simple extends

More information

Object-Oriented Programming Design. Topic : User Interface Components with Swing GUI Part III

Object-Oriented Programming Design. Topic : User Interface Components with Swing GUI Part III Electrical and Computer Engineering Object-Oriented Topic : User Interface Components with Swing GUI Part III Maj Joel Young Joel.Young@afit.edu 17-Sep-03 Maj Joel Young Creating GUI Apps The Process Overview

More information

Chapter 9 Designing Graphical User Interfaces (GUIs)

Chapter 9 Designing Graphical User Interfaces (GUIs) Chapter 9 Designing Graphical User Interfaces (GUIs) Overview The basics of GUIs in Java A tour of Java GUI libraries Containers and components Swing: the full picture Layout managers Understanding events

More information

CSCI 201L Midterm Written SOLUTION Fall % of course grade

CSCI 201L Midterm Written SOLUTION Fall % of course grade CSCI 201L Midterm Written SOLUTION Fall 2015 10% of course grade 1. Inheritance Answer the following questions about inheritance. a. Does Java allow overloading, overriding, and redefining of methods?

More information

CSIS 10A Assignment 7 SOLUTIONS

CSIS 10A Assignment 7 SOLUTIONS CSIS 10A Assignment 7 SOLUTIONS Read: Chapter 7 Choose and complete any 10 points from the problems below, which are all included in the download file on the website. Use BlueJ to complete the assignment,

More information

MIT AITI Swing Event Model Lecture 17

MIT AITI Swing Event Model Lecture 17 MIT AITI 2004 Swing Event Model Lecture 17 The Java Event Model In the last lecture, we learned how to construct a GUI to present information to the user. But how do GUIs interact with users? How do applications

More information

COSC 123 Computer Creativity. Graphics and Events. Dr. Ramon Lawrence University of British Columbia Okanagan

COSC 123 Computer Creativity. Graphics and Events. Dr. Ramon Lawrence University of British Columbia Okanagan COSC 123 Computer Creativity Graphics and Events Dr. Ramon Lawrence University of British Columbia Okanagan ramon.lawrence@ubc.ca Key Points 1) Draw shapes, text in various fonts, and colors. 2) Build

More information

AP CS Unit 12: Drawing and Mouse Events

AP CS Unit 12: Drawing and Mouse Events AP CS Unit 12: Drawing and Mouse Events A JPanel object can be used as a container for other objects. It can also be used as an object that we can draw on. The first example demonstrates how to do that.

More information

14.2 Java s New Nimbus Look-and-Feel 551 Sample GUI: The SwingSet3 Demo Application As an example of a GUI, consider Fig. 14.1, which shows the SwingS

14.2 Java s New Nimbus Look-and-Feel 551 Sample GUI: The SwingSet3 Demo Application As an example of a GUI, consider Fig. 14.1, which shows the SwingS 550 Chapter 14 GUI Components: Part 1 14.1 Introduction 14.2 Java s New Nimbus Look-and-Feel 14.3 Simple GUI-Based Input/Output with JOptionPane 14.4 Overview of Swing Components 14.5 Displaying Text and

More information

Swing JTable. JTable

Swing JTable. JTable Swing JTable Corso di Principi di Progettazione del Software, a.a. 2017/18 12 Dicembre 2017 ing. Roberto Vergallo 1 JTable Tables are used to display data in a spreadsheet fashion The JTable is oriented

More information

CS 209 Programming in Java #10 Exception Handling

CS 209 Programming in Java #10 Exception Handling CS 209 Programming in Java #10 Exception Handling Textbook Chapter 15 Spring, 2006 Instructor: J.G. Neal 1 Topics What is an Exception? Exception Handling Fundamentals Errors and Exceptions The try-catch-finally

More information

Starting Out with Java: From Control Structures Through Objects Sixth Edition

Starting Out with Java: From Control Structures Through Objects Sixth Edition Starting Out with Java: From Control Structures Through Objects Sixth Edition Chapter 12 A First Look at GUI Applications Chapter Topics 12.1 Introduction 12.2 Creating Windows 12.3 Equipping GUI Classes

More information

II 12, JFileChooser. , 2. SolidEllipse ( 2), PolyLine.java ( 3). Draw.java

II 12, JFileChooser. , 2. SolidEllipse ( 2), PolyLine.java ( 3). Draw.java II 12, 13 (ono@isnagoya-uacjp) 2007 1 15, 17 2 : 1 2, JFileChooser, 2,,, Draw 1, SolidEllipse ( 2), PolyLinejava ( 3) 1 Drawjava 2 import javaxswing*; 3 import javaawtevent*; import javautil*; 5 import

More information

CSCI 201L Midterm Written Fall % of course grade

CSCI 201L Midterm Written Fall % of course grade CSCI 201L Midterm Written Fall 2015 10% of course grade 1. Inheritance Answer the following questions about inheritance. a. Does Java allow overloading, overriding, and redefining of methods? (0.5%) b.

More information

Outline. Topic 9: Swing. GUIs Up to now: line-by-line programs: computer displays text user types text AWT. A. Basics

Outline. Topic 9: Swing. GUIs Up to now: line-by-line programs: computer displays text user types text AWT. A. Basics Topic 9: Swing Outline Swing = Java's GUI library Swing is a BIG library Goal: cover basics give you concepts & tools for learning more Assignment 7: Expand moving shapes from Assignment 4 into game. "Programming

More information

13 (ono@is.nagoya-u.ac.jp) 2008 1 15 1 factory., factory,. 2 2.,, JFileChooser. 1. Java,,, Serializable *1., FigBase ( 1). FigBase.java 3 5. 1 import java. lang.*; 2 import java. awt.*; 3 import java.

More information

Chapter 12 GUI Basics

Chapter 12 GUI Basics Chapter 12 GUI Basics 1 Creating GUI Objects // Create a button with text OK JButton jbtok = new JButton("OK"); // Create a label with text "Enter your name: " JLabel jlblname = new JLabel("Enter your

More information

JComponent. JPanel. JFrame. JFrame JDialog, JOptionPane. JPanel. JPanel

JComponent. JPanel. JFrame. JFrame JDialog, JOptionPane. JPanel. JPanel JComponent JPanel JPanel JFrameJDialog, JOptionPane JFrame JPanel Myclass SomeInterface SomeInterface anobject = new SomeInterface () { public void interfacefunc() { System.out.println("Some

More information

Marcin Luckner Warsaw University of Technology Faculty of Mathematics and Information Science

Marcin Luckner Warsaw University of Technology Faculty of Mathematics and Information Science Marcin Luckner Warsaw University of Technology Faculty of Mathematics and Information Science mluckner@mini.pw.edu.pl http://www.mini.pw.edu.pl/~lucknerm } Abstract Window Toolkit Delegates creation and

More information

CSE 331. Event-driven Programming and Graphical User Interfaces (GUIs) with Swing/AWT

CSE 331. Event-driven Programming and Graphical User Interfaces (GUIs) with Swing/AWT CSE 331 Event-driven Programming and Graphical User Interfaces (GUIs) with Swing/AWT slides created by Marty Stepp based on materials by M. Ernst, S. Reges, D. Notkin, R. Mercer, Wikipedia http://www.cs.washington.edu/331/

More information

JLayeredPane. Depth Constants in JLayeredPane

JLayeredPane. Depth Constants in JLayeredPane JLayeredPane Continuing on Swing Components A layered pane is a Swing container that provides a third dimension for positioning components depth or Z order. The class for the layered pane is JLayeredPane.

More information

A Simple Text Editor Application

A Simple Text Editor Application CASE STUDY 7 A Simple Text Editor Application To demonstrate the JTextArea component, fonts, menus, and file choosers we present a simple text editor application. This application allows you to create

More information

Graphical User Interfaces. Comp 152

Graphical User Interfaces. Comp 152 Graphical User Interfaces Comp 152 Procedural programming Execute line of code at a time Allowing for selection and repetition Call one function and then another. Can trace program execution on paper from

More information

Contents Chapter 1 Introduction to Programming and the Java Language

Contents Chapter 1 Introduction to Programming and the Java Language Chapter 1 Introduction to Programming and the Java Language 1.1 Basic Computer Concepts 5 1.1.1 Hardware 5 1.1.2 Operating Systems 8 1.1.3 Application Software 9 1.1.4 Computer Networks and the Internet

More information

Prototyping a Swing Interface with the Netbeans IDE GUI Editor

Prototyping a Swing Interface with the Netbeans IDE GUI Editor Prototyping a Swing Interface with the Netbeans IDE GUI Editor Netbeans provides an environment for creating Java applications including a module for GUI design. Here we assume that we have some existing

More information

The JFrame Class Frame Windows GRAPHICAL USER INTERFACES. Five steps to displaying a frame: 1) Construct an object of the JFrame class

The JFrame Class Frame Windows GRAPHICAL USER INTERFACES. Five steps to displaying a frame: 1) Construct an object of the JFrame class CHAPTER GRAPHICAL USER INTERFACES 10 Slides by Donald W. Smith TechNeTrain.com Final Draft 10/30/11 10.1 Frame Windows Java provides classes to create graphical applications that can run on any major graphical

More information

GUI Components: Part Pearson Education, Inc. All rights reserved.

GUI Components: Part Pearson Education, Inc. All rights reserved. 1 11 GUI Components: Part 1 2 11.1 Introduction Graphical user interface (GUI) Presents a user-friendly mechanism for interacting with an application Often contains title bar, menu bar containing menus,

More information

DM550 / DM857 Introduction to Programming. Peter Schneider-Kamp

DM550 / DM857 Introduction to Programming. Peter Schneider-Kamp DM550 / DM857 Introduction to Programming Peter Schneider-Kamp petersk@imada.sdu.dk http://imada.sdu.dk/~petersk/dm550/ http://imada.sdu.dk/~petersk/dm857/ GRAPHICAL USER INTERFACES 2 HelloWorld Reloaded

More information

Swing I CHAPTER EVENT-DRIVEN PROGRAMMING 921 Events and Listeners 921

Swing I CHAPTER EVENT-DRIVEN PROGRAMMING 921 Events and Listeners 921 CHAPTER 17 Swing I 17.1 EVENT-DRIVEN PROGRAMMING 921 Events and Listeners 921 17.2 BUTTONS, EVENTS, AND OTHER SWING BASICS 923 Example: A Simple Window 923 Buttons 930 Action Listeners and Action Events

More information

Swing I Event-Driven Programming Buttons, Events, and Other Swing Basics Containers and Layout Managers 946

Swing I Event-Driven Programming Buttons, Events, and Other Swing Basics Containers and Layout Managers 946 17.1 Event-Driven Programming 925 Events and Listeners 925 17.2 Buttons, Events, and Other Swing Basics 926 Example: A Simple Window 927 Buttons 933 Action Listeners and Action Events 934 Example: A Better

More information

import java.applet.applet; import java.applet.audioclip; import java.net.url; public class Vjesala2 {

import java.applet.applet; import java.applet.audioclip; import java.net.url; public class Vjesala2 { import java.awt.color; import java.awt.flowlayout; import java.awt.font; import java.awt.gridlayout; import java.awt.event.actionevent; import java.awt.event.actionlistener; import javax.swing.jbutton;

More information

Workbook 7. Remember to check the course website regularly for announcements and errata:

Workbook 7. Remember to check the course website regularly for announcements and errata: Introduction Workbook 7 Last week you built your own graphical interface with Java Swing in order to make your program more accessible to other users. Unfortunately, whilst your interface looked pretty,

More information

Course Status Networking GUI Wrap-up. CS Java. Introduction to Java. Andy Mroczkowski

Course Status Networking GUI Wrap-up. CS Java. Introduction to Java. Andy Mroczkowski CS 190 - Java Introduction to Java Andy Mroczkowski uamroczk@cs.drexel.edu Department of Computer Science Drexel University March 10, 2008 / Lecture 8 Outline Course Status Course Information & Schedule

More information

Virtualians.ning.pk. 2 - Java program code is compiled into form called 1. Machine code 2. native Code 3. Byte Code (From Lectuer # 2) 4.

Virtualians.ning.pk. 2 - Java program code is compiled into form called 1. Machine code 2. native Code 3. Byte Code (From Lectuer # 2) 4. 1 - What if the main method is declared as private? 1. The program does not compile 2. The program compiles but does not run 3. The program compiles and runs properly ( From Lectuer # 2) 4. The program

More information

Packages: Putting Classes Together

Packages: Putting Classes Together Packages: Putting Classes Together 1 Introduction 2 The main feature of OOP is its ability to support the reuse of code: Extending the classes (via inheritance) Extending interfaces The features in basic

More information