OSDN Git Service

refactoring
[stigmata/stigmata.git] / src / main / java / jp / naist / se / stigmata / ui / swing / RoundRobinComparisonResultPane.java
1 package jp.naist.se.stigmata.ui.swing;\r
2 \r
3 /*\r
4  * $Id$\r
5  */\r
6 \r
7 import java.awt.BorderLayout;\r
8 import java.awt.Component;\r
9 import java.awt.GridLayout;\r
10 import java.awt.event.ActionEvent;\r
11 import java.awt.event.ActionListener;\r
12 import java.awt.event.MouseAdapter;\r
13 import java.awt.event.MouseEvent;\r
14 import java.io.File;\r
15 import java.io.IOException;\r
16 import java.io.PrintWriter;\r
17 import java.net.URL;\r
18 import java.util.Arrays;\r
19 import java.util.HashMap;\r
20 import java.util.List;\r
21 import java.util.Map;\r
22 \r
23 import javax.swing.Box;\r
24 import javax.swing.JButton;\r
25 import javax.swing.JComponent;\r
26 import javax.swing.JLabel;\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.JTable;\r
32 import javax.swing.border.TitledBorder;\r
33 import javax.swing.table.DefaultTableModel;\r
34 \r
35 import jp.naist.se.stigmata.Birthmark;\r
36 import jp.naist.se.stigmata.BirthmarkComparator;\r
37 import jp.naist.se.stigmata.BirthmarkContext;\r
38 import jp.naist.se.stigmata.BirthmarkSet;\r
39 import jp.naist.se.stigmata.CertainPairComparisonResultSet;\r
40 import jp.naist.se.stigmata.ComparisonResultSet;\r
41 import jp.naist.se.stigmata.RoundRobinComparisonResultSet;\r
42 import jp.naist.se.stigmata.filter.FilteredComparisonResultSet;\r
43 import jp.naist.se.stigmata.format.FormatManager;\r
44 import jp.naist.se.stigmata.spi.ResultFormatSpi;\r
45 import jp.naist.se.stigmata.ui.swing.actions.SaveAction;\r
46 \r
47 /**\r
48  * \r
49  * @author Haruaki TAMADA\r
50  * @version $Revision$ $Date$\r
51  */\r
52 public class RoundRobinComparisonResultPane extends JPanel{\r
53     private static final long serialVersionUID = 2134574576543623L;\r
54 \r
55     private List<BirthmarkSet> birthmarksX;\r
56     private List<BirthmarkSet> birthmarksY;\r
57     private JTable table;\r
58     private DefaultTableModel model;\r
59     private JLabel classCount, comparisonCount, distinctionRatio;\r
60     private JLabel average, minimum, maximum;\r
61     private StigmataFrame stigmataFrame;\r
62     private BirthmarkContext context;\r
63 \r
64     public RoundRobinComparisonResultPane(StigmataFrame stigmata, BirthmarkContext context,\r
65                                           BirthmarkSet[] birthmarksX, BirthmarkSet[] birthmarksY){\r
66         this.stigmataFrame = stigmata;\r
67         this.context = context;\r
68         this.birthmarksX = Arrays.asList(birthmarksX);\r
69         this.birthmarksY = Arrays.asList(birthmarksY);\r
70 \r
71         initialize();\r
72         compare(model);\r
73     }\r
74 \r
75     private void compare(DefaultTableModel model){\r
76         int comparison = birthmarksX.size() * birthmarksY.size();\r
77 \r
78         classCount.setText(Integer.toString(birthmarksX.size() + birthmarksY.size()));\r
79         comparisonCount.setText(Integer.toString(comparison));\r
80         int correct = 0;\r
81         double avg = 0d;\r
82         double max = 0d;\r
83         double min = 100d;\r
84         model.addColumn("");\r
85         for(BirthmarkSet x: birthmarksX){\r
86             model.addColumn(x.getName());\r
87         }\r
88         for(int j = 0; j < birthmarksY.size(); j++){\r
89             Object[] rows = new Object[birthmarksX.size() + 1];\r
90             rows[0] = birthmarksY.get(j).getName();\r
91 \r
92             for(int i = 0; i < birthmarksX.size(); i++){\r
93                 double similarity = compare(context, birthmarksX.get(i), birthmarksY.get(j));\r
94                 rows[i + 1] = new Double(similarity);\r
95 \r
96                 if(Math.abs(similarity - 1) < 1E-8){\r
97                     correct += 1;\r
98                 }\r
99                 avg += similarity;\r
100                 if(max < similarity) max = similarity;\r
101                 if(min > similarity) min = similarity;\r
102             }\r
103             model.addRow(rows);\r
104         }\r
105         distinctionRatio.setText(\r
106             Double.toString((double)(comparison - correct) / (double)comparison)\r
107         );\r
108         avg = avg / comparison;\r
109         average.setText(Double.toString(avg));\r
110         minimum.setText(Double.toString(min));\r
111         maximum.setText(Double.toString(max));\r
112     }\r
113 \r
114     private double compare(BirthmarkContext context, BirthmarkSet x, BirthmarkSet y){\r
115         double similarity = 0d;\r
116         int count = 0;\r
117 \r
118         for(String type: x.getBirthmarkTypes()){\r
119             Birthmark b1 = x.getBirthmark(type);\r
120             Birthmark b2 = y.getBirthmark(type);\r
121             if(b1 != null && b2 != null){\r
122                 BirthmarkComparator comparator = context.getService(type).getComparator();\r
123                 double result = comparator.compare(b1, b2);\r
124                 if(result != Double.NaN){\r
125                     similarity += result;\r
126                     count++;\r
127                 }\r
128             }\r
129         }\r
130         return similarity / count;\r
131     }\r
132 \r
133     private Component getMainPane(){\r
134         JPanel panel = new JPanel();\r
135         panel.setLayout(new BorderLayout());\r
136 \r
137         model = new RoundRobinComparisonResultSetTableModel();\r
138         table = new JTable(model);\r
139         table.setDefaultRenderer(Double.class, new CompareTableCellRenderer());\r
140         table.addMouseListener(new MouseAdapter(){\r
141             public void mouseClicked(MouseEvent e){\r
142                 if(e.getClickCount() == 2){\r
143                     int row = table.rowAtPoint(e.getPoint());\r
144                     int col = table.columnAtPoint(e.getPoint());\r
145                     if(col >= 1 && col < table.getColumnCount() && row >= 0\r
146                             && row < table.getRowCount()){\r
147                         BirthmarkSet b1 = birthmarksX.get(col - 1);\r
148                         BirthmarkSet b2 = birthmarksY.get(row);\r
149 \r
150                         stigmataFrame.compareDetails(b1, b2, context);\r
151                     }\r
152                 }\r
153             }\r
154         });\r
155         table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);\r
156         table.setCellSelectionEnabled(true);\r
157         JScrollPane scroll = new JScrollPane();\r
158         scroll.setViewportView(table);\r
159         scroll.setWheelScrollingEnabled(true);\r
160         panel.add(scroll, BorderLayout.CENTER);\r
161         JComponent south = Box.createVerticalBox();\r
162         JPanel box1 = new JPanel(new GridLayout(1, 3));\r
163         box1.add(classCount = new JLabel());\r
164         box1.add(comparisonCount = new JLabel());\r
165         box1.add(distinctionRatio = new JLabel());\r
166         south.add(box1);\r
167         JPanel box2 = new JPanel(new GridLayout(1, 3));\r
168         box2.setBorder(new TitledBorder(Messages.getString("similarity.border"))); //$NON-NLS-1$\r
169         box2.add(average = new JLabel());\r
170         box2.add(minimum = new JLabel());\r
171         box2.add(maximum = new JLabel());\r
172         south.add(box2);\r
173 \r
174         classCount.setBorder(new TitledBorder(Messages.getString("numberofclasses.border")));\r
175         comparisonCount.setBorder(new TitledBorder(Messages.getString("comparisoncount.border")));\r
176         distinctionRatio.setBorder(new TitledBorder(Messages.getString("distinctionratio.border")));\r
177         average.setBorder(new TitledBorder(Messages.getString("average.border")));\r
178         minimum.setBorder(new TitledBorder(Messages.getString("minimum.border")));\r
179         maximum.setBorder(new TitledBorder(Messages.getString("maximum.border")));\r
180 \r
181         panel.add(south, BorderLayout.SOUTH);\r
182 \r
183         return panel;\r
184     }\r
185 \r
186     private void mdsButtonActionPerformed(ActionEvent e){\r
187         Map<URL, BirthmarkSet> map = new HashMap<URL, BirthmarkSet>();\r
188         for(BirthmarkSet bs: birthmarksX){\r
189             map.put(bs.getLocation(), bs);\r
190         }\r
191         for(BirthmarkSet bs: birthmarksY){\r
192             map.put(bs.getLocation(), bs);\r
193         }\r
194         int index = 0;\r
195         BirthmarkSet[] set = new BirthmarkSet[map.size()];\r
196         for(Map.Entry<URL, BirthmarkSet> entry: map.entrySet()){\r
197             set[index] = entry.getValue();\r
198             index++;\r
199         }\r
200 \r
201         stigmataFrame.showMDSGraph(set);\r
202     }\r
203 \r
204     private void graphButtonActionPerformed(ActionEvent e){\r
205         Map<Integer, Integer> values = new HashMap<Integer, Integer>();\r
206         for(int i = 0; i < table.getRowCount(); i++){\r
207             for(int j = 1; j < table.getColumnCount(); j++){\r
208                 Double d = (Double)table.getValueAt(i, j);\r
209                 int similarity = (int)Math.round(d.doubleValue() * 100);\r
210                 Integer dist = values.get(new Integer(similarity));\r
211                 if(dist == null){\r
212                     dist = new Integer(0);\r
213                 }\r
214                 dist = new Integer(dist.intValue() + 1);\r
215                 values.put(new Integer(similarity), dist);\r
216             }\r
217         }\r
218         stigmataFrame.showSimilarityDistributionGraph(values);\r
219     }\r
220 \r
221     private void initialize(){\r
222         JButton save = Utility.createButton(\r
223             "savecomparison", new SaveAction(stigmataFrame, new AsciiDataWritable(){\r
224                 public void writeAsciiData(PrintWriter out, String format){\r
225                     ResultFormatSpi service = FormatManager.getInstance().getService(format);\r
226                     if(service == null){\r
227                         service = FormatManager.getDefaultFormatService();\r
228                     }\r
229 \r
230                     service.getComparisonResultFormat().printResult(out,\r
231                         new RoundRobinComparisonResultSet(\r
232                             birthmarksX.toArray(new BirthmarkSet[birthmarksX.size()]), \r
233                             birthmarksY.toArray(new BirthmarkSet[birthmarksY.size()]), context\r
234                         )\r
235                     );\r
236                 }\r
237             }\r
238         ));\r
239         JButton graph = Utility.createButton("showgraph");\r
240         JButton obfuscate = Utility.createButton("obfuscate");\r
241         JButton compare = Utility.createButton("guessedpair");\r
242         JMenuItem mdsMenu = Utility.createJMenuItem("mdsmap");\r
243 \r
244         PopupButton comparePopup = new PopupButton(compare);\r
245         PopupButton graphPopup = new PopupButton(graph);\r
246 \r
247         JComponent southPanel = Box.createHorizontalBox();\r
248 \r
249         setLayout(new BorderLayout());\r
250         add(getMainPane(), BorderLayout.CENTER);\r
251         add(southPanel, BorderLayout.SOUTH);\r
252         southPanel.add(Box.createHorizontalGlue());\r
253         southPanel.add(save);\r
254         southPanel.add(Box.createHorizontalGlue());\r
255         southPanel.add(graphPopup);\r
256         southPanel.add(Box.createHorizontalGlue());\r
257         southPanel.add(obfuscate);\r
258         southPanel.add(Box.createHorizontalGlue());\r
259         southPanel.add(comparePopup);\r
260         southPanel.add(Box.createHorizontalGlue());\r
261 \r
262         graph.addActionListener(new ActionListener(){\r
263             public void actionPerformed(ActionEvent e){\r
264                 graphButtonActionPerformed(e);\r
265             }\r
266         });\r
267         mdsMenu.addActionListener(new ActionListener(){\r
268             public void actionPerformed(ActionEvent e){\r
269                 mdsButtonActionPerformed(e);\r
270             }\r
271         });\r
272 \r
273         obfuscate.addActionListener(new ActionListener(){\r
274             public void actionPerformed(ActionEvent e){\r
275                 obfuscateClassNames();\r
276             }\r
277         });\r
278 \r
279         ActionListener compareListener = new ActionListener(){\r
280             public void actionPerformed(ActionEvent e){\r
281                 String item = e.getActionCommand();\r
282                 if(item.equals("guessedpair")){\r
283                     compareGuessedPair();\r
284                 }\r
285                 else if(item.equals("specifiedpair")){\r
286                     compareSpecifiedPair();\r
287                 }\r
288                 else if(item.equals("roundrobin.filtering")){\r
289                     compareRoundRobinWithFiltering();\r
290                 }\r
291             }\r
292         };\r
293 \r
294         compare.addActionListener(compareListener);\r
295         String[] comparisonMethods = Messages.getStringArray("comparison.methods.inroundrobinresult");\r
296         for(int i = 1; i < comparisonMethods.length; i++){\r
297             JMenuItem item = Utility.createJMenuItem(comparisonMethods[i]);\r
298             comparePopup.addMenuItem(item);\r
299             item.addActionListener(compareListener);\r
300         }\r
301         graphPopup.addMenuItem(mdsMenu);\r
302     }\r
303 \r
304     private void compareRoundRobinWithFiltering(){\r
305         FilterSelectionPane pane = new FilterSelectionPane(\r
306             context.getFilterManager()\r
307         );\r
308         int returnValue = JOptionPane.showConfirmDialog(\r
309             stigmataFrame, pane, Messages.getString("filterselection.dialog.title"),\r
310             JOptionPane.OK_CANCEL_OPTION,\r
311             JOptionPane.QUESTION_MESSAGE\r
312         );\r
313         if(returnValue == JOptionPane.OK_OPTION){\r
314             String[] filterSetList = pane.getSelectedFilters();\r
315 \r
316             ComparisonResultSet resultset = new RoundRobinComparisonResultSet(\r
317                 birthmarksX.toArray(new BirthmarkSet[birthmarksX.size()]),\r
318                 birthmarksY.toArray(new BirthmarkSet[birthmarksY.size()]),\r
319                 context\r
320             );\r
321             \r
322             ComparisonResultSet filterResultSet = new FilteredComparisonResultSet(\r
323                 resultset,\r
324                 context.getFilterManager().getFilterSets(filterSetList)\r
325             );\r
326             stigmataFrame.showComparisonResultSet(filterResultSet);\r
327         }\r
328     }\r
329 \r
330     private void compareGuessedPair(){\r
331         ComparisonResultSet resultset = new CertainPairComparisonResultSet(\r
332             birthmarksX.toArray(new BirthmarkSet[birthmarksX.size()]),\r
333             birthmarksY.toArray(new BirthmarkSet[birthmarksY.size()]),\r
334             context\r
335         );\r
336         stigmataFrame.showComparisonResultSet(resultset);\r
337     }\r
338 \r
339     private void compareSpecifiedPair(){\r
340         File file = stigmataFrame.getOpenFile(\r
341             Messages.getStringArray("comparemapping.extension"),\r
342             Messages.getString("comparemapping.description")\r
343         );\r
344         if(file != null){\r
345             Map<String, String> mapping = stigmataFrame.constructMapping(file);\r
346 \r
347             ComparisonResultSet resultset = new CertainPairComparisonResultSet(\r
348                 birthmarksX.toArray(new BirthmarkSet[birthmarksX.size()]),\r
349                 birthmarksY.toArray(new BirthmarkSet[birthmarksY.size()]),\r
350                 mapping, context\r
351             );\r
352             stigmataFrame.showComparisonResultSet(resultset);\r
353         }\r
354     }\r
355 \r
356     private void obfuscateClassNames(){\r
357         ClassNameObfuscator obfuscator = new ClassNameObfuscator();\r
358 \r
359         try{\r
360             File file = stigmataFrame.getSaveFile(\r
361                 Messages.getStringArray("obfuscationmapping.extension"),\r
362                 Messages.getString("obfuscationmapping.description")\r
363             );\r
364             if(file != null){\r
365                 for(int i = 0; i < birthmarksX.size(); i++){\r
366                     birthmarksX.set(i, obfuscator.obfuscateClassName(birthmarksX.get(i)));\r
367                 }\r
368                 for(int i = 0; i < birthmarksY.size(); i++){\r
369                     birthmarksY.set(i, obfuscator.obfuscateClassName(birthmarksY.get(i)));\r
370                 }\r
371 \r
372                 obfuscator.outputNameMappings(file);\r
373             }\r
374         }catch(IOException e){\r
375             JOptionPane.showMessageDialog(this, e.getMessage(), Messages\r
376                     .getString("error.dialog.title"), JOptionPane.ERROR_MESSAGE);\r
377             return;\r
378         }\r
379 \r
380         DefaultTableModel model = new RoundRobinComparisonResultSetTableModel();\r
381         compare(model);\r
382         table.setModel(model);\r
383         this.model = model;\r
384     }\r
385 \r
386     private static class RoundRobinComparisonResultSetTableModel extends DefaultTableModel{\r
387         private static final long serialVersionUID = 765435324523543242L;\r
388 \r
389         @Override\r
390         public boolean isCellEditable(int row, int col){\r
391             return false;\r
392         }\r
393 \r
394         public Class<?> getColumnClass(int column){\r
395             if(column == 0){\r
396                 return String.class;\r
397             }\r
398             else{\r
399                 return Double.class;\r
400             }\r
401         }\r
402     }\r
403 }\r