1 package jp.naist.se.stigmata.ui.swing;
\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
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
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
49 * @author Haruaki TAMADA
\r
50 * @version $Revision$ $Date$
\r
52 public class RoundRobinComparisonResultPane extends JPanel{
\r
53 private static final long serialVersionUID = 2134574576543623L;
\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
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
75 private void compare(DefaultTableModel model){
\r
76 int comparison = birthmarksX.size() * birthmarksY.size();
\r
78 classCount.setText(Integer.toString(birthmarksX.size() + birthmarksY.size()));
\r
79 comparisonCount.setText(Integer.toString(comparison));
\r
84 model.addColumn("");
\r
85 for(BirthmarkSet x: birthmarksX){
\r
86 model.addColumn(x.getName());
\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
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
96 if(Math.abs(similarity - 1) < 1E-8){
\r
100 if(max < similarity) max = similarity;
\r
101 if(min > similarity) min = similarity;
\r
103 model.addRow(rows);
\r
105 distinctionRatio.setText(
\r
106 Double.toString((double)(comparison - correct) / (double)comparison)
\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
114 private double compare(BirthmarkContext context, BirthmarkSet x, BirthmarkSet y){
\r
115 double similarity = 0d;
\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
130 return similarity / count;
\r
133 private Component getMainPane(){
\r
134 JPanel panel = new JPanel();
\r
135 panel.setLayout(new BorderLayout());
\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
150 stigmataFrame.compareDetails(b1, b2, context);
\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
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
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
181 panel.add(south, BorderLayout.SOUTH);
\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
191 for(BirthmarkSet bs: birthmarksY){
\r
192 map.put(bs.getLocation(), bs);
\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
201 stigmataFrame.showMDSGraph(set);
\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
212 dist = new Integer(0);
\r
214 dist = new Integer(dist.intValue() + 1);
\r
215 values.put(new Integer(similarity), dist);
\r
218 stigmataFrame.showSimilarityDistributionGraph(values);
\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
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
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
244 PopupButton comparePopup = new PopupButton(compare);
\r
245 PopupButton graphPopup = new PopupButton(graph);
\r
247 JComponent southPanel = Box.createHorizontalBox();
\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
262 graph.addActionListener(new ActionListener(){
\r
263 public void actionPerformed(ActionEvent e){
\r
264 graphButtonActionPerformed(e);
\r
267 mdsMenu.addActionListener(new ActionListener(){
\r
268 public void actionPerformed(ActionEvent e){
\r
269 mdsButtonActionPerformed(e);
\r
273 obfuscate.addActionListener(new ActionListener(){
\r
274 public void actionPerformed(ActionEvent e){
\r
275 obfuscateClassNames();
\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
285 else if(item.equals("specifiedpair")){
\r
286 compareSpecifiedPair();
\r
288 else if(item.equals("roundrobin.filtering")){
\r
289 compareRoundRobinWithFiltering();
\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
301 graphPopup.addMenuItem(mdsMenu);
\r
304 private void compareRoundRobinWithFiltering(){
\r
305 FilterSelectionPane pane = new FilterSelectionPane(
\r
306 context.getFilterManager()
\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
313 if(returnValue == JOptionPane.OK_OPTION){
\r
314 String[] filterSetList = pane.getSelectedFilters();
\r
316 ComparisonResultSet resultset = new RoundRobinComparisonResultSet(
\r
317 birthmarksX.toArray(new BirthmarkSet[birthmarksX.size()]),
\r
318 birthmarksY.toArray(new BirthmarkSet[birthmarksY.size()]),
\r
322 ComparisonResultSet filterResultSet = new FilteredComparisonResultSet(
\r
324 context.getFilterManager().getFilterSets(filterSetList)
\r
326 stigmataFrame.showComparisonResultSet(filterResultSet);
\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
336 stigmataFrame.showComparisonResultSet(resultset);
\r
339 private void compareSpecifiedPair(){
\r
340 File file = stigmataFrame.getOpenFile(
\r
341 Messages.getStringArray("comparemapping.extension"),
\r
342 Messages.getString("comparemapping.description")
\r
345 Map<String, String> mapping = stigmataFrame.constructMapping(file);
\r
347 ComparisonResultSet resultset = new CertainPairComparisonResultSet(
\r
348 birthmarksX.toArray(new BirthmarkSet[birthmarksX.size()]),
\r
349 birthmarksY.toArray(new BirthmarkSet[birthmarksY.size()]),
\r
352 stigmataFrame.showComparisonResultSet(resultset);
\r
356 private void obfuscateClassNames(){
\r
357 ClassNameObfuscator obfuscator = new ClassNameObfuscator();
\r
360 File file = stigmataFrame.getSaveFile(
\r
361 Messages.getStringArray("obfuscationmapping.extension"),
\r
362 Messages.getString("obfuscationmapping.description")
\r
365 for(int i = 0; i < birthmarksX.size(); i++){
\r
366 birthmarksX.set(i, obfuscator.obfuscateClassName(birthmarksX.get(i)));
\r
368 for(int i = 0; i < birthmarksY.size(); i++){
\r
369 birthmarksY.set(i, obfuscator.obfuscateClassName(birthmarksY.get(i)));
\r
372 obfuscator.outputNameMappings(file);
\r
374 }catch(IOException e){
\r
375 JOptionPane.showMessageDialog(this, e.getMessage(), Messages
\r
376 .getString("error.dialog.title"), JOptionPane.ERROR_MESSAGE);
\r
380 DefaultTableModel model = new RoundRobinComparisonResultSetTableModel();
\r
382 table.setModel(model);
\r
383 this.model = model;
\r
386 private static class RoundRobinComparisonResultSetTableModel extends DefaultTableModel{
\r
387 private static final long serialVersionUID = 765435324523543242L;
\r
390 public boolean isCellEditable(int row, int col){
\r
394 public Class<?> getColumnClass(int column){
\r
396 return String.class;
\r
399 return Double.class;
\r