1 package jp.naist.se.stigmata.ui.swing;
\r
7 import java.awt.BorderLayout;
\r
8 import java.awt.Image;
\r
9 import java.awt.event.ActionEvent;
\r
10 import java.awt.event.ActionListener;
\r
11 import java.io.BufferedReader;
\r
12 import java.io.File;
\r
13 import java.io.FileReader;
\r
14 import java.io.IOException;
\r
15 import java.io.PrintWriter;
\r
16 import java.io.StringWriter;
\r
17 import java.util.HashMap;
\r
18 import java.util.Iterator;
\r
19 import java.util.Map;
\r
21 import javax.swing.ButtonGroup;
\r
22 import javax.swing.JCheckBoxMenuItem;
\r
23 import javax.swing.JFrame;
\r
24 import javax.swing.JLabel;
\r
25 import javax.swing.JMenu;
\r
26 import javax.swing.JMenuBar;
\r
27 import javax.swing.JMenuItem;
\r
28 import javax.swing.JOptionPane;
\r
29 import javax.swing.JPanel;
\r
30 import javax.swing.JScrollPane;
\r
31 import javax.swing.JSeparator;
\r
32 import javax.swing.JTabbedPane;
\r
33 import javax.swing.JTextArea;
\r
34 import javax.swing.LookAndFeel;
\r
35 import javax.swing.SwingUtilities;
\r
36 import javax.swing.UIManager;
\r
37 import javax.swing.WindowConstants;
\r
38 import javax.swing.event.ChangeEvent;
\r
39 import javax.swing.event.ChangeListener;
\r
40 import javax.swing.filechooser.FileFilter;
\r
42 import jp.naist.se.stigmata.BirthmarkContext;
\r
43 import jp.naist.se.stigmata.BirthmarkElementClassNotFoundException;
\r
44 import jp.naist.se.stigmata.BirthmarkEngine;
\r
45 import jp.naist.se.stigmata.BirthmarkEnvironment;
\r
46 import jp.naist.se.stigmata.BirthmarkExtractionFailedException;
\r
47 import jp.naist.se.stigmata.BirthmarkSet;
\r
48 import jp.naist.se.stigmata.ComparisonPair;
\r
49 import jp.naist.se.stigmata.ComparisonResultSet;
\r
50 import jp.naist.se.stigmata.ExtractionResultSet;
\r
51 import jp.naist.se.stigmata.Stigmata;
\r
52 import jp.naist.se.stigmata.event.BirthmarkEngineAdapter;
\r
53 import jp.naist.se.stigmata.event.BirthmarkEngineEvent;
\r
54 import jp.naist.se.stigmata.event.WarningMessages;
\r
55 import jp.naist.se.stigmata.result.CertainPairComparisonResultSet;
\r
56 import jp.naist.se.stigmata.ui.swing.actions.AboutAction;
\r
57 import jp.naist.se.stigmata.ui.swing.actions.LicenseAction;
\r
58 import jp.naist.se.stigmata.ui.swing.graph.SimilarityDistributionGraphPane;
\r
59 import jp.naist.se.stigmata.ui.swing.mds.MDSGraphPanel;
\r
60 import jp.naist.se.stigmata.ui.swing.tab.EditableTabbedPane;
\r
64 * @author Haruaki TAMADA
\r
65 * @version $Revision$ $Date$
\r
67 public class StigmataFrame extends JFrame{
\r
68 private static final long serialVersionUID = 92345543665342134L;
\r
70 private JTabbedPane tabPane;
\r
71 private JMenuItem closeTabMenu;
\r
72 private JCheckBoxMenuItem expertmodeMenu;
\r
73 private Stigmata stigmata;
\r
74 private BirthmarkEnvironment environment;
\r
75 private ControlPane control;
\r
76 private FileIOManager fileio;
\r
77 private Map<String, Integer> countmap = new HashMap<String, Integer>();
\r
79 public StigmataFrame(){
\r
80 this(Stigmata.getInstance());
\r
83 public StigmataFrame(Stigmata stigmata){
\r
84 this(stigmata, BirthmarkEnvironment.getDefaultEnvironment());
\r
87 public StigmataFrame(Stigmata stigmata, BirthmarkEnvironment environment){
\r
88 this.stigmata = stigmata;
\r
89 this.environment = environment;
\r
90 this.fileio = new FileIOManager(this);
\r
91 Image iconImage = Utility.getImage("stigmata.icon");
\r
92 if(iconImage != null){
\r
93 setIconImage(iconImage);
\r
96 stigmata.addBirthmarkEngineListener(new BirthmarkEngineAdapter(){
\r
98 public void operationDone(BirthmarkEngineEvent e){
\r
99 showWarnings(e.getMessage());
\r
106 public Stigmata getStigmata(){
\r
110 public BirthmarkEnvironment getEnvironment(){
\r
111 return environment;
\r
114 public File getCurrentDirectory(){
\r
115 return fileio.getCurrentDirectory();
\r
118 public void setCurrentDirectory(File file){
\r
120 fileio.setCurrentDirectory(file);
\r
121 } catch(IllegalArgumentException e){
\r
122 JOptionPane.showMessageDialog(
\r
124 Messages.getString("notdirectory.dialog.message", file.getName()),
\r
125 Messages.getString("notdirectory.dialog.title"),
\r
126 JOptionPane.ERROR_MESSAGE
\r
128 } catch(Exception e){
\r
129 showExceptionMessage(e);
\r
133 public File[] openFiles(FileFilter[] filters, boolean multipleSelectable, boolean directorySelectable){
\r
134 return fileio.openFiles(filters, multipleSelectable, directorySelectable);
\r
138 * Find file to open it.
\r
140 public File getOpenFile(String[] exts, String desc){
\r
141 return fileio.findFile(true, exts, desc);
\r
145 * Find file for storing data to it.
\r
146 * Extension of found file is correct as selected extension.
\r
148 public File getSaveFile(String[] exts, String desc){
\r
149 return fileio.findFile(false, exts, desc);
\r
152 public void addBirthmarkServiceListener(BirthmarkServiceListener listener){
\r
153 control.addBirthmarkServiceListener(listener);
\r
156 public void removeBirthmarkServiceListener(BirthmarkServiceListener listener){
\r
157 control.removeBirthmarkServiceListener(listener);
\r
160 public void compareDetails(BirthmarkSet target1, BirthmarkSet target2, BirthmarkContext context){
\r
161 PairComparisonPane detail = new PairComparisonPane(
\r
162 this, new ComparisonPair(target1, target2, context)
\r
164 int compareDetail = getNextCount("compare_detail");
\r
166 Utility.addNewTab("comparedetail", tabPane, detail,
\r
167 new Object[] { new Integer(compareDetail), },
\r
169 Utility.array2String(target1.getBirthmarkTypes()),
\r
174 tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
\r
177 public void compareRoundRobin(String[] targetX, String[] targetY,
\r
178 BirthmarkContext context){
\r
180 BirthmarkEngine engine = new BirthmarkEngine(context.getEnvironment());
\r
181 ExtractionResultSet ers = engine.extract(targetX, targetY, context);
\r
183 RoundRobinComparisonResultPane compare = new RoundRobinComparisonResultPane(this, ers);
\r
184 int compareCount = getNextCount("compare");
\r
186 "compare", tabPane, compare,
\r
187 new Object[] { new Integer(compareCount), },
\r
189 Utility.array2String(context.getExtractionTypes()),
\r
190 Utility.array2String(targetX),
\r
191 Utility.array2String(targetY),
\r
194 tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
\r
195 } catch(Throwable e){
\r
196 showExceptionMessage(e);
\r
200 public void compareRoundRobinFilter(String[] targetX, String[] targetY,
\r
201 BirthmarkContext context){
\r
203 BirthmarkEngine engine = new BirthmarkEngine(context.getEnvironment());
\r
205 ExtractionResultSet ers = engine.extract(targetX, targetY, context);
\r
206 ComparisonResultSet resultset = engine.compare(ers);
\r
207 if(context.hasFilter()){
\r
208 resultset = engine.filter(resultset);
\r
210 int compareCount = getNextCount("compare");
\r
212 "compare", tabPane, new PairComparisonResultSetPane(this, resultset),
\r
213 new Object[] { new Integer(compareCount), },
\r
215 Utility.array2String(context.getExtractionTypes()),
\r
216 Utility.array2String(targetX),
\r
217 Utility.array2String(targetY),
\r
220 tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
\r
221 } catch(Throwable e){
\r
222 showExceptionMessage(e);
\r
226 public void compareGuessedPair(String[] targetX, String[] targetY, BirthmarkContext context){
\r
228 BirthmarkEngine engine = new BirthmarkEngine(context.getEnvironment());
\r
229 ExtractionResultSet extraction = engine.extract(targetX, targetY, context);
\r
230 int comparePair = getNextCount("compare_pair");
\r
232 ComparisonResultSet resultset = new CertainPairComparisonResultSet(extraction);
\r
233 Utility.addNewTab("comparepair", tabPane,
\r
234 new PairComparisonResultSetPane(this, resultset),
\r
235 new Object[] { new Integer(comparePair), },
\r
237 Utility.array2String(context.getExtractionTypes()),
\r
238 Utility.array2String(targetX),
\r
239 Utility.array2String(targetY),
\r
242 tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
\r
243 }catch(Throwable e){
\r
244 showExceptionMessage(e);
\r
248 public void compareSpecifiedPair(String[] targetX, String[] targetY, BirthmarkContext context){
\r
249 File file = getOpenFile(Messages.getStringArray("comparemapping.extension"),
\r
250 Messages.getString("comparemapping.description"));
\r
253 Map<String, String> mapping = constructMapping(file);
\r
256 BirthmarkEngine engine = new BirthmarkEngine(context.getEnvironment());
\r
257 context.setNameMappings(mapping);
\r
258 ComparisonResultSet crs = engine.compare(targetX, targetY, context);
\r
259 int comparePair = getNextCount("compare_pair");
\r
262 "comparepair", tabPane,
\r
263 new PairComparisonResultSetPane(this, crs),
\r
264 new Object[] { new Integer(comparePair), },
\r
266 Utility.array2String(context.getExtractionTypes()),
\r
267 Utility.array2String(targetX),
\r
268 Utility.array2String(targetY),
\r
271 tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
\r
272 }catch(Exception e){
\r
273 showExceptionMessage(e);
\r
278 public void showComparisonResultSet(ComparisonResultSet resultset){
\r
279 int comparePair = getNextCount("compare_pair");
\r
281 "comparisonresultset", tabPane,
\r
282 new PairComparisonResultSetPane(this, resultset),
\r
283 new Object[] { new Integer(comparePair), }, null
\r
285 tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
\r
288 public void showMDSGraph(BirthmarkSet[] set, BirthmarkContext context){
\r
290 MDSGraphPanel panel = new MDSGraphPanel(this, set, context);
\r
291 int mappingGraphCount = getNextCount("mds_graph");
\r
292 Utility.addNewTab("mappinggraph", tabPane, panel, new Object[] { new Integer(mappingGraphCount), }, null);
\r
293 tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
\r
294 } catch(Exception e){
\r
295 showExceptionMessage(e);
\r
299 public void showSimilarityDistributionGraph(Map<Integer, Integer> distributions){
\r
300 SimilarityDistributionGraphPane graph = new SimilarityDistributionGraphPane(this, distributions);
\r
302 int similarityGraphCount = getNextCount("similarity_graph");
\r
303 Utility.addNewTab("similaritygraph", tabPane, graph, new Object[] { new Integer(similarityGraphCount), }, null);
\r
304 tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
\r
307 public void showExtractionResult(ExtractionResultSet ers){
\r
308 int extractCount = getNextCount("extract");
\r
309 BirthmarkExtractionResultPane viewer = new BirthmarkExtractionResultPane(this, ers);
\r
311 "extract", tabPane, viewer,
\r
312 new Object[] { new Integer(extractCount), },
\r
313 new Object[] { Utility.array2String(ers.getBirthmarkTypes()), }
\r
315 tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
\r
319 public void extract(String[] targets, BirthmarkContext context){
\r
321 BirthmarkEngine engine = new BirthmarkEngine(context.getEnvironment());
\r
322 ExtractionResultSet ers = engine.extract(targets, context);
\r
323 showExtractionResult(ers);
\r
324 }catch(Throwable e){
\r
325 showExceptionMessage(e);
\r
332 public Map<String, String> constructMapping(File file){
\r
333 Map<String, String> mapping = new HashMap<String, String>();
\r
334 BufferedReader in = null;
\r
336 in = new BufferedReader(new FileReader(file));
\r
338 while((line = in.readLine()) != null){
\r
339 String[] tokens = line.split(", *");
\r
340 if(tokens.length >= 2){
\r
341 mapping.put(tokens[0], tokens[1]);
\r
345 }catch(Exception e){
\r
346 showExceptionMessage(e);
\r
351 }catch(IOException e){
\r
358 private void initLayouts(){
\r
359 setTitle(Messages.getString("stigmata.frame.title"));
\r
362 Utility.addNewTab("control", tabPane, control = new ControlPane(this), null, null);
\r
363 control.inititalize();
\r
364 tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
\r
369 private void showWarnings(WarningMessages warnings){
\r
370 if(warnings.getWarningCount() > 0){
\r
371 StringBuilder sb = new StringBuilder("<html><body><dl>");
\r
372 for(Iterator<Exception> i = warnings.exceptions(); i.hasNext(); ){
\r
373 Exception e = i.next();
\r
374 sb.append("<dt>").append(e.getClass().getName()).append("</dt>");
\r
375 sb.append("<dd>").append(e.getMessage()).append("</dd>");
\r
376 sb.append("<dd>").append(warnings.getString(e)).append("</dd>");
\r
378 sb.append("</dl></body></html>");
\r
380 JOptionPane.showMessageDialog(
\r
381 this, new String(sb), Messages.getString("warning.dialog.title"),
\r
382 JOptionPane.WARNING_MESSAGE
\r
387 private void initComponents(){
\r
389 JMenuBar menubar = new JMenuBar();
\r
390 menubar.add(createFileMenu());
\r
391 menubar.add(createHelpMenu());
\r
393 setJMenuBar(menubar);
\r
395 tabPane = new EditableTabbedPane(this);
\r
396 add(tabPane, BorderLayout.CENTER);
\r
398 tabPane.addChangeListener(new ChangeListener(){
\r
399 public void stateChanged(ChangeEvent arg0){
\r
400 String title = tabPane.getTitleAt(tabPane.getSelectedIndex());
\r
401 closeTabMenu.setEnabled(!title.equals(Messages.getString("control.tab.label")));
\r
405 setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
\r
408 private JMenu createFileMenu(){
\r
409 JMenu fileMenu = Utility.createJMenu("fileMenu");
\r
410 JMenuItem newFrameMenu = Utility.createJMenuItem("newframe");
\r
411 JMenuItem exportMenu = Utility.createJMenuItem("exportsetting");
\r
412 JMenuItem closeTabMenu = Utility.createJMenuItem("closetab");
\r
413 JMenuItem closeMenu = Utility.createJMenuItem("closeframe");
\r
414 JMenuItem exitMenu = Utility.createJMenuItem("exit");
\r
415 this.closeTabMenu = closeTabMenu;
\r
417 fileMenu.add(newFrameMenu);
\r
418 fileMenu.add(new JSeparator());
\r
419 fileMenu.add(exportMenu);
\r
420 fileMenu.add(new JSeparator());
\r
421 fileMenu.add(closeTabMenu);
\r
422 fileMenu.add(closeMenu);
\r
423 fileMenu.add(new JSeparator());
\r
424 fileMenu.add(exitMenu);
\r
426 newFrameMenu.addActionListener(new ActionListener(){
\r
427 public void actionPerformed(ActionEvent evt){
\r
428 StigmataFrame frame = new StigmataFrame(stigmata, environment);
\r
429 frame.setVisible(true);
\r
432 exportMenu.addActionListener(new ActionListener(){
\r
433 public void actionPerformed(ActionEvent e){
\r
434 control.exportSettings();
\r
438 closeTabMenu.addActionListener(new ActionListener(){
\r
439 public void actionPerformed(ActionEvent evt){
\r
440 closeTabMenuActionPerformed();
\r
444 closeMenu.addActionListener(new ActionListener(){
\r
445 public void actionPerformed(ActionEvent evt){
\r
451 exitMenu.addActionListener(new ActionListener(){
\r
452 public void actionPerformed(ActionEvent evt){
\r
459 private JMenu createHelpMenu(){
\r
460 JMenu menu = Utility.createJMenu("helpmenu");
\r
461 JMenuItem about = Utility.createJMenuItem("about", new AboutAction(this));
\r
462 JMenuItem license = Utility.createJMenuItem("license", new LicenseAction(this));
\r
463 JMenuItem help = Utility.createJMenuItem("helpmenu");
\r
464 expertmodeMenu = Utility.createJCheckBoxMenuItem("expertmenu");
\r
469 menu.add(new JSeparator());
\r
470 menu.add(createLookAndFeelMenu());
\r
471 menu.add(new JSeparator());
\r
472 menu.add(expertmodeMenu);
\r
474 expertmodeMenu.addActionListener(new ActionListener(){
\r
475 public void actionPerformed(ActionEvent e){
\r
476 expertMenuActionPerformed(((JCheckBoxMenuItem)e.getSource()).getState());
\r
479 help.setEnabled(false);
\r
484 private JMenu createLookAndFeelMenu(){
\r
485 JMenu laf = Utility.createJMenu("lookandfeel");
\r
486 ButtonGroup bg = new ButtonGroup();
\r
487 UIManager.LookAndFeelInfo[] info = UIManager.getInstalledLookAndFeels();
\r
488 LookAndFeel lookfeel = UIManager.getLookAndFeel();
\r
490 ActionListener listener = new ActionListener(){
\r
491 public void actionPerformed(ActionEvent e){
\r
493 String command = e.getActionCommand();
\r
494 UIManager.setLookAndFeel(command);
\r
495 SwingUtilities.updateComponentTreeUI(StigmataFrame.this);
\r
496 } catch(Exception ee){
\r
500 for(int i = 0; i < info.length; i++){
\r
501 JCheckBoxMenuItem item = new JCheckBoxMenuItem(info[i].getName());
\r
502 item.setActionCommand(info[i].getClassName());
\r
503 item.addActionListener(listener);
\r
507 if(info[i].getClassName().equals(lookfeel.getClass().getName())){
\r
508 item.setState(true);
\r
515 public void setExpertMode(boolean expertmode){
\r
516 expertmodeMenu.setState(expertmode);
\r
519 private void expertMenuActionPerformed(boolean status){
\r
520 control.setExpertMode(status);
\r
523 private void showExceptionMessage(Throwable e){
\r
524 if(e instanceof BirthmarkElementClassNotFoundException){
\r
525 showClassNotFoundMessage((BirthmarkElementClassNotFoundException)e);
\r
527 else if(e instanceof OutOfMemoryError){
\r
528 showOutOfMemoryError();
\r
531 JTextArea area = new JTextArea(20, 60);
\r
532 StringWriter writer = new StringWriter();
\r
533 PrintWriter out = new PrintWriter(writer);
\r
534 e.printStackTrace(out);
\r
535 if(e instanceof BirthmarkExtractionFailedException){
\r
536 out.println("Causes:");
\r
537 for(Throwable t: ((BirthmarkExtractionFailedException)e).getCauses()){
\r
538 t.printStackTrace(out);
\r
542 area.setText(writer.toString());
\r
543 JPanel panel = new JPanel(new BorderLayout());
\r
544 panel.add(new JLabel("<html><body><p>" + Messages.getString("error.message.contactus") + "</p></body></html>"), BorderLayout.NORTH);
\r
545 panel.add(new JScrollPane(area), BorderLayout.CENTER);
\r
547 JOptionPane.showMessageDialog(
\r
548 this, panel, Messages.getString("error.dialog.title"),
\r
549 JOptionPane.WARNING_MESSAGE
\r
554 private void showOutOfMemoryError(){
\r
555 StringBuffer sb = new StringBuffer();
\r
556 sb.append("<html><body><p>");
\r
557 sb.append(Messages.getString("error.message.outofmemory"));
\r
558 sb.append("</p></body></html>");
\r
559 JOptionPane.showMessageDialog(
\r
560 this, new String(sb), Messages.getString("error.dialog.title"),
\r
561 JOptionPane.WARNING_MESSAGE
\r
565 private void showClassNotFoundMessage(BirthmarkElementClassNotFoundException e){
\r
566 StringBuffer sb = new StringBuffer();
\r
567 sb.append("<html><body><p>");
\r
568 sb.append(Messages.getString("error.message.classpath"));
\r
569 sb.append("</p><ul>");
\r
570 for(String name: e.getClassNames()){
\r
571 sb.append("<li>").append(name).append("</li>");
\r
573 sb.append("</ul></body></html>");
\r
574 JOptionPane.showMessageDialog(
\r
575 this, new String(sb), Messages.getString("error.dialog.title"),
\r
576 JOptionPane.WARNING_MESSAGE
\r
580 private void closeTabMenuActionPerformed(){
\r
581 int index = tabPane.getSelectedIndex();
\r
583 JOptionPane.showMessageDialog(
\r
584 this, Messages.getString("cannotclosecontroltab.dialog.message"),
\r
585 Messages.getString("cannotclosecontroltab.dialog.title"),
\r
586 JOptionPane.ERROR_MESSAGE
\r
590 tabPane.removeTabAt(index);
\r
594 private int getNextCount(String label){
\r
595 Integer i = countmap.get(label);
\r
597 i = new Integer(0);
\r
600 countmap.put(label, i);
\r
604 private void setDefaultUI(){
\r
606 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
\r
607 } catch(Exception e){
\r