1 package jp.sourceforge.stigmata.ui.swing;
7 import java.awt.BorderLayout;
8 import java.awt.Component;
9 import java.awt.GridLayout;
10 import java.awt.event.ActionEvent;
11 import java.awt.event.ActionListener;
12 import java.awt.event.MouseAdapter;
13 import java.awt.event.MouseEvent;
15 import java.io.IOException;
16 import java.io.PrintWriter;
18 import java.util.HashMap;
19 import java.util.Iterator;
22 import javax.swing.Box;
23 import javax.swing.JButton;
24 import javax.swing.JComponent;
25 import javax.swing.JLabel;
26 import javax.swing.JMenuItem;
27 import javax.swing.JOptionPane;
28 import javax.swing.JPanel;
29 import javax.swing.JScrollPane;
30 import javax.swing.JTable;
31 import javax.swing.border.TitledBorder;
32 import javax.swing.table.DefaultTableModel;
34 import jp.sourceforge.stigmata.Birthmark;
35 import jp.sourceforge.stigmata.BirthmarkComparator;
36 import jp.sourceforge.stigmata.BirthmarkContext;
37 import jp.sourceforge.stigmata.BirthmarkEnvironment;
38 import jp.sourceforge.stigmata.BirthmarkSet;
39 import jp.sourceforge.stigmata.BirthmarkStoreException;
40 import jp.sourceforge.stigmata.ComparisonResultSet;
41 import jp.sourceforge.stigmata.ExtractionResultSet;
42 import jp.sourceforge.stigmata.ExtractionTarget;
43 import jp.sourceforge.stigmata.filter.FilteredComparisonResultSet;
44 import jp.sourceforge.stigmata.printer.PrinterManager;
45 import jp.sourceforge.stigmata.result.CertainPairComparisonResultSet;
46 import jp.sourceforge.stigmata.result.RoundRobinComparisonResultSet;
47 import jp.sourceforge.stigmata.spi.ResultPrinterSpi;
48 import jp.sourceforge.stigmata.ui.swing.actions.SaveAction;
49 import jp.sourceforge.stigmata.ui.swing.actions.UpdateBirthmarkCellColorAction;
50 import jp.sourceforge.stigmata.utils.AsciiDataWritable;
51 import jp.sourceforge.talisman.i18n.Messages;
55 * @author Haruaki TAMADA
58 public class RoundRobinComparisonResultPane extends JPanel{
59 private static final long serialVersionUID = 2134574576543623L;
61 private StigmataFrame stigmata;
62 private ExtractionResultSet extraction;
64 private DefaultTableModel model;
65 private JLabel classCount, comparisonCount, distinctionRatio;
66 private JLabel average, minimum, maximum;
68 public RoundRobinComparisonResultPane(StigmataFrame stigmata, ExtractionResultSet resultset){
69 this.stigmata = stigmata;
70 this.extraction = resultset;
75 private void compare(DefaultTableModel model){
76 ExtractionTarget targetX = ExtractionTarget.TARGET_X;
77 ExtractionTarget targetY = ExtractionTarget.TARGET_Y;
78 int countX = extraction.getBirthmarkSetSize(targetX);
79 int countY = extraction.getBirthmarkSetSize(targetY);
80 int comparisonCount = countX * countY;
81 if(countX == 0 && countY == 0){
82 targetX = ExtractionTarget.TARGET_XY;
83 targetY = ExtractionTarget.TARGET_XY;
84 countX = extraction.getBirthmarkSetSize(targetX);
85 countY = extraction.getBirthmarkSetSize(targetY);
86 comparisonCount = countX * (countY - 1) / 2;
88 else if(countX == 0 || countY == 0){
89 targetX = ExtractionTarget.TARGET_BOTH;
90 targetY = ExtractionTarget.TARGET_BOTH;
91 countX = extraction.getBirthmarkSetSize(targetX);
92 countY = extraction.getBirthmarkSetSize(targetY);
93 comparisonCount = countX * (countY - 1) / 2;
96 classCount.setText(Integer.toString(countX + countY));
97 this.comparisonCount.setText(Integer.toString(comparisonCount));
103 for(Iterator<BirthmarkSet> i = extraction.birthmarkSets(targetX); i.hasNext(); ){
104 BirthmarkSet x = i.next();
105 model.addColumn(x.getName());
107 int sizeX = extraction.getBirthmarkSetSize(targetX);
108 for(Iterator<BirthmarkSet> i = extraction.birthmarkSets(targetY); i.hasNext(); ){
109 Object[] rows = new Object[sizeX + 1];
110 BirthmarkSet setY = i.next();
111 rows[0] = setY.getName();
114 for(Iterator<BirthmarkSet> j = extraction.birthmarkSets(targetX); j.hasNext(); ){
115 BirthmarkSet setX = j.next();
116 double similarity = compare(setX, setY, extraction.getContext());
117 rows[index + 1] = new Double(similarity);
119 if(Math.abs(similarity - 1) < 1E-8){
123 if(max < similarity) max = similarity;
124 if(min > similarity) min = similarity;
129 distinctionRatio.setText(
130 Double.toString((double)(comparisonCount - correct) / (double)comparisonCount)
132 avg = avg / comparisonCount;
133 average.setText(Double.toString(avg));
134 minimum.setText(Double.toString(min));
135 maximum.setText(Double.toString(max));
138 private double compare(BirthmarkSet x, BirthmarkSet y, BirthmarkContext context){
139 double similarity = 0d;
142 for(String type: x.getBirthmarkTypes()){
143 Birthmark b1 = x.getBirthmark(type);
144 Birthmark b2 = y.getBirthmark(type);
145 if(b1 != null && b2 != null){
146 BirthmarkComparator comparator = context.getEnvironment().getService(type).getComparator();
147 double result = comparator.compare(b1, b2, context);
148 if(!Double.isNaN(result)){
149 similarity += result;
154 return similarity / count;
157 private Component getMainPane(){
158 JPanel panel = new JPanel();
159 panel.setLayout(new BorderLayout());
161 model = new RoundRobinComparisonResultSetTableModel();
162 table = new JTable(model);
163 table.setDefaultRenderer(Double.class, new CompareTableCellRenderer(extraction.getEnvironment()));
164 table.addMouseListener(new MouseAdapter(){
165 public void mouseClicked(MouseEvent e){
166 if(e.getClickCount() == 2){
167 int row = table.rowAtPoint(e.getPoint());
168 int col = table.columnAtPoint(e.getPoint());
169 if(col >= 1 && col < table.getColumnCount() && row >= 0
170 && row < table.getRowCount()){
171 BirthmarkSet b1 = extraction.getBirthmarkSet(ExtractionTarget.TARGET_X, col - 1);
172 BirthmarkSet b2 = extraction.getBirthmarkSet(ExtractionTarget.TARGET_Y, row);
174 stigmata.compareDetails(b1, b2, extraction.getContext());
179 table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
180 table.setCellSelectionEnabled(true);
181 JScrollPane scroll = new JScrollPane();
182 scroll.setViewportView(table);
183 scroll.setWheelScrollingEnabled(true);
184 panel.add(scroll, BorderLayout.CENTER);
185 JComponent south = Box.createVerticalBox();
186 JPanel box1 = new JPanel(new GridLayout(1, 3));
187 box1.add(classCount = new JLabel());
188 box1.add(comparisonCount = new JLabel());
189 box1.add(distinctionRatio = new JLabel());
191 JPanel box2 = new JPanel(new GridLayout(1, 3));
192 box2.setBorder(new TitledBorder(stigmata.getMessages().get("similarity.border")));
193 box2.add(average = new JLabel());
194 box2.add(minimum = new JLabel());
195 box2.add(maximum = new JLabel());
198 classCount.setBorder(new TitledBorder(stigmata.getMessages().get("numberofclasses.border")));
199 comparisonCount.setBorder(new TitledBorder(stigmata.getMessages().get("comparisoncount.border")));
200 distinctionRatio.setBorder(new TitledBorder(stigmata.getMessages().get("distinctionratio.border")));
201 average.setBorder(new TitledBorder(stigmata.getMessages().get("average.border")));
202 minimum.setBorder(new TitledBorder(stigmata.getMessages().get("minimum.border")));
203 maximum.setBorder(new TitledBorder(stigmata.getMessages().get("maximum.border")));
205 panel.add(south, BorderLayout.SOUTH);
210 private void mdsButtonActionPerformed(ActionEvent e){
211 Map<URL, BirthmarkSet> map = new HashMap<URL, BirthmarkSet>();
212 for(Iterator<BirthmarkSet> i = extraction.birthmarkSets(ExtractionTarget.TARGET_X); i.hasNext(); ){
213 BirthmarkSet bs = i.next();
214 map.put(bs.getLocation(), bs);
216 for(Iterator<BirthmarkSet> i = extraction.birthmarkSets(ExtractionTarget.TARGET_Y); i.hasNext(); ){
217 BirthmarkSet bs = i.next();
218 map.put(bs.getLocation(), bs);
221 BirthmarkSet[] set = new BirthmarkSet[map.size()];
222 for(Map.Entry<URL, BirthmarkSet> entry: map.entrySet()){
223 set[index] = entry.getValue();
227 stigmata.showMdsGraph(set, extraction.getContext());
230 private void graphButtonActionPerformed(ActionEvent e){
231 Map<Integer, Integer> values = new HashMap<Integer, Integer>();
232 for(int i = 0; i < table.getRowCount(); i++){
233 for(int j = 1; j < table.getColumnCount(); j++){
234 Double d = (Double)table.getValueAt(i, j);
235 int similarity = (int)Math.round(d.doubleValue() * 100);
236 Integer dist = values.get(new Integer(similarity));
238 dist = new Integer(0);
240 dist = new Integer(dist.intValue() + 1);
241 values.put(new Integer(similarity), dist);
244 stigmata.showSimilarityDistributionGraph(values);
247 private void initialize(){
248 final Messages messages = stigmata.getMessages();
249 JButton save = GUIUtility.createButton(
250 messages, "savecomparison", new SaveAction(stigmata, new AsciiDataWritable(){
251 public void writeAsciiData(PrintWriter out, String format){
252 ResultPrinterSpi service = PrinterManager.getInstance().getService(format);
254 service = PrinterManager.getDefaultFormatService();
257 service.getComparisonResultSetPrinter().printResult(
258 out, new RoundRobinComparisonResultSet(extraction)
263 JButton graph = GUIUtility.createButton(messages, "showgraph");
264 JButton obfuscate = GUIUtility.createButton(messages, "obfuscate");
265 JButton compare = GUIUtility.createButton(messages, "guessedpair");
266 JButton updateColor = GUIUtility.createButton(
267 messages, "updatecellcolor",
268 new UpdateBirthmarkCellColorAction(stigmata, extraction.getEnvironment())
270 JMenuItem mdsMenu = GUIUtility.createJMenuItem(messages, "mdsmap");
272 PopupButton comparePopup = new PopupButton(compare);
273 PopupButton graphPopup = new PopupButton(graph);
275 JComponent southPanel = Box.createHorizontalBox();
277 setLayout(new BorderLayout());
278 add(getMainPane(), BorderLayout.CENTER);
279 add(southPanel, BorderLayout.SOUTH);
280 southPanel.add(Box.createHorizontalGlue());
281 southPanel.add(save);
282 southPanel.add(Box.createHorizontalGlue());
283 southPanel.add(updateColor);
284 southPanel.add(Box.createHorizontalGlue());
285 southPanel.add(graphPopup);
286 southPanel.add(Box.createHorizontalGlue());
287 southPanel.add(obfuscate);
288 southPanel.add(Box.createHorizontalGlue());
289 southPanel.add(comparePopup);
290 southPanel.add(Box.createHorizontalGlue());
292 graph.addActionListener(new ActionListener(){
293 public void actionPerformed(ActionEvent e){
294 graphButtonActionPerformed(e);
297 mdsMenu.addActionListener(new ActionListener(){
298 public void actionPerformed(ActionEvent e){
299 mdsButtonActionPerformed(e);
303 obfuscate.addActionListener(new ActionListener(){
304 public void actionPerformed(ActionEvent e){
305 obfuscateClassNames();
309 ActionListener compareListener = new ActionListener(){
310 public void actionPerformed(ActionEvent e){
311 String item = e.getActionCommand();
312 if(item.equals("guessedpair")){
313 compareGuessedPair();
315 else if(item.equals("specifiedpair")){
316 compareSpecifiedPair();
318 else if(item.equals("roundrobin.filtering")){
319 compareRoundRobinWithFiltering();
324 compare.addActionListener(compareListener);
325 String[] comparisonMethods = stigmata.getMessages().getArray("comparison.methods.inroundrobinresult");
326 for(int i = 1; i < comparisonMethods.length; i++){
327 JMenuItem item = GUIUtility.createJMenuItem(messages, comparisonMethods[i]);
328 comparePopup.addMenuItem(item);
329 item.addActionListener(compareListener);
331 graphPopup.addMenuItem(mdsMenu);
334 private void compareRoundRobinWithFiltering(){
335 FilterSelectionPane pane = new FilterSelectionPane(
336 stigmata, extraction.getEnvironment().getFilterManager()
338 int returnValue = JOptionPane.showConfirmDialog(
339 stigmata, pane, stigmata.getMessages().get("filterselection.dialog.title"),
340 JOptionPane.OK_CANCEL_OPTION,
341 JOptionPane.QUESTION_MESSAGE
343 if(returnValue == JOptionPane.OK_OPTION){
344 String[] filterSetList = pane.getSelectedFilters();
346 ComparisonResultSet rs = new RoundRobinComparisonResultSet(extraction);
348 ComparisonResultSet filterResultSet = new FilteredComparisonResultSet(
349 rs, extraction.getEnvironment().getFilterManager().getFilterSets(filterSetList)
351 stigmata.showComparisonResultSet(filterResultSet);
355 private void compareGuessedPair(){
356 ComparisonResultSet rs = new CertainPairComparisonResultSet(extraction);
357 stigmata.showComparisonResultSet(rs);
360 private void compareSpecifiedPair(){
361 File file = stigmata.getOpenFile(
362 stigmata.getMessages().getArray("comparemapping.extension"),
363 stigmata.getMessages().get("comparemapping.description")
366 Map<String, String> mapping = stigmata.constructMapping(file);
368 ComparisonResultSet comparison = new CertainPairComparisonResultSet(extraction, mapping);
369 stigmata.showComparisonResultSet(comparison);
373 private void obfuscateClassNames(){
374 ClassNameObfuscator obfuscator = new ClassNameObfuscator();
377 File file = stigmata.getSaveFile(
378 stigmata.getMessages().getArray("obfuscationmapping.extension"),
379 stigmata.getMessages().get("obfuscationmapping.description")
382 BirthmarkContext context = extraction.getContext();
383 BirthmarkEnvironment env = context.getEnvironment();
384 ExtractionResultSet ers = env.getHistoryManager().createDefaultResultSet(context);
386 for(Iterator<BirthmarkSet> i = extraction.birthmarkSets(ExtractionTarget.TARGET_X); i.hasNext(); ){
387 BirthmarkSet bs = i.next();
388 ers.addBirthmarkSet(ExtractionTarget.TARGET_X, obfuscator.obfuscateClassName(bs));
390 for(Iterator<BirthmarkSet> i = extraction.birthmarkSets(ExtractionTarget.TARGET_Y); i.hasNext(); ){
391 BirthmarkSet bs = i.next();
392 ers.addBirthmarkSet(ExtractionTarget.TARGET_Y, obfuscator.obfuscateClassName(bs));
394 } catch(BirthmarkStoreException e){
396 this.extraction = ers;
397 obfuscator.outputNameMappings(file);
399 }catch(IOException e){
400 JOptionPane.showMessageDialog(
401 this, e.getMessage(), stigmata.getMessages().get("error.dialog.title"),
402 JOptionPane.ERROR_MESSAGE
407 DefaultTableModel model = new RoundRobinComparisonResultSetTableModel();
409 table.setModel(model);
413 private static class RoundRobinComparisonResultSetTableModel extends DefaultTableModel{
414 private static final long serialVersionUID = 765435324523543242L;
417 public boolean isCellEditable(int row, int col){
421 public Class<?> getColumnClass(int column){