001 package org.LiveGraph.gui;
002
003 import java.util.List;
004
005 import javax.swing.JFrame;
006 import javax.swing.JMenuBar;
007 import javax.swing.JOptionPane;
008 import javax.swing.JPanel;
009
010 import org.LiveGraph.LiveGraph;
011 import org.LiveGraph.dataCache.DataCache;
012 import org.LiveGraph.events.Event;
013 import org.LiveGraph.events.EventAnnotation;
014 import org.LiveGraph.events.EventProcessingException;
015 import org.LiveGraph.events.EventProducer;
016 import org.LiveGraph.events.EventType;
017 import org.LiveGraph.gui.dfs.DataFileSettingsPanel;
018 import org.LiveGraph.gui.dfs.DataFileSettingsWindow;
019 import org.LiveGraph.gui.dss.SeriesSettingsPanel;
020 import org.LiveGraph.gui.dss.SeriesSettingsWindow;
021 import org.LiveGraph.gui.gs.GraphSettingsPanel;
022 import org.LiveGraph.gui.gs.GraphSettingsWindow;
023 import org.LiveGraph.gui.msg.MessagePanel;
024 import org.LiveGraph.gui.msg.MessageWindow;
025 import org.LiveGraph.gui.plot.PlotPanel;
026 import org.LiveGraph.gui.plot.PlotWindow;
027 import org.LiveGraph.plot.Plotter;
028
029 import com.softnetConsult.utils.exceptions.ThrowableTools;
030
031 import static org.LiveGraph.gui.GUIEvent.*;
032
033
034 public class GUIManager implements EventProducer {
035
036 /**
037 * The data cache that is used to provide data series information
038 * to new panels and also when constructing new {@code Plotter} objects
039 * required for creating new {@code PlotPanel}s.
040 */
041 private DataCache dataCache = null;
042
043
044 /**
045 * Constructor doesn't do much.
046 */
047 public GUIManager() { }
048
049 /**
050 * Sets tha data cache that is used to provide data series information
051 * to new panels and also when constructing new {@code Plotter} objects
052 * required for creating new {@code PlotPanel}s.
053 * @param cache
054 */
055 public void setDataCache(DataCache cache) {
056 dataCache = cache;
057 }
058
059 /**
060 * Creates a new fully registered instance of a main menu bar.
061 * @return a new main menu bar.
062 */
063 public JMenuBar createMainMenuBar() {
064 MainMenuBar menuBar = new MainMenuBar();
065 LiveGraph.application().eventManager().registerListener(menuBar);
066 return menuBar;
067 }
068
069 public JPanel createDataFileSettingsPanel() {
070 DataFileSettingsPanel panel = new DataFileSettingsPanel();
071 LiveGraph.application().eventManager().registerListener(panel);
072 return panel;
073 }
074
075 public JPanel createGraphSettingsPanel() {
076 GraphSettingsPanel panel = new GraphSettingsPanel();
077 if (null != dataCache) {
078 synchronized(dataCache) {
079 panel.setSeriesLabels(dataCache.iterateDataSeriesLabels());
080 }
081 }
082 LiveGraph.application().eventManager().registerListener(panel);
083 return panel;
084 }
085
086 public JPanel createSeriesSettingsPanel() {
087 SeriesSettingsPanel panel = new SeriesSettingsPanel();
088 if (null != dataCache) {
089 synchronized(dataCache) {
090 panel.setSeriesLabels(dataCache.iterateDataSeriesLabels());
091 }
092 }
093 LiveGraph.application().eventManager().registerListener(panel);
094 return panel;
095 }
096
097 public JPanel createMessagePanel() {
098 MessagePanel panel = new MessagePanel();
099 LiveGraph.application().eventManager().registerListener(panel);
100 return panel;
101 }
102
103 public JPanel createPlotPanel() {
104
105 Plotter plotter = new Plotter(dataCache);
106 LiveGraph.application().eventManager().registerListener(plotter);
107
108 PlotPanel panel = new PlotPanel(plotter);
109 if (null != dataCache) {
110 synchronized(dataCache) {
111 panel.setSeriesLabels(dataCache.iterateDataSeriesLabels());
112 }
113 }
114 LiveGraph.application().eventManager().registerListener(panel);
115 return panel;
116 }
117
118 /**
119 * Create a data file settings window and set-up its communication with other objects.
120 * @return data file settings window.
121 */
122 public JFrame createDataFileSettingsWindow() {
123 DataFileSettingsWindow win = new DataFileSettingsWindow();
124 LiveGraph.application().eventManager().registerListener(win);
125 JPanel panel = createDataFileSettingsPanel();
126 win.getContentPane().add(panel);
127 return win;
128 }
129
130 /**
131 * Create a graph settings window and set-up its communication with other objects.
132 * @return graph settings window.
133 */
134 public JFrame createGraphSettingsWindow() {
135 GraphSettingsWindow win = new GraphSettingsWindow();
136 LiveGraph.application().eventManager().registerListener(win);
137 JPanel panel = createGraphSettingsPanel();
138 win.getContentPane().add(panel);
139 return win;
140 }
141
142 /**
143 * Create a data series settings window and set-up its communication with other objects.
144 * @return data series settings window.
145 */
146 public JFrame createSeriesSettingsWindow() {
147 SeriesSettingsWindow win = new SeriesSettingsWindow();
148 LiveGraph.application().eventManager().registerListener(win);
149 JPanel panel = createSeriesSettingsPanel();
150 win.getContentPane().add(panel);
151 return win;
152 }
153
154 /**
155 * Create a message window and set-up its communication with other objects.
156 * @return data series settings window.
157 */
158 public JFrame createMessageWindow() {
159 MessageWindow win = new MessageWindow();
160 LiveGraph.application().eventManager().registerListener(win);
161 JPanel panel = createMessagePanel();
162 win.getContentPane().add(panel);
163 return win;
164 }
165
166 /**
167 * Create a plot window and set-up its communication with other objects.
168 *
169 * @return plot window.
170 */
171 public JFrame createPlotWindow() {
172 PlotWindow win = new PlotWindow();
173 win.setJMenuBar(createMainMenuBar());
174 LiveGraph.application().eventManager().registerListener(win);
175 JPanel panel = createPlotPanel();
176 win.getContentPane().add(panel);
177 return win;
178 }
179
180
181 /**
182 * Displays or hides the message window.
183 *
184 * @param state Whether to display ({@code true}) or to hide ({@code false}).
185 */
186 public void setDisplayMessageWindows(boolean state) {
187 Event<GUIEvent> event = new Event<GUIEvent>(this, GUIEvent.class, GUI_MessagesDisplayStateChanged,
188 state);
189 LiveGraph.application().eventManager().raiseEvent(event);
190 }
191
192 /**
193 * Displays or hides the data file settings window.
194 *
195 * @param state Whether to display ({@code true}) or to hide ({@code false}).
196 */
197 public void setDisplayDataFileSettingsWindows(boolean state) {
198 Event<GUIEvent> event = new Event<GUIEvent>(this, GUIEvent.class, GUI_DataFileSettingsDisplayStateChanged,
199 state);
200 LiveGraph.application().eventManager().raiseEvent(event);
201 }
202
203 /**
204 * Displays or hides the graph settings window.
205 *
206 * @param state Whether to display ({@code true}) or to hide ({@code false}).
207 */
208 public void setDisplayGraphSettingsWindows(boolean state) {
209 Event<GUIEvent> event = new Event<GUIEvent>(this, GUIEvent.class, GUI_GraphSettingsDisplayStateChanged,
210 state);
211 LiveGraph.application().eventManager().raiseEvent(event);
212 }
213
214 /**
215 * Displays or hides the data series settings window.
216 *
217 * @param state Whether to display ({@code true}) or to hide ({@code false}).
218 */
219 public void setDisplaySeriesSettingsWindows(boolean state) {
220 Event<GUIEvent> event = new Event<GUIEvent>(this, GUIEvent.class, GUI_DataSeriesSettingsDisplayStateChanged,
221 state);
222 LiveGraph.application().eventManager().raiseEvent(event);
223 }
224
225 /**
226 * Displays or hides the plot window.
227 *
228 * @param state Whether to display ({@code true}) or to hide ({@code false}).
229 */
230 public void setDisplayPlotWindows(boolean state) {
231 Event<GUIEvent> event = new Event<GUIEvent>(this, GUIEvent.class, GUI_PlotDisplayStateChanged,
232 state);
233 LiveGraph.application().eventManager().raiseEvent(event);
234 }
235
236 /**
237 * Raises an event to inform listeners that an info message should be displayed.
238 *
239 * @param o The message.
240 */
241 public void logInfoLn(Object o) {
242 String s = (null == o ? "null" : o.toString());
243 Event<GUIEvent> event = new Event<GUIEvent>(this, GUIEvent.class, GUI_LogMessageInfo, s);
244 LiveGraph.application().eventManager().raiseEvent(event);
245 }
246
247 /**
248 * Raises an event to inform listeners that an error message should be displayed.
249 *
250 * @param o The message.
251 */
252 public void logErrorLn(Object o) {
253 try {
254 String s = (null == o ? "null" : o.toString());
255 Event<GUIEvent> event = new Event<GUIEvent>(this, GUIEvent.class, GUI_LogMessageError, s);
256 LiveGraph.application().eventManager().raiseEvent(event);
257 } catch (Throwable ex) {
258 logErrorLnModal2(o, ex);
259 }
260 }
261
262 public void logErrorLnModal(Object o) {
263
264 String msg = (null == o ? "null" : o.toString());
265 System.err.println(msg);
266 JOptionPane.showMessageDialog(null, msg, "LiveGraph error", JOptionPane.ERROR_MESSAGE);
267 }
268
269 private void logErrorLnModal2(Object o, Throwable ex) {
270
271 String s = String.format("LiveGraph was going to display an error message,%n" +
272 "but another error occured during the display process.%n%n" +
273 "The original error message was:%n" +
274 "%s%n%n" +
275 "The error that occured during display is:%n" +
276 "%s%n",
277 (null == o ? "null" : o.toString()),
278 ThrowableTools.stackTraceToString(ex));
279
280 logErrorLnModal(s);
281 }
282
283 /**
284 * Raises an event to inform listeners that a success message should be displayed.
285 *
286 * @param o The message.
287 */
288 public void logSuccessLn(Object o) {
289 String s = (null == o ? "null" : o.toString());
290 Event<GUIEvent> event = new Event<GUIEvent>(this, GUIEvent.class, GUI_LogMessageSuccess, s);
291 LiveGraph.application().eventManager().raiseEvent(event);
292 }
293
294 /**
295 * Notifies the listeners about the highlighted series.
296 *
297 * @param hlSeries highlighted series indices.
298 */
299 public void dataSeriesHighlighted(List<Integer> hlSeries) {
300
301 Event<GUIEvent> event = new Event<GUIEvent>(this, GUIEvent.class, GUIEvent.GUI_DataSeriesHighlighted,
302 hlSeries);
303 LiveGraph.application().eventManager().raiseEvent(event);
304 }
305
306 /**
307 * Raises an event that requests all listening GUI components to call their {@code dispose()} methods.
308 */
309 public void disposeAllGUI() {
310 Event<GUIEvent> event = new Event<GUIEvent>(this, GUIEvent.class, GUI_DisposeAll);
311 LiveGraph.application().eventManager().raiseEvent(event);
312 }
313
314 /**
315 * ...
316 *
317 * @param event ... .
318 */
319 public void eventProcessingFinished(Event<? extends EventType> event) {
320
321 if (event.getDomain() == GUIEvent.class) {
322 guiEventProcessingFinished(event.cast(GUIEvent.class));
323 return;
324 }
325 }
326
327 /**
328 * ...
329 *
330 * @param event ... .
331 */
332 public void guiEventProcessingFinished(Event<GUIEvent> event) {
333
334 switch(event.getType()) {
335
336 // Check whther an error message was actually logged:
337 case GUI_LogMessageError:
338 // Look for positive event annotations:
339 List<EventAnnotation> annotations = event.getAnnotations();
340 boolean ok = false;
341 for (EventAnnotation ann : annotations) {
342 Object info = ann.getInfo();
343 if (null != info && info instanceof Boolean) {
344 if (((Boolean) info).booleanValue()) {
345 ok = true;
346 break;
347 }
348 }
349 }
350 // If no positive event annotations found, display without raising an event:
351 if (!ok) {
352 logErrorLnModal(event.getInfoObject());
353 }
354 break;
355 default:
356 break;
357 }
358 }
359
360 /**
361 * ...
362 *
363 * @param event ...
364 * @param exception ...
365 * @return ...
366 */
367 public boolean eventProcessingException(Event<? extends EventType> event, EventProcessingException exception) {
368
369 if (event.getDomain() == GUIEvent.class) {
370 return guiEventProcessingException(event.cast(GUIEvent.class), exception);
371 }
372
373 return false;
374 }
375
376
377 public boolean guiEventProcessingException(Event<GUIEvent> event, EventProcessingException exception) {
378
379 switch(event.getType()) {
380
381 // If an exception occured while logging an error message, we have to display both, the
382 // original error message AND the occured exception without raisig further events:
383 case GUI_LogMessageError:
384 logErrorLnModal2(event.getInfoObject(), exception);
385 return true;
386
387 default:
388 return false;
389 }
390 }
391
392 } // public class GUIManager