1 package org.uncommons.watchmaker.examples.travellingsalesman;
17
18 import java.awt.BorderLayout;
19 import java.awt.event.ActionEvent;
20 import java.awt.event.ActionListener;
21 import java.util.Collection;
22 import java.util.List;
23 import javax.swing.JApplet;
24 import javax.swing.JOptionPane;
25 import javax.swing.JPanel;
26 import org.uncommons.swing.SwingBackgroundTask;
27 import org.uncommons.watchmaker.framework.FitnessEvaluator;
28
29
34 public final class TravellingSalesmanApplet extends JApplet
35 {
36 private final ItineraryPanel itineraryPanel;
37 private final StrategyPanel strategyPanel;
38 private final ExecutionPanel executionPanel;
39
40 private final FitnessEvaluator<List<String>> evaluator;
41
42
43
46 public TravellingSalesmanApplet()
47 {
48 DistanceLookup distances = new EuropeanDistanceLookup();
49 evaluator = new RouteEvaluator(distances);
50 itineraryPanel = new ItineraryPanel(distances.getKnownCities());
51 strategyPanel = new StrategyPanel(distances);
52 executionPanel = new ExecutionPanel();
53 add(itineraryPanel, BorderLayout.WEST);
54 JPanel innerPanel = new JPanel(new BorderLayout());
55 innerPanel.add(strategyPanel, BorderLayout.NORTH);
56 innerPanel.add(executionPanel, BorderLayout.CENTER);
57 add(innerPanel, BorderLayout.CENTER);
58
59 executionPanel.addActionListener(new ActionListener()
60 {
61 public void actionPerformed(ActionEvent actionEvent)
62 {
63 Collection<String> cities = itineraryPanel.getSelectedCities();
64 if (cities.size() < 4)
65 {
66 JOptionPane.showMessageDialog(TravellingSalesmanApplet.this,
67 "Itinerary must include at least 4 cities.",
68 "Error",
69 JOptionPane.ERROR_MESSAGE);
70 }
71 else
72 {
73 try
74 {
75 setEnabled(false);
76 createTask(cities).execute();
77 }
78 catch (IllegalArgumentException ex)
79 {
80 JOptionPane.showMessageDialog(TravellingSalesmanApplet.this,
81 ex.getMessage(),
82 "Error",
83 JOptionPane.ERROR_MESSAGE);
84 setEnabled(true);
85 }
86 }
87 }
88 });
89 validate();
90 }
91
92
93
100 private SwingBackgroundTask<List<String>> createTask(final Collection<String> cities)
101 {
102 final TravellingSalesmanStrategy strategy = strategyPanel.getStrategy();
103 return new SwingBackgroundTask<List<String>>()
104 {
105 private long elapsedTime = 0;
106
107 protected List<String> performTask()
108 {
109 long startTime = System.currentTimeMillis();
110 List<String> result = strategy.calculateShortestRoute(cities, executionPanel);
111 elapsedTime = System.currentTimeMillis() - startTime;
112 return result;
113 }
114
115 protected void postProcessing(List<String> result)
116 {
117 executionPanel.appendOutput(createResultString(strategy.getDescription(),
118 result,
119 evaluator.getFitness(result, null),
120 elapsedTime));
121 setEnabled(true);
122 }
123 };
124 }
125
126
127
130 private String createResultString(String strategyDescription,
131 List<String> shortestRoute,
132 double distance,
133 long elapsedTime)
134 {
135 StringBuilder buffer = new StringBuilder();
136 buffer.append('[');
137 buffer.append(strategyDescription);
138 buffer.append("]\n");
139 buffer.append("ROUTE: ");
140 for (String s : shortestRoute)
141 {
142 buffer.append(s);
143 buffer.append(" -> ");
144 }
145 buffer.append(shortestRoute.get(0));
146 buffer.append('\n');
147 buffer.append("TOTAL DISTANCE: ");
148 buffer.append(String.valueOf(distance));
149 buffer.append("km\n");
150 buffer.append("(Search Time: ");
151 double seconds = (double) elapsedTime / 1000;
152 buffer.append(String.valueOf(seconds));
153 buffer.append(" seconds)\n\n");
154 return buffer.toString();
155 }
156
157
158
162 @Override
163 public void setEnabled(boolean b)
164 {
165 itineraryPanel.setEnabled(b);
166 strategyPanel.setEnabled(b);
167 executionPanel.setEnabled(b);
168 super.setEnabled(b);
169 }
170 }
171