OSDN Git Service

change mode name experimental mode'
[stigmata/stigmata.git] / src / main / java / jp / sourceforge / stigmata / ui / swing / StigmataFrame.java
1 package jp.sourceforge.stigmata.ui.swing;
2
3 /*
4  * $Id$
5  */
6
7 import java.awt.BorderLayout;
8 import java.awt.Image;
9 import java.awt.event.ActionEvent;
10 import java.awt.event.ActionListener;
11 import java.awt.event.WindowAdapter;
12 import java.awt.event.WindowEvent;
13 import java.io.BufferedReader;
14 import java.io.File;
15 import java.io.FileReader;
16 import java.io.IOException;
17 import java.io.PrintWriter;
18 import java.io.StringWriter;
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24
25 import javax.swing.ButtonGroup;
26 import javax.swing.JCheckBoxMenuItem;
27 import javax.swing.JFrame;
28 import javax.swing.JLabel;
29 import javax.swing.JMenu;
30 import javax.swing.JMenuBar;
31 import javax.swing.JMenuItem;
32 import javax.swing.JOptionPane;
33 import javax.swing.JPanel;
34 import javax.swing.JScrollPane;
35 import javax.swing.JSeparator;
36 import javax.swing.JTabbedPane;
37 import javax.swing.JTextArea;
38 import javax.swing.LookAndFeel;
39 import javax.swing.SwingUtilities;
40 import javax.swing.UIManager;
41 import javax.swing.WindowConstants;
42 import javax.swing.event.ChangeEvent;
43 import javax.swing.event.ChangeListener;
44 import javax.swing.filechooser.FileFilter;
45
46 import jp.sourceforge.stigmata.BirthmarkContext;
47 import jp.sourceforge.stigmata.BirthmarkElementClassNotFoundException;
48 import jp.sourceforge.stigmata.BirthmarkEngine;
49 import jp.sourceforge.stigmata.BirthmarkEnvironment;
50 import jp.sourceforge.stigmata.BirthmarkExtractionFailedException;
51 import jp.sourceforge.stigmata.BirthmarkSet;
52 import jp.sourceforge.stigmata.ComparisonPair;
53 import jp.sourceforge.stigmata.ComparisonResultSet;
54 import jp.sourceforge.stigmata.ExtractionResultSet;
55 import jp.sourceforge.stigmata.Main;
56 import jp.sourceforge.stigmata.Stigmata;
57 import jp.sourceforge.stigmata.StigmataCommand;
58 import jp.sourceforge.stigmata.command.StigmataCommandFactory;
59 import jp.sourceforge.stigmata.event.BirthmarkEngineAdapter;
60 import jp.sourceforge.stigmata.event.BirthmarkEngineEvent;
61 import jp.sourceforge.stigmata.event.WarningMessages;
62 import jp.sourceforge.stigmata.result.CertainPairComparisonResultSet;
63 import jp.sourceforge.stigmata.ui.swing.actions.AboutAction;
64 import jp.sourceforge.stigmata.ui.swing.actions.LicenseAction;
65 import jp.sourceforge.stigmata.ui.swing.actions.OpenSettingDirAction;
66 import jp.sourceforge.stigmata.ui.swing.graph.SimilarityDistributionGraphPane;
67 import jp.sourceforge.stigmata.ui.swing.mds.MdsViewerPane;
68 import jp.sourceforge.stigmata.ui.swing.tab.EditableTabbedPane;
69 import jp.sourceforge.stigmata.utils.Utility;
70 import jp.sourceforge.talisman.i18n.Messages;
71 import jp.sourceforge.talisman.i18n.ResourceNotFoundException;
72
73 import org.apache.commons.cli.ParseException;
74
75 /**
76  *
77  * @author Haruaki TAMADA
78  * @version $Revision$
79  */
80 public class StigmataFrame extends JFrame{
81     private static final long serialVersionUID = 92345543665342134L;
82
83     private Messages messages;
84     private JTabbedPane tabPane;
85     private JMenuItem closeTabMenu;
86     private JMenuItem saveMenu;
87     private JCheckBoxMenuItem experimentalMode;
88     private Stigmata stigmata;
89     private BirthmarkEnvironment environment;
90     private ControlPane control;
91     private FileIOManager fileio;
92     private Map<String, Integer> countmap = new HashMap<String, Integer>();
93
94     public StigmataFrame(){
95         this(Stigmata.getInstance());
96     }
97
98     public StigmataFrame(Stigmata stigmata){
99         this(stigmata, BirthmarkEnvironment.getDefaultEnvironment());
100     }
101
102     public StigmataFrame(Stigmata stigmata, BirthmarkEnvironment environment){
103         this.stigmata = stigmata;
104         this.environment = environment;
105         this.fileio = new FileIOManager(this, environment);
106         try{
107             this.messages = new Messages("resources.messages");
108         } catch(ResourceNotFoundException e){
109             throw new InternalError(e.getMessage());
110         }
111         Image iconImage = GUIUtility.getImage(getMessages(), "stigmata.icon");
112         if(iconImage != null){
113             setIconImage(iconImage);
114         }
115
116         stigmata.addBirthmarkEngineListener(new BirthmarkEngineAdapter(){
117             @Override
118             public void operationDone(BirthmarkEngineEvent e){
119                 showWarnings(e.getMessage());
120             }
121         });
122
123         initLayouts();
124     }
125
126     public Messages getMessages(){
127         return messages;
128     }
129
130     public boolean isNeedToSaveSettings(){
131         return saveMenu.isEnabled();
132     }
133
134     public void setNeedToSaveSettings(boolean flag){
135         saveMenu.setEnabled(flag);
136     }
137
138     public Stigmata getStigmata(){
139         return stigmata;
140     }
141
142     public BirthmarkEnvironment getEnvironment(){
143         return environment;
144     }
145
146     public File getCurrentDirectory(){
147         return fileio.getCurrentDirectory();
148     }
149
150     public void setCurrentDirectory(File file){
151         try{
152             fileio.setCurrentDirectory(file);
153         } catch(IllegalArgumentException e){
154             JOptionPane.showMessageDialog(
155                 this,
156                 getMessages().get("notdirectory.dialog.message", file.getName()),
157                 getMessages().get("notdirectory.dialog.title"),
158                 JOptionPane.ERROR_MESSAGE
159             );
160         } catch(Exception e){
161             showExceptionMessage(e);
162         }
163     }
164
165     public File[] openFiles(FileFilter[] filters, boolean multipleSelectable, boolean directorySelectable){
166         return fileio.openFiles(filters, multipleSelectable, directorySelectable);
167     }
168
169     /**
170      * Find file to open it.
171      */
172     public File getOpenFile(String[] exts, String desc){
173         return fileio.findFile(true, exts, desc);
174     }
175
176     /**
177      * Find file for storing data to it.
178      * Extension of found file is correct as selected extension.
179      */
180     public File getSaveFile(String[] exts, String desc){
181         return fileio.findFile(false, exts, desc);
182     }
183
184     public void addBirthmarkServiceListener(BirthmarkServiceListener listener){
185         control.addBirthmarkServiceListener(listener);
186     }
187
188     public void removeBirthmarkServiceListener(BirthmarkServiceListener listener){
189         control.removeBirthmarkServiceListener(listener);
190     }
191
192     public void compareDetails(BirthmarkSet target1, BirthmarkSet target2, BirthmarkContext context){
193         PairComparisonPane detail = new PairComparisonPane(
194             this, new ComparisonPair(target1, target2, context)
195         );
196         int compareDetail = getNextCount("compare_detail");
197
198         GUIUtility.addNewTab(getMessages(), "comparedetail", tabPane, detail,
199             new Object[] { new Integer(compareDetail), },
200             new Object[] {
201                 Utility.array2String(target1.getBirthmarkTypes()),
202                 target1.getName(),
203                 target2.getName(),
204             }, true
205         );
206     }
207
208     public void compareRoundRobin(String[] targetX, String[] targetY, 
209             BirthmarkContext context){
210         try{
211             BirthmarkEngine engine = getStigmata().createEngine(context.getEnvironment());
212             ExtractionResultSet ers = engine.extract(targetX, targetY, context);
213
214             RoundRobinComparisonResultPane compare = new RoundRobinComparisonResultPane(this, ers);
215             int compareCount = getNextCount("compare");
216             GUIUtility.addNewTab(
217                 getMessages(), "compare", tabPane, compare,
218                 new Object[] { new Integer(compareCount), },
219                 new Object[] {
220                     Utility.array2String(context.getBirthmarkTypes()),
221                     Utility.array2String(targetX),
222                     Utility.array2String(targetY),
223                 }, true
224             );
225         } catch(Throwable e){
226             showExceptionMessage(e);
227         }
228     }
229
230     public void compareRoundRobinFilter(String[] targetX, String[] targetY, 
231             BirthmarkContext context){
232         try{
233             BirthmarkEngine engine = getStigmata().createEngine(context.getEnvironment());
234
235             ExtractionResultSet ers = engine.extract(targetX, targetY, context);
236             ComparisonResultSet resultset = engine.compare(ers);
237             if(context.hasFilter()){
238                 resultset = engine.filter(resultset);
239             }
240             int compareCount = getNextCount("compare");
241             GUIUtility.addNewTab(
242                 getMessages(), "compare", tabPane, new PairComparisonResultSetPane(this, resultset),
243                 new Object[] { new Integer(compareCount), },
244                 new Object[] {
245                     Utility.array2String(context.getBirthmarkTypes()),
246                     Utility.array2String(targetX),
247                     Utility.array2String(targetY),
248                 }, true
249             );
250         } catch(Throwable e){
251             showExceptionMessage(e);
252         }
253     }
254
255     public void compareGuessedPair(String[] targetX, String[] targetY, BirthmarkContext context){
256         try{
257             BirthmarkEngine engine = getStigmata().createEngine(context.getEnvironment());
258             ExtractionResultSet extraction = engine.extract(targetX, targetY, context);
259             int comparePair = getNextCount("compare_pair");
260
261             ComparisonResultSet resultset = new CertainPairComparisonResultSet(extraction);
262             GUIUtility.addNewTab(
263                 getMessages(), "comparepair", tabPane,
264                 new PairComparisonResultSetPane(this, resultset),
265                 new Object[] { new Integer(comparePair), },
266                 new Object[] {
267                     Utility.array2String(context.getBirthmarkTypes()),
268                     Utility.array2String(targetX),
269                     Utility.array2String(targetY),
270                 }, true
271             );
272             tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
273         }catch(Throwable e){
274             showExceptionMessage(e);
275         }
276     }
277
278     public void compareSpecifiedPair(String[] targetX, String[] targetY, BirthmarkContext context){
279         File file = getOpenFile(
280             getMessages().getArray("comparemapping.extension"),
281             getMessages().get("comparemapping.description")
282         );
283
284         if(file != null){
285             Map<String, String> mapping = constructMapping(file);
286
287             try{
288                 BirthmarkEngine engine = getStigmata().createEngine(context.getEnvironment());
289                 context.setNameMappings(mapping);
290                 ComparisonResultSet crs = engine.compare(targetX, targetY, context);
291                 int comparePair = getNextCount("compare_pair");
292
293                 GUIUtility.addNewTab(
294                     getMessages(), "comparepair", tabPane,
295                     new PairComparisonResultSetPane(this, crs),
296                     new Object[] { new Integer(comparePair), },
297                     new Object[] {
298                         Utility.array2String(context.getBirthmarkTypes()),
299                         Utility.array2String(targetX),
300                         Utility.array2String(targetY),
301                     }, true
302                 );
303             }catch(Exception e){
304                 showExceptionMessage(e);
305             }
306         }
307     }
308
309     public void showComparisonResultSet(ComparisonResultSet resultset){
310         int comparePair = getNextCount("compare_pair");
311         GUIUtility.addNewTab(
312             getMessages(), "comparisonresultset", tabPane,
313             new PairComparisonResultSetPane(this, resultset),
314             new Object[] { new Integer(comparePair), }, null, true
315         );
316     }
317
318     public void showMdsGraph(BirthmarkSet[] set, BirthmarkContext context){
319         try{
320             MdsViewerPane panel = new MdsViewerPane(this, set, context);
321             int mappingGraphCount = getNextCount("mds_graph");
322             GUIUtility.addNewTab(
323                 getMessages(), "mappinggraph", tabPane, panel,
324                 new Object[] { new Integer(mappingGraphCount), }, null, true
325             );
326         } catch(Exception e){
327             showExceptionMessage(e);
328         }
329     }
330
331     public void showSimilarityDistributionGraph(Map<Integer, Integer> distributions){
332         SimilarityDistributionGraphPane graph = new SimilarityDistributionGraphPane(this, distributions);
333
334         int similarityGraphCount = getNextCount("similarity_graph");
335         GUIUtility.addNewTab(
336             getMessages(), "similaritygraph", tabPane, graph,
337             new Object[] { new Integer(similarityGraphCount), }, null, true
338         );
339     }
340
341     public void compareExtractionResult(ExtractionResultSet ers){
342         RoundRobinComparisonResultPane compare = new RoundRobinComparisonResultPane(this, ers);
343         int compareCount = getNextCount("compare");
344         GUIUtility.addNewTab(
345             getMessages(), "compare", tabPane, compare,
346             new Object[] { new Integer(compareCount), },
347             new Object[] {
348                 Utility.array2String(ers.getBirthmarkTypes()),
349                 Utility.array2String(new String[0]),
350                 Utility.array2String(new String[0]),
351             }, true
352         );
353     }
354
355     public void showExtractionResult(ExtractionResultSet ers){
356         int extractCount = getNextCount("extract");
357         BirthmarkExtractionResultPane viewer = new BirthmarkExtractionResultPane(this, ers);
358         GUIUtility.addNewTab(
359             getMessages(), "extract", tabPane, viewer,
360             new Object[] { new Integer(extractCount), },
361             new Object[] { Utility.array2String(ers.getBirthmarkTypes()), }, true
362         );
363     }
364
365     public void extract(String[] targetX, String[] targetY, BirthmarkContext context){
366         try{
367             BirthmarkEngine engine = getStigmata().createEngine(context.getEnvironment());
368             ExtractionResultSet ers = engine.extract(targetX, targetY, context);
369             showExtractionResult(ers);
370         }catch(Throwable e){
371             showExceptionMessage(e);
372         }
373     }
374
375     /**
376      * csv file to Map.
377      */
378     public Map<String, String> constructMapping(File file){
379         Map<String, String> mapping = new HashMap<String, String>();
380         BufferedReader in = null;
381         try{
382             in = new BufferedReader(new FileReader(file));
383             String line;
384             while((line = in.readLine()) != null){
385                 String[] tokens = line.split(", *");
386                 if(tokens.length >= 2){
387                     mapping.put(tokens[0], tokens[1]);
388                 }
389             }
390
391         }catch(Exception e){
392             showExceptionMessage(e);
393         }finally{
394             if(in != null){
395                 try{
396                     in.close();
397                 }catch(IOException e){
398                 }
399             }
400         }
401         return mapping;
402     }
403
404     private void reloadSettings(String[] args){
405         try{
406             setVisible(false);
407             dispose();
408             new Main(args);
409         } catch(ParseException e){
410         }
411     }
412
413     private void clearSettings(){
414         Utility.deleteDirectory(new File(BirthmarkEnvironment.getStigmataHome()));
415         reloadSettings(new String[] { "--reset-config", "gui", });
416     }
417
418     private void initLayouts(){
419         setTitle(getMessages().get("stigmata.frame.title"));
420         initComponents();
421
422         GUIUtility.addNewTab(getMessages(), "control", tabPane, control = new ControlPane(this), null, null, false);
423         control.inititalize();
424         tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
425
426         setNeedToSaveSettings(false);
427         setSize(900, 600);
428     }
429
430     private void showWarnings(WarningMessages warnings){
431         if(warnings.getWarningCount() > 0){
432             StringBuilder sb = new StringBuilder("<html><body><dl>");
433             for(Iterator<Exception> i = warnings.exceptions(); i.hasNext(); ){
434                 Exception e = i.next();
435                 sb.append("<dt>").append(e.getClass().getName()).append("</dt>");
436                 sb.append("<dd>").append(e.getMessage()).append("</dd>");
437                 sb.append("<dd>").append(warnings.getString(e)).append("</dd>");
438             }
439             sb.append("</dl></body></html>");
440
441             JOptionPane.showMessageDialog(
442                 this, new String(sb), getMessages().get("warning.dialog.title"),
443                 JOptionPane.WARNING_MESSAGE
444             );
445         }
446     }
447
448     private void installPlugin(){
449         File pluginFile = getOpenFile(
450             new String[] { "jar", },
451             messages.get("installplugin.fileopen.description")
452         );
453         List<String> messages = new ArrayList<String>();
454         if(pluginFile == null){
455             return;
456         }
457
458         if(Utility.isStigmataPluginJarFile(pluginFile, messages)){
459             StigmataCommand command = StigmataCommandFactory.getInstance().getCommand("install");
460             String path = pluginFile.getPath();
461             command.perform(getStigmata(), new String[] { path });
462
463             int flag = JOptionPane.showConfirmDialog(
464                 this, getMessages().get("reload.after.installplugin"),
465                 getMessages().get("reload.after.installplugin.title"),
466                 JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE
467             );
468
469             if(flag == JOptionPane.YES_OPTION){
470                 reloadSettings(new String[] { "gui", });
471             }
472             else{
473                 JOptionPane.showMessageDialog(
474                     this, getMessages().get("reload.manually"),
475                     getMessages().get("reload.manually.title"),
476                     JOptionPane.INFORMATION_MESSAGE
477                 );
478             }
479         }
480         else{
481             StringBuilder sb = new StringBuilder("<html><body>");
482             sb.append("<p>").append(getMessages().format("install.error", pluginFile.getPath())).append("</p>");
483             sb.append("<ul>");
484             for(String message: messages){
485                 sb.append("<li>").append(getMessages().get(message)).append("</li>");
486             }
487             sb.append("</ul></body></html>");
488
489             JOptionPane.showMessageDialog(
490                 this, new String(sb),
491                 getMessages().get("install.error.title"),
492                 JOptionPane.ERROR_MESSAGE
493             );
494         }
495     }
496
497     private void initComponents(){
498         setDefaultUI();
499         JMenuBar menubar = new JMenuBar();
500         menubar.add(createFileMenu());
501         menubar.add(createHelpMenu());
502
503         setJMenuBar(menubar);
504
505         tabPane = new EditableTabbedPane(this);
506         add(tabPane, BorderLayout.CENTER);
507
508         tabPane.addChangeListener(new ChangeListener(){
509             public void stateChanged(ChangeEvent arg0){
510                 String title = tabPane.getTitleAt(tabPane.getSelectedIndex());
511                 closeTabMenu.setEnabled(!title.equals(getMessages().get("control.tab.label")));
512             }
513         });
514         addWindowListener(new WindowAdapter(){
515             @Override
516             public void windowClosing(WindowEvent e){
517                 boolean closeFlag = true;
518                 if(isNeedToSaveSettings()){
519                     int returnValue = JOptionPane.showConfirmDialog(
520                         StigmataFrame.this,
521                         getMessages().get("needtosave.settings.message"),
522                         getMessages().get("needtosave.settings.title"),
523                         JOptionPane.YES_NO_CANCEL_OPTION,
524                         JOptionPane.WARNING_MESSAGE
525                     );
526                     closeFlag = returnValue != JOptionPane.CANCEL_OPTION;
527                     if(returnValue == JOptionPane.YES_OPTION){
528                         control.saveSettings(new File(BirthmarkEnvironment.getStigmataHome(), "stigmata.xml"));
529                     }
530                 }
531                 if(closeFlag){
532                     setVisible(false);
533                     dispose();
534                 }
535             }
536         });
537         setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
538     }
539
540     private JMenu createFileMenu(){
541         JMenu fileMenu = GUIUtility.createJMenu(getMessages(), "fileMenu");
542         JMenuItem newFrameMenu = GUIUtility.createJMenuItem(getMessages(), "newframe");
543         JMenuItem saveMenu = GUIUtility.createJMenuItem(getMessages(), "savesetting");
544         JMenuItem exportMenu = GUIUtility.createJMenuItem(getMessages(), "exportsetting");
545         JMenuItem clearMenu = GUIUtility.createJMenuItem(getMessages(), "clearsetting");
546         JMenuItem refreshMenu = GUIUtility.createJMenuItem(getMessages(), "refreshsetting");
547         JMenuItem installMenu = GUIUtility.createJMenuItem(getMessages(), "installplugin");
548         JMenuItem openSettingDirMenu = GUIUtility.createJMenuItem(getMessages(), "opensettingdir", new OpenSettingDirAction(this, getMessages()));
549         JMenuItem closeTabMenu = GUIUtility.createJMenuItem(getMessages(), "closetab");
550         JMenuItem closeMenu = GUIUtility.createJMenuItem(getMessages(), "closeframe");
551         JMenuItem exitMenu = GUIUtility.createJMenuItem(getMessages(), "exit");
552         this.closeTabMenu = closeTabMenu;
553         this.saveMenu = saveMenu;
554         saveMenu.setEnabled(false);
555
556         fileMenu.add(newFrameMenu);
557         fileMenu.add(new JSeparator());
558         fileMenu.add(saveMenu);
559         fileMenu.add(exportMenu);
560         fileMenu.add(refreshMenu);
561         fileMenu.add(clearMenu);
562         fileMenu.add(new JSeparator());
563         fileMenu.add(openSettingDirMenu);
564         fileMenu.add(installMenu);
565         fileMenu.add(new JSeparator());
566         fileMenu.add(closeTabMenu);
567         fileMenu.add(closeMenu);
568         fileMenu.add(new JSeparator());
569         fileMenu.add(exitMenu);
570
571         newFrameMenu.addActionListener(new ActionListener(){
572             public void actionPerformed(ActionEvent evt){
573                 StigmataFrame frame = new StigmataFrame(stigmata, environment);
574                 frame.setVisible(true);
575             }
576         });
577         saveMenu.addActionListener(new ActionListener(){
578             public void actionPerformed(ActionEvent e){
579                 control.saveSettings(new File(BirthmarkEnvironment.getStigmataHome(), "stigmata.xml"));
580                 setNeedToSaveSettings(false);
581             }
582         });
583
584         exportMenu.addActionListener(new ActionListener(){
585             public void actionPerformed(ActionEvent e){
586                 control.exportSettings();
587             }
588         });
589
590         closeTabMenu.addActionListener(new ActionListener(){
591             public void actionPerformed(ActionEvent evt){
592                 closeTabMenuActionPerformed();
593             }
594         });
595
596         clearMenu.addActionListener(new ActionListener(){
597             public void actionPerformed(ActionEvent evt){
598                 clearSettings();
599             }
600         });
601         installMenu.addActionListener(new ActionListener(){
602             public void actionPerformed(ActionEvent evt){
603                 installPlugin();
604             }
605         });
606         refreshMenu.addActionListener(new ActionListener(){
607             public void actionPerformed(ActionEvent evt){
608                 reloadSettings(new String[] { "gui", });
609             }
610         });
611
612         closeMenu.addActionListener(new ActionListener(){
613             public void actionPerformed(ActionEvent evt){
614                 setVisible(false);
615                 dispose();
616             }
617         });
618
619         exitMenu.addActionListener(new ActionListener(){
620             public void actionPerformed(ActionEvent evt){
621                 System.exit(0);
622             }
623         });
624         return fileMenu;
625     }
626
627     private JMenu createHelpMenu(){
628         JMenu menu = GUIUtility.createJMenu(getMessages(), "helpmenu");
629         JMenuItem about = GUIUtility.createJMenuItem(getMessages(), "about", new AboutAction(this));
630         JMenuItem license = GUIUtility.createJMenuItem(getMessages(), "license", new LicenseAction(this));
631         JMenuItem help = GUIUtility.createJMenuItem(getMessages(), "helpmenu");
632         experimentalMode = GUIUtility.createJCheckBoxMenuItem(getMessages(), "experimentalmenu");
633
634         menu.add(about);
635         menu.add(license);
636         menu.add(help);
637         menu.add(new JSeparator());
638         menu.add(createLookAndFeelMenu());
639         menu.add(new JSeparator());
640         menu.add(experimentalMode);
641
642         experimentalMode.addActionListener(new ActionListener(){
643             public void actionPerformed(ActionEvent e){
644                 updateExperimentalModeState(((JCheckBoxMenuItem)e.getSource()).getState());
645             }
646         });
647         help.setEnabled(false);
648
649         return menu;
650     }
651
652     private JMenu createLookAndFeelMenu(){
653         JMenu laf = GUIUtility.createJMenu(getMessages(), "lookandfeel");
654         ButtonGroup bg = new ButtonGroup();
655         UIManager.LookAndFeelInfo[] info = UIManager.getInstalledLookAndFeels();
656         LookAndFeel lookfeel = UIManager.getLookAndFeel();
657
658         ActionListener listener = new ActionListener(){
659             public void actionPerformed(ActionEvent e){
660                 try{
661                     String command = e.getActionCommand();
662                     UIManager.setLookAndFeel(command);
663                     SwingUtilities.updateComponentTreeUI(StigmataFrame.this);
664                 } catch(Exception ee){
665                 }
666             }
667         };
668         for(int i = 0; i < info.length; i++){
669             JCheckBoxMenuItem item = new JCheckBoxMenuItem(info[i].getName());
670             item.setActionCommand(info[i].getClassName());
671             item.addActionListener(listener);
672             bg.add(item);
673             laf.add(item);
674
675             if(info[i].getClassName().equals(lookfeel.getClass().getName())){
676                 item.setState(true);
677             }
678         }
679
680         return laf;
681     }
682
683     public void setExperimentalMode(boolean experimentalModeFlag){
684         experimentalMode.setState(experimentalModeFlag);
685     }
686
687     private void updateExperimentalModeState(boolean status){
688         control.setExperimentalMode(status);
689     }
690
691     private void showExceptionMessage(Throwable e){
692         if(e instanceof BirthmarkElementClassNotFoundException){
693             showClassNotFoundMessage((BirthmarkElementClassNotFoundException)e);
694         }
695         else if(e instanceof OutOfMemoryError){
696             showOutOfMemoryError();
697         }
698         else{
699             JTextArea area = new JTextArea(20, 60);
700             StringWriter writer = new StringWriter();
701             PrintWriter out = new PrintWriter(writer);
702             e.printStackTrace(out);
703             if(e instanceof BirthmarkExtractionFailedException){
704                 out.println("Causes:");
705                 for(Throwable t: ((BirthmarkExtractionFailedException)e).getCauses()){
706                     t.printStackTrace(out);
707                 }
708             }
709             out.close();
710             area.setText(writer.toString());
711             JPanel panel = new JPanel(new BorderLayout());
712             panel.add(new JLabel("<html><body><p>" + getMessages().get("error.message.contactus") + "</p></body></html>"), BorderLayout.NORTH);
713             panel.add(new JScrollPane(area), BorderLayout.CENTER);
714
715             JOptionPane.showMessageDialog(
716                 this, panel, getMessages().get("error.dialog.title"),
717                 JOptionPane.WARNING_MESSAGE
718             );
719         }
720     }
721
722     private void showOutOfMemoryError(){
723         StringBuffer sb = new StringBuffer();
724         sb.append("<html><body><p>");
725         sb.append(getMessages().get("error.message.outofmemory"));
726         sb.append("</p></body></html>");
727         JOptionPane.showMessageDialog(
728             this, new String(sb), getMessages().get("error.dialog.title"),
729             JOptionPane.WARNING_MESSAGE
730         );
731     }
732
733     private void showClassNotFoundMessage(BirthmarkElementClassNotFoundException e){
734         StringBuffer sb = new StringBuffer();
735         sb.append("<html><body><p>");
736         sb.append(getMessages().get("error.message.classpath"));
737         sb.append("</p><ul>");
738         for(String name: e.getClassNames()){
739             sb.append("<li>").append(name).append("</li>");
740         }
741         sb.append("</ul></body></html>");
742         JOptionPane.showMessageDialog(
743             this, new String(sb), getMessages().get("error.dialog.title"),
744             JOptionPane.WARNING_MESSAGE
745         );
746     }
747
748     private void closeTabMenuActionPerformed(){
749         int index = tabPane.getSelectedIndex();
750         if(index == 0){
751             JOptionPane.showMessageDialog(
752                 this, getMessages().get("cannotclosecontroltab.dialog.message"),
753                 getMessages().get("cannotclosecontroltab.dialog.title"),
754                 JOptionPane.ERROR_MESSAGE
755             );
756         }
757         else{
758             tabPane.removeTabAt(index);
759         }
760     }
761
762     private int getNextCount(String label){
763         Integer i = countmap.get(label);
764         if(i == null){
765             i = new Integer(0);
766         }
767         i = i + 1;
768         countmap.put(label, i);
769         return i;
770     }
771
772     private void setDefaultUI(){
773         try{
774             UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
775         } catch(Exception e){
776         }
777     }
778 }