Mercurial > hg > accesspd
comparison java/src/uk/ac/qmul/eecs/ccmi/main/DiagramEditorApp.java @ 0:78b7fc5391a2
first import, outcome of NIME 2014 hackaton
author | Fiore Martin <f.martin@qmul.ac.uk> |
---|---|
date | Tue, 08 Jul 2014 16:28:59 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:78b7fc5391a2 |
---|---|
1 /* | |
2 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool | |
3 | |
4 Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) | |
5 | |
6 This program is free software: you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation, either version 3 of the License, or | |
9 (at your option) any later version. | |
10 | |
11 This program is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 */ | |
19 | |
20 package uk.ac.qmul.eecs.ccmi.main; | |
21 | |
22 import java.io.File; | |
23 import java.io.FilenameFilter; | |
24 import java.io.IOException; | |
25 import java.lang.reflect.InvocationTargetException; | |
26 import java.text.MessageFormat; | |
27 import java.util.ResourceBundle; | |
28 | |
29 import javax.swing.JOptionPane; | |
30 import javax.swing.SwingUtilities; | |
31 import javax.swing.UIManager; | |
32 | |
33 import uk.ac.qmul.eecs.ccmi.gui.Diagram; | |
34 import uk.ac.qmul.eecs.ccmi.gui.EditorFrame; | |
35 import uk.ac.qmul.eecs.ccmi.gui.HapticKindle; | |
36 import uk.ac.qmul.eecs.ccmi.gui.SpeechOptionPane; | |
37 import uk.ac.qmul.eecs.ccmi.gui.TemplateEditor; | |
38 import uk.ac.qmul.eecs.ccmi.haptics.Haptics; | |
39 import uk.ac.qmul.eecs.ccmi.haptics.HapticsFactory; | |
40 import uk.ac.qmul.eecs.ccmi.simpletemplate.SimpleTemplateEditor; | |
41 import uk.ac.qmul.eecs.ccmi.sound.SoundFactory; | |
42 import uk.ac.qmul.eecs.ccmi.speech.NarratorFactory; | |
43 import uk.ac.qmul.eecs.ccmi.utils.CCmIUncaughtExceptionHandler; | |
44 import uk.ac.qmul.eecs.ccmi.utils.InteractionLog; | |
45 import uk.ac.qmul.eecs.ccmi.utils.PreferencesService; | |
46 import uk.ac.qmul.eecs.ccmi.utils.ResourceFileWriter; | |
47 | |
48 /** | |
49 * | |
50 * The application class with the main method. The main performs | |
51 * the start up initialization and then displays the graphical user interface. | |
52 * | |
53 */ | |
54 public class DiagramEditorApp implements Runnable { | |
55 | |
56 /* initialize all the non gui resources */ | |
57 private void init() throws IOException { | |
58 Thread.setDefaultUncaughtExceptionHandler(new CCmIUncaughtExceptionHandler()); | |
59 final ResourceBundle resources = ResourceBundle.getBundle(DiagramEditorApp.class.getName()); | |
60 /* create the home directory if it does not exist and store the path into the preferences */ | |
61 PreferencesService preferences = PreferencesService.getInstance(); | |
62 String homeDirPath = preferences.get("home", null); | |
63 if(homeDirPath == null){ | |
64 homeDirPath = new StringBuilder(System.getProperty("user.home")).append(System.getProperty("file.separator")).append(resources.getString("dir.home")).toString(); | |
65 preferences.put("home", homeDirPath); | |
66 } | |
67 File homeDir = new File(homeDirPath); | |
68 mkDir(homeDir, resources); | |
69 | |
70 File backupDir = new File(homeDir,resources.getString("dir.backups")); | |
71 mkDir(backupDir, resources); | |
72 backupDirPath = backupDir.getAbsolutePath(); | |
73 | |
74 /* create the templates directory into the home directory */ | |
75 File templateDir = new File(homeDir,resources.getString("dir.templates")); | |
76 mkDir(templateDir,resources); | |
77 | |
78 /* create the images directory into the home directory */ | |
79 File imagesDir = new File(homeDir,resources.getString("dir.images")); | |
80 mkDir(imagesDir,resources); | |
81 preferences.put("dir.images", imagesDir.getAbsolutePath()); | |
82 | |
83 /* create the diagrams dir into the home directory */ | |
84 File diagramDir = new File(homeDir,resources.getString("dir.diagrams")); | |
85 mkDir(diagramDir,resources); | |
86 preferences.put("dir.diagrams", diagramDir.getAbsolutePath()); | |
87 | |
88 /* create the libs directory into he home directory */ | |
89 File libsDir = new File(homeDir,resources.getString("dir.libs")); | |
90 mkDir(libsDir,resources); | |
91 preferences.put("dir.libs", libsDir.getAbsolutePath()); | |
92 | |
93 /* write the template files included in the software in the template dir, if they don't exist yet */ | |
94 ResourceFileWriter resourceWriter = new ResourceFileWriter(getClass().getResource("UML Diagram.xml")); | |
95 resourceWriter.writeOnDisk(templateDir.getAbsolutePath(),"UML Diagram.xml"); | |
96 resourceWriter.setResource(getClass().getResource("Tube.xml")); | |
97 resourceWriter.writeOnDisk(templateDir.getAbsolutePath(),"Tube.xml"); | |
98 resourceWriter.setResource(getClass().getResource("Organization Chart.xml")); | |
99 resourceWriter.writeOnDisk(templateDir.getAbsolutePath(),"Organization Chart.xml"); | |
100 | |
101 /* read the template files into an array to pass to the EditorFrame instance */ | |
102 FilenameFilter filter = new FilenameFilter() { | |
103 @Override | |
104 public boolean accept(File f, String name) { | |
105 return (name.endsWith(resources.getString("template.extension"))); | |
106 } | |
107 }; | |
108 templateFiles = templateDir.listFiles(filter); | |
109 File logDir = new File(homeDir,resources.getString("dir.log")); | |
110 mkDir(logDir,resources); | |
111 preferences.put("dir.log", logDir.getAbsolutePath()); | |
112 | |
113 String enableLog = preferences.get("enable_log", "false"); | |
114 if(Boolean.parseBoolean(enableLog)){ | |
115 try{ | |
116 InteractionLog.enable(logDir.getAbsolutePath()); | |
117 InteractionLog.log("PROGRAM STARTED"); | |
118 }catch(IOException ioe){ | |
119 /* if logging was enabled, the possibility to log is considered inescapable */ | |
120 /* at launch time: do not allow the execution to continue any further */ | |
121 throw new RuntimeException(ioe); | |
122 } | |
123 } | |
124 | |
125 /* create sound, speech engines */ | |
126 NarratorFactory.createInstance(); | |
127 SoundFactory.createInstance(); | |
128 } | |
129 | |
130 /* loads haptic device. If the user is running the software for the first time * | |
131 * they're prompted with a dialog to select the device they want to use */ | |
132 private void initHaptics(){ | |
133 final PreferencesService preferences = PreferencesService.getInstance(); | |
134 if(!Boolean.parseBoolean(preferences.get("haptic_device.initialized", "false"))){ | |
135 try { | |
136 SwingUtilities.invokeAndWait(new Runnable(){ | |
137 @Override | |
138 public void run() { | |
139 try { | |
140 UIManager.setLookAndFeel( | |
141 UIManager.getSystemLookAndFeelClassName()); | |
142 }catch(Exception e){/* nevermind */} | |
143 | |
144 String [] hapticDevices = { | |
145 HapticsFactory.PHANTOM_ID, | |
146 HapticsFactory.FALCON_ID, | |
147 HapticsFactory.TABLET_ID}; | |
148 String selection = (String)SpeechOptionPane.showSelectionDialog(null, | |
149 ResourceBundle.getBundle(DiagramEditorApp.class.getName()).getString("haptics_init.welcome"), | |
150 hapticDevices, | |
151 hapticDevices[2]); | |
152 if(selection == null) | |
153 System.exit(0); | |
154 preferences.put("haptic_device", selection); | |
155 preferences.put("haptic_device.initialized", "true"); | |
156 } | |
157 }); | |
158 }catch(InvocationTargetException ite){ | |
159 throw new RuntimeException(ite); | |
160 }catch(InterruptedException ie){ | |
161 throw new RuntimeException(ie); | |
162 } | |
163 } | |
164 | |
165 /* creates the Haptics instance */ | |
166 HapticsFactory.createInstance(new HapticKindle()); | |
167 haptics = HapticsFactory.getInstance(); | |
168 if(haptics.isAlive()) | |
169 NarratorFactory.getInstance().speakWholeText("Haptic device successfully initialized"); | |
170 } | |
171 | |
172 /* return true if the directory was created, false if it existed before */ | |
173 private boolean mkDir(File dir,ResourceBundle resources) throws IOException{ | |
174 boolean created = dir.mkdir(); | |
175 if(!dir.exists()) | |
176 throw new IOException(MessageFormat.format( | |
177 resources.getString("dir.error_msg"), | |
178 dir.getAbsolutePath()) | |
179 ); | |
180 return created; | |
181 } | |
182 | |
183 /** | |
184 * build up the GUI and display it | |
185 */ | |
186 @Override | |
187 public void run() { | |
188 editorFrame = new EditorFrame(haptics,getTemplateFiles(),backupDirPath,getTemplateEditors(),getDiagrams()); | |
189 } | |
190 | |
191 /** | |
192 * Provides template editors to create own templates using the diagram editor. | |
193 * | |
194 * Subclasses who don't want any template editor to appear in the diagram | |
195 * can just return an empty array. Returning {@code null} will throw an exception. | |
196 * | |
197 * @return an array of template editors | |
198 */ | |
199 protected TemplateEditor[] getTemplateEditors(){ | |
200 TemplateEditor[] templateEditors = new TemplateEditor[1]; | |
201 templateEditors[0] = new SimpleTemplateEditor(); | |
202 return templateEditors; | |
203 } | |
204 | |
205 /** | |
206 * Returns the template files detected in the ccmi_editor_data/templates directory. | |
207 * | |
208 * Returning {@code null} will throw an exception. | |
209 * | |
210 * @return an array of (xml) Files containing a template | |
211 */ | |
212 protected File[] getTemplateFiles(){ | |
213 return templateFiles; | |
214 } | |
215 | |
216 /** | |
217 * Returns an empty list. This method can be overwritten by subclasses to | |
218 * provide their own custom diagrams. Such diagrams will appear in the menu. | |
219 * | |
220 * Returning {@code null} will throw an exception. | |
221 * | |
222 * @return an array of diagram templates. The array is empty in this implementation. | |
223 */ | |
224 protected Diagram[] getDiagrams(){ | |
225 return new Diagram[0]; | |
226 } | |
227 | |
228 /** | |
229 * The main function | |
230 * @param args this software accepts no args from the command line | |
231 */ | |
232 public static void main(String[] args){ | |
233 DiagramEditorApp application = new DiagramEditorApp(); | |
234 mainImplementation(application); | |
235 } | |
236 | |
237 | |
238 /** | |
239 * Implementation of the main body. It can be used to run the program | |
240 * using a subclass of {@code DiagramEditorApp}, providing it's own | |
241 * diagram templates | |
242 * | |
243 * @param application the diagram editor application to execute | |
244 */ | |
245 public final static void mainImplementation(DiagramEditorApp application) { | |
246 try{ | |
247 application.init(); | |
248 } catch (IOException e) { | |
249 final String msg = e.getLocalizedMessage(); | |
250 try { | |
251 SwingUtilities.invokeAndWait(new Runnable(){ | |
252 @Override | |
253 public void run(){ | |
254 try { | |
255 UIManager.setLookAndFeel( | |
256 UIManager.getSystemLookAndFeelClassName()); | |
257 }catch(Exception e){/* nevermind */} | |
258 JOptionPane.showMessageDialog(null, msg); | |
259 } | |
260 }); | |
261 } catch (InterruptedException ex) { | |
262 throw new RuntimeException(ex); | |
263 } catch (InvocationTargetException ex) { | |
264 throw new RuntimeException(ex); | |
265 } | |
266 System.exit(-1); | |
267 } | |
268 | |
269 application.initHaptics(); | |
270 | |
271 /* start the application */ | |
272 try { | |
273 SwingUtilities.invokeAndWait(application); | |
274 } catch (InvocationTargetException ex) { | |
275 throw new RuntimeException(ex); | |
276 } catch (InterruptedException ex) { | |
277 throw new RuntimeException(ex); | |
278 } | |
279 } | |
280 | |
281 /** | |
282 * Returns the reference to the unique {@code EditorFrame} instance of the program. | |
283 * The main GUI class. | |
284 * | |
285 * @return an reference to {@code EditorFrame} | |
286 */ | |
287 public static EditorFrame getFrame(){ | |
288 return editorFrame; | |
289 } | |
290 | |
291 private static EditorFrame editorFrame; | |
292 Haptics haptics; | |
293 File[] templateFiles; | |
294 TemplateEditor[] templateCreators; | |
295 String backupDirPath; | |
296 } | |
297 |