dd845f988cb32205b6e5801631a7663c6daebd44
[applet-bots.git] / src / appletbots / swarm / SwarmApplet.java
1 /*
2  * Copyright (c) 2002 Erik Rasmussen - All Rights Reserverd
3  */
4 package appletbots.swarm;
5
6 import appletbots.World;
7 import appletbots.Applet;
8
9 import javax.swing.*;
10 import javax.swing.event.ChangeEvent;
11 import javax.swing.event.ChangeListener;
12 import java.awt.event.ActionEvent;
13 import java.text.NumberFormat;
14 import java.util.Hashtable;
15
16 /**
17  * An applet to run a SwarmAgent simulation
18  *
19  * @author Erik Rasmussen
20  */
21 public class SwarmApplet extends Applet
22 {
23         /**
24          * The maximum number of agents allowed
25          */
26         public static final int MAX_NUM_AGENTS = 100;
27         /**
28          * The minimum number of agents allowed
29          */
30         public static final int MIN_NUM_AGENTS = 2;
31         /**
32          * The number of agents
33          */
34         protected int numAgents = 50;
35         /**
36          * The "Number of Agents" slider
37          */
38         protected JSlider numAgentsSlider;
39         /**
40          * The "Number of Agents" label
41          */
42         protected JLabel numAgentsLabel;
43         /**
44          * The maximum agent sight value allowed
45          */
46         public static final int MAX_AGENT_SIGHT = 100;
47         /**
48          * The minimum agent sight value allowed
49          */
50         public static final int MIN_AGENT_SIGHT = 5;
51         /**
52          * The agent sight value
53          */
54         protected int agentSight = 60;
55         /**
56          * The "Agent Sight" slider
57          */
58         protected JSlider agentSightSlider;
59         /**
60          * The "Agent Sight" label
61          */
62         protected JLabel agentSightLabel;
63         /**
64          * The maximum number of neighbors to follow allowed
65          */
66         public static final int MAX_NUM_NEIGHBORS_TO_FOLLOW = 10;
67         /**
68          * The minimum number of neighbors to follow allowed
69          */
70         public static final int MIN_NUM_NEIGHBORS_TO_FOLLOW = 1;
71         /**
72          * The number of neighbors to follow
73          */
74         protected int numNeighborsToFollow = 3;
75         /**
76          * The "Number of Neighbors to Follow" slider
77          */
78         protected JSlider numNeighborsToFollowSlider;
79         /**
80          * The "Number of Neighbors to Follow" label
81          */
82         protected JLabel numNeighborsToFollowLabel;
83         /**
84          * The maximum randomization factor allowed
85          */
86         public static final int MAX_RANDOMIZATION_FACTOR = 100;
87         /**
88          * The minimum randomization factor allowed
89          */
90         public static final int MIN_RANDOMIZATION_FACTOR = 0;
91         /**
92          * The randomization factor
93          */
94         protected int randomizationFactor = 10;
95         /**
96          * The "Randomization Factor" slider
97          */
98         protected JSlider randomizationFactorSlider;
99         /**
100          * The "Randomization Factor" label
101          */
102         protected JLabel randomizationFactorLabel;
103         /**
104          * The "Choose Neighbors by Proximity" checkbox
105          */
106         protected JCheckBox chooseNeighborsByProximityCheckBox;
107         /**
108          * How to choose neighbors to follow
109          */
110         protected boolean chooseNeighborsByProximity = true;
111
112         private static final NumberFormat PERCENT_FORMAT = NumberFormat.getPercentInstance();
113
114         /**
115          * Initializes the world with the appropriate number of SwarmAgents
116          * with the appropriate "agent sight" settings
117          *
118          * @return A world with SwarmAgents
119          */
120         protected World initializeWorld()
121         {
122                 final World world = new World(300, 300);
123                 try
124                 {
125                         for (int i = 0; i < numAgents; i++)
126                                 world.addObject(new SwarmAgent(5, agentSight, 5, 3, numNeighborsToFollow, chooseNeighborsByProximity, randomizationFactor / 100.0));
127                 }
128                 catch (Exception e)
129                 {
130                         e.printStackTrace();
131                 }
132                 return world;
133         }
134
135         /**
136          * Returns a settings panel with "Number of Agents" and "Agent Sight"
137          * sliders
138          *
139          * @return A settings panel with "Number of Agents" and "Agent Sight"
140          *         sliders
141          */
142         protected JPanel getSettingsPanel()
143         {
144                 final JPanel settingsPanel = new JPanel();
145                 settingsPanel.setLayout(new BoxLayout(settingsPanel, BoxLayout.Y_AXIS));
146
147                 numAgentsLabel = new JLabel("Number of Agents: " + numAgents);
148                 numAgentsLabel.setAlignmentX(java.awt.Component.CENTER_ALIGNMENT);
149                 settingsPanel.add(numAgentsLabel);
150
151                 final Hashtable numAgentsLabels = new Hashtable();
152                 numAgentsLabels.put(new Integer(MIN_NUM_AGENTS), new JLabel(Integer.toString(MIN_NUM_AGENTS)));
153                 numAgentsLabels.put(new Integer(MAX_NUM_AGENTS), new JLabel(Integer.toString(MAX_NUM_AGENTS)));
154
155                 numAgentsSlider = new JSlider(MIN_NUM_AGENTS, MAX_NUM_AGENTS, numAgents);
156                 numAgentsSlider.setLabelTable(numAgentsLabels);
157                 numAgentsSlider.setPaintLabels(true);
158                 numAgentsSlider.addChangeListener(new ChangeListener()
159                 {
160                         public void stateChanged(final ChangeEvent event)
161                         {
162                                 numAgentsChanged(event);
163                         }
164                 });
165                 settingsPanel.add(numAgentsSlider);
166
167                 agentSightLabel = new JLabel("Agent Sight: " + agentSight);
168                 agentSightLabel.setAlignmentX(java.awt.Component.CENTER_ALIGNMENT);
169                 settingsPanel.add(agentSightLabel);
170
171                 final Hashtable agentSightLabels = new Hashtable();
172                 agentSightLabels.put(new Integer(MIN_AGENT_SIGHT), new JLabel(Integer.toString(MIN_AGENT_SIGHT)));
173                 agentSightLabels.put(new Integer(MAX_AGENT_SIGHT), new JLabel(Integer.toString(MAX_AGENT_SIGHT)));
174
175                 agentSightSlider = new JSlider(MIN_AGENT_SIGHT, MAX_AGENT_SIGHT, agentSight);
176                 agentSightSlider.setLabelTable(agentSightLabels);
177                 agentSightSlider.setPaintLabels(true);
178                 agentSightSlider.addChangeListener(new ChangeListener()
179                 {
180                         public void stateChanged(final ChangeEvent event)
181                         {
182                                 agentSightChanged(event);
183                         }
184                 });
185                 settingsPanel.add(agentSightSlider);
186
187                 numNeighborsToFollowLabel = new JLabel("Number of Neighbors to Follow: " + numNeighborsToFollow);
188                 numNeighborsToFollowLabel.setAlignmentX(java.awt.Component.CENTER_ALIGNMENT);
189                 settingsPanel.add(numNeighborsToFollowLabel);
190
191                 final Hashtable numNeighborsToFollowLabels = new Hashtable();
192                 numNeighborsToFollowLabels.put(new Integer(MIN_NUM_NEIGHBORS_TO_FOLLOW), new JLabel(Integer.toString(MIN_NUM_NEIGHBORS_TO_FOLLOW)));
193                 numNeighborsToFollowLabels.put(new Integer(MAX_NUM_NEIGHBORS_TO_FOLLOW), new JLabel(Integer.toString(MAX_NUM_NEIGHBORS_TO_FOLLOW)));
194
195                 numNeighborsToFollowSlider = new JSlider(MIN_NUM_NEIGHBORS_TO_FOLLOW, MAX_NUM_NEIGHBORS_TO_FOLLOW, numNeighborsToFollow);
196                 numNeighborsToFollowSlider.setLabelTable(numNeighborsToFollowLabels);
197                 numNeighborsToFollowSlider.setPaintLabels(true);
198                 numNeighborsToFollowSlider.addChangeListener(new ChangeListener()
199                 {
200                         public void stateChanged(final ChangeEvent event)
201                         {
202                                 numNeighborsToFollowChanged(event);
203                         }
204                 });
205                 settingsPanel.add(numNeighborsToFollowSlider);
206
207                 randomizationFactorLabel = new JLabel("Randomization Factor: " + PERCENT_FORMAT.format(randomizationFactor / 100.0));
208                 randomizationFactorLabel.setAlignmentX(java.awt.Component.CENTER_ALIGNMENT);
209                 settingsPanel.add(randomizationFactorLabel);
210
211                 final Hashtable randomizationFactorLabels = new Hashtable();
212                 randomizationFactorLabels.put(new Integer(MIN_RANDOMIZATION_FACTOR), new JLabel(PERCENT_FORMAT.format(MIN_RANDOMIZATION_FACTOR / 100.0)));
213                 randomizationFactorLabels.put(new Integer(MAX_RANDOMIZATION_FACTOR), new JLabel(PERCENT_FORMAT.format(MAX_RANDOMIZATION_FACTOR / 100.0)));
214
215                 randomizationFactorSlider = new JSlider(MIN_RANDOMIZATION_FACTOR, MAX_RANDOMIZATION_FACTOR, randomizationFactor);
216                 randomizationFactorSlider.setLabelTable(randomizationFactorLabels);
217                 randomizationFactorSlider.setPaintLabels(true);
218                 randomizationFactorSlider.addChangeListener(new ChangeListener()
219                 {
220                         public void stateChanged(final ChangeEvent event)
221                         {
222                                 randomizationFactorChanged(event);
223                         }
224                 });
225                 settingsPanel.add(randomizationFactorSlider);
226
227                 chooseNeighborsByProximityCheckBox = new JCheckBox("Choose Neighbors by Proximity");
228                 chooseNeighborsByProximityCheckBox.setSelected(chooseNeighborsByProximity);
229                 chooseNeighborsByProximityCheckBox.setAlignmentX(java.awt.Component.CENTER_ALIGNMENT);
230                 chooseNeighborsByProximityCheckBox.addActionListener(new java.awt.event.ActionListener()
231                 {
232                         public void actionPerformed(final ActionEvent event)
233                         {
234                                 chooseNeighborsByProximityClicked(event);
235                         }
236                 });
237                 settingsPanel.add(chooseNeighborsByProximityCheckBox);
238
239                 final JLabel changes = new JLabel("Changes will take");
240                 changes.setAlignmentX(java.awt.Component.CENTER_ALIGNMENT);
241                 final JLabel takeEffect = new JLabel("effect at next reset");
242                 takeEffect.setAlignmentX(java.awt.Component.CENTER_ALIGNMENT);
243                 settingsPanel.add(changes);
244                 settingsPanel.add(takeEffect);
245                 return settingsPanel;
246         }
247
248         /**
249          * The method invoked when the "Number of Agents" slider changes
250          *
251          * @param event The change event
252          */
253         public void numAgentsChanged(final ChangeEvent event)
254         {
255                 numAgents = numAgentsSlider.getValue();
256                 numAgentsLabel.setText("Number of Agents: " + numAgents);
257         }
258
259         /**
260          * The method invoked when the "Agent Sight" slider changes
261          *
262          * @param event The change event
263          */
264         public void agentSightChanged(final ChangeEvent event)
265         {
266                 agentSight = agentSightSlider.getValue();
267                 agentSightLabel.setText("Agent Sight: " + agentSight);
268         }
269
270         /**
271          * The method invoked when the "Number of Neighbors to Follow" slider changes
272          *
273          * @param event The change event
274          */
275         public void numNeighborsToFollowChanged(final ChangeEvent event)
276         {
277                 numNeighborsToFollow = numNeighborsToFollowSlider.getValue();
278                 numNeighborsToFollowLabel.setText("Number of Neighbors to Follow: " + numNeighborsToFollow);
279         }
280
281         /**
282          * The method invoked when the "Randomization Factor" slider changes
283          *
284          * @param event The change event
285          */
286         public void randomizationFactorChanged(final ChangeEvent event)
287         {
288                 randomizationFactor = randomizationFactorSlider.getValue();
289                 randomizationFactorLabel.setText("Randomization Factor: " + PERCENT_FORMAT.format(randomizationFactor / 100.0));
290         }
291
292         /**
293          * The method invoked when the user selects or deselects the "Choose Neighbors
294          * by Proximity" check box
295          *
296          * @param event The action event
297          */
298         public void chooseNeighborsByProximityClicked(final ActionEvent event)
299         {
300                 chooseNeighborsByProximity = chooseNeighborsByProximityCheckBox.isSelected();
301         }
302 }