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