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(){
166 public void mouseClicked(MouseEvent e){
167 if(e.getClickCount() == 2){
168 int row = table.rowAtPoint(e.getPoint());
169 int col = table.columnAtPoint(e.getPoint());
170 if(col >= 1 && col < table.getColumnCount() && row >= 0
171 && row < table.getRowCount()){
172 BirthmarkSet b1 = extraction.getBirthmarkSet(ExtractionTarget.TARGET_X, col - 1);
173 BirthmarkSet b2 = extraction.getBirthmarkSet(ExtractionTarget.TARGET_Y, row);
175 stigmata.compareDetails(b1, b2, extraction.getContext());
180 table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
181 table.setCellSelectionEnabled(true);
182 JScrollPane scroll = new JScrollPane();
183 scroll.setViewportView(table);
184 scroll.setWheelScrollingEnabled(true);
185 panel.add(scroll, BorderLayout.CENTER);
186 JComponent south = Box.createVerticalBox();
187 JPanel box1 = new JPanel(new GridLayout(1, 3));
188 box1.add(classCount = new JLabel());
189 box1.add(comparisonCount = new JLabel());
190 box1.add(distinctionRatio = new JLabel());
192 JPanel box2 = new JPanel(new GridLayout(1, 3));
193 box2.setBorder(new TitledBorder(stigmata.getMessages().get("similarity.border")));
194 box2.add(average = new JLabel());
195 box2.add(minimum = new JLabel());
196 box2.add(maximum = new JLabel());
199 classCount.setBorder(new TitledBorder(stigmata.getMessages().get("numberofclasses.border")));
200 comparisonCount.setBorder(new TitledBorder(stigmata.getMessages().get("comparisoncount.border")));
201 distinctionRatio.setBorder(new TitledBorder(stigmata.getMessages().get("distinctionratio.border")));
202 average.setBorder(new TitledBorder(stigmata.getMessages().get("average.border")));
203 minimum.setBorder(new TitledBorder(stigmata.getMessages().get("minimum.border")));
204 maximum.setBorder(new TitledBorder(stigmata.getMessages().get("maximum.border")));
206 panel.add(south, BorderLayout.SOUTH);
211 private void mdsButtonActionPerformed(ActionEvent e){
212 Map<URL, BirthmarkSet> map = new HashMap<URL, BirthmarkSet>();
213 for(Iterator<BirthmarkSet> i = extraction.birthmarkSets(ExtractionTarget.TARGET_X); i.hasNext(); ){
214 BirthmarkSet bs = i.next();
215 map.put(bs.getLocation(), bs);
217 for(Iterator<BirthmarkSet> i = extraction.birthmarkSets(ExtractionTarget.TARGET_Y); i.hasNext(); ){
218 BirthmarkSet bs = i.next();
219 map.put(bs.getLocation(), bs);
222 BirthmarkSet[] set = new BirthmarkSet[map.size()];
223 for(Map.Entry<URL, BirthmarkSet> entry: map.entrySet()){
224 set[index] = entry.getValue();
228 stigmata.showMdsGraph(set, extraction.getContext());
231 private void graphButtonActionPerformed(ActionEvent e){
232 Map<Integer, Integer> values = new HashMap<Integer, Integer>();
233 for(int i = 0; i < table.getRowCount(); i++){
234 for(int j = 1; j < table.getColumnCount(); j++){
235 Double d = (Double)table.getValueAt(i, j);
236 int similarity = (int)Math.round(d.doubleValue() * 100);
237 Integer dist = values.get(new Integer(similarity));
239 dist = new Integer(0);
241 dist = new Integer(dist.intValue() + 1);
242 values.put(new Integer(similarity), dist);
245 stigmata.showSimilarityDistributionGraph(values);
248 private void initialize(){
249 final Messages messages = stigmata.getMessages();
250 JButton save = GUIUtility.createButton(
251 messages, "savecomparison", new SaveAction(stigmata, new AsciiDataWritable(){
253 public void writeAsciiData(PrintWriter out, String format){
254 ResultPrinterSpi service = PrinterManager.getInstance().getService(format);
256 service = PrinterManager.getDefaultFormatService();
259 service.getComparisonResultSetPrinter().printResult(
260 out, new RoundRobinComparisonResultSet(extraction)
265 JButton graph = GUIUtility.createButton(messages, "showgraph");
266 JButton obfuscate = GUIUtility.createButton(messages, "obfuscate");
267 JButton compare = GUIUtility.createButton(messages, "guessedpair");
268 JButton updateColor = GUIUtility.createButton(
269 messages, "updatecellcolor",
270 new UpdateBirthmarkCellColorAction(stigmata, extraction.getEnvironment())
272 JMenuItem mdsMenu = GUIUtility.createJMenuItem(messages, "mdsmap");
274 PopupButton comparePopup = new PopupButton(compare);
275 PopupButton graphPopup = new PopupButton(graph);
277 JComponent southPanel = Box.createHorizontalBox();
279 setLayout(new BorderLayout());
280 add(getMainPane(), BorderLayout.CENTER);
281 add(southPanel, BorderLayout.SOUTH);
282 southPanel.add(Box.createHorizontalGlue());
283 southPanel.add(save);
284 southPanel.add(Box.createHorizontalGlue());
285 southPanel.add(updateColor);
286 southPanel.add(Box.createHorizontalGlue());
287 southPanel.add(graphPopup);
288 southPanel.add(Box.createHorizontalGlue());
289 southPanel.add(obfuscate);
290 southPanel.add(Box.createHorizontalGlue());
291 southPanel.add(comparePopup);
292 southPanel.add(Box.createHorizontalGlue());
294 graph.addActionListener(new ActionListener(){
296 public void actionPerformed(ActionEvent e){
297 graphButtonActionPerformed(e);
300 mdsMenu.addActionListener(new ActionListener(){
302 public void actionPerformed(ActionEvent e){
303 mdsButtonActionPerformed(e);
307 obfuscate.addActionListener(new ActionListener(){
309 public void actionPerformed(ActionEvent e){
310 obfuscateClassNames();
314 ActionListener compareListener = new ActionListener(){
316 public void actionPerformed(ActionEvent e){
317 String item = e.getActionCommand();
318 if(item.equals("guessedpair")){
319 compareGuessedPair();
321 else if(item.equals("specifiedpair")){
322 compareSpecifiedPair();
324 else if(item.equals("roundrobin.filtering")){
325 compareRoundRobinWithFiltering();
330 compare.addActionListener(compareListener);
331 String[] comparisonMethods = stigmata.getMessages().getArray("comparison.methods.inroundrobinresult");
332 for(int i = 1; i < comparisonMethods.length; i++){
333 JMenuItem item = GUIUtility.createJMenuItem(messages, comparisonMethods[i]);
334 comparePopup.addMenuItem(item);
335 item.addActionListener(compareListener);
337 graphPopup.addMenuItem(mdsMenu);
340 private void compareRoundRobinWithFiltering(){
341 FilterSelectionPane pane = new FilterSelectionPane(
342 stigmata, extraction.getEnvironment().getFilterManager()
344 int returnValue = JOptionPane.showConfirmDialog(
345 stigmata, pane, stigmata.getMessages().get("filterselection.dialog.title"),
346 JOptionPane.OK_CANCEL_OPTION,
347 JOptionPane.QUESTION_MESSAGE
349 if(returnValue == JOptionPane.OK_OPTION){
350 String[] filterSetList = pane.getSelectedFilters();
352 ComparisonResultSet rs = new RoundRobinComparisonResultSet(extraction);
354 ComparisonResultSet filterResultSet = new FilteredComparisonResultSet(
355 rs, extraction.getEnvironment().getFilterManager().getFilterSets(filterSetList)
357 stigmata.showComparisonResultSet(filterResultSet);
361 private void compareGuessedPair(){
362 ComparisonResultSet rs = new CertainPairComparisonResultSet(extraction);
363 stigmata.showComparisonResultSet(rs);
366 private void compareSpecifiedPair(){
367 File file = stigmata.getOpenFile(
368 stigmata.getMessages().getArray("comparemapping.extension"),
369 stigmata.getMessages().get("comparemapping.description")
372 Map<String, String> mapping = stigmata.constructMapping(file);
374 ComparisonResultSet comparison = new CertainPairComparisonResultSet(extraction, mapping);
375 stigmata.showComparisonResultSet(comparison);
379 private void obfuscateClassNames(){
380 ClassNameObfuscator obfuscator = new ClassNameObfuscator();
383 File file = stigmata.getSaveFile(
384 stigmata.getMessages().getArray("obfuscationmapping.extension"),
385 stigmata.getMessages().get("obfuscationmapping.description")
388 BirthmarkContext context = extraction.getContext();
389 BirthmarkEnvironment env = context.getEnvironment();
390 ExtractionResultSet ers = env.getHistoryManager().createDefaultResultSet(context);
392 for(Iterator<BirthmarkSet> i = extraction.birthmarkSets(ExtractionTarget.TARGET_X); i.hasNext(); ){
393 BirthmarkSet bs = i.next();
394 ers.addBirthmarkSet(ExtractionTarget.TARGET_X, obfuscator.obfuscateClassName(bs));
396 for(Iterator<BirthmarkSet> i = extraction.birthmarkSets(ExtractionTarget.TARGET_Y); i.hasNext(); ){
397 BirthmarkSet bs = i.next();
398 ers.addBirthmarkSet(ExtractionTarget.TARGET_Y, obfuscator.obfuscateClassName(bs));
400 } catch(BirthmarkStoreException e){
402 this.extraction = ers;
403 obfuscator.outputNameMappings(file);
405 }catch(IOException e){
406 JOptionPane.showMessageDialog(
407 this, e.getMessage(), stigmata.getMessages().get("error.dialog.title"),
408 JOptionPane.ERROR_MESSAGE
413 DefaultTableModel model = new RoundRobinComparisonResultSetTableModel();
415 table.setModel(model);
419 private static class RoundRobinComparisonResultSetTableModel extends DefaultTableModel{
420 private static final long serialVersionUID = 765435324523543242L;
423 public boolean isCellEditable(int row, int col){
428 public Class<?> getColumnClass(int column){