OSDN Git Service

プラットフォームごとのStigmataのホームディレクトリの場所を返す一連のクラスをリファクタリングした.
[stigmata/stigmata.git] / src / main / java / jp / sourceforge / stigmata / ui / swing / mds / MdsViewerPane.java
1 package jp.sourceforge.stigmata.ui.swing.mds;
2
3 /*
4  * $Id$
5  */
6
7 import java.awt.BorderLayout;
8 import java.awt.Dimension;
9 import java.awt.FlowLayout;
10 import java.awt.GridLayout;
11 import java.awt.event.ActionEvent;
12 import java.awt.event.ActionListener;
13 import java.awt.event.ComponentAdapter;
14 import java.awt.event.ComponentEvent;
15 import java.net.URL;
16 import java.util.HashMap;
17 import java.util.Map;
18
19 import javax.swing.Action;
20 import javax.swing.Box;
21 import javax.swing.JButton;
22 import javax.swing.JCheckBox;
23 import javax.swing.JComboBox;
24 import javax.swing.JLabel;
25 import javax.swing.JPanel;
26 import javax.swing.JScrollPane;
27 import javax.swing.JTextField;
28 import javax.swing.JToolBar;
29
30 import jp.sourceforge.stigmata.BirthmarkContext;
31 import jp.sourceforge.stigmata.BirthmarkEnvironment;
32 import jp.sourceforge.stigmata.BirthmarkSet;
33 import jp.sourceforge.stigmata.ComparisonPair;
34 import jp.sourceforge.stigmata.ui.swing.ClippedLRListCellRenderer;
35 import jp.sourceforge.stigmata.ui.swing.GUIUtility;
36 import jp.sourceforge.stigmata.ui.swing.PopupButton;
37 import jp.sourceforge.stigmata.ui.swing.StigmataFrame;
38 import jp.sourceforge.stigmata.ui.swing.actions.SaveAction;
39 import jp.sourceforge.talisman.i18n.MessageManager;
40 import jp.sourceforge.talisman.i18n.Messages;
41 import jp.sourceforge.talisman.i18n.ResourceNotFoundException;
42 import jp.sourceforge.talisman.mds.Item;
43 import jp.sourceforge.talisman.mds.MdsMethod;
44 import jp.sourceforge.talisman.mds.Table;
45 import jp.sourceforge.talisman.mds.ui.MdsGraphSetting;
46 import jp.sourceforge.talisman.mds.ui.mark.DrawerFactory;
47 import jp.sourceforge.talisman.mds.ui.swing.MdsPane;
48 import jp.sourceforge.talisman.mds.ui.swing.actions.AntiClockwiseRotateAction;
49 import jp.sourceforge.talisman.mds.ui.swing.actions.ClearAction;
50 import jp.sourceforge.talisman.mds.ui.swing.actions.ClockwiseRotateAction;
51 import jp.sourceforge.talisman.mds.ui.swing.actions.ClusteringAction;
52 import jp.sourceforge.talisman.mds.ui.swing.actions.HorizontalFlipAction;
53 import jp.sourceforge.talisman.mds.ui.swing.actions.VerticalFlipAction;
54 import jp.sourceforge.talisman.mds.ui.swing.actions.ZoomEnabler;
55 import jp.sourceforge.talisman.mds.ui.swing.actions.ZoomInAction;
56 import jp.sourceforge.talisman.mds.ui.swing.actions.ZoomOutAction;
57
58 /**
59  * 
60  * @author Haruaki TAMADA
61  * @version $Revision$ 
62  */
63 public class MdsViewerPane extends JPanel implements ZoomEnabler, MessageManager{
64     private static final long serialVersionUID = -7256554014379112897L;
65     private static final int[] ZOOM_PATTERN = { 30, 40, 50, 75, 100, 125, 150,
66             200, 300, 400, };
67
68     private StigmataFrame stigmata;
69     private BirthmarkSet[] set;
70     private BirthmarkContext context;
71     private MdsPane mdspane;
72     private MdsGraphSetting setting;
73     private LabelMap labels;
74
75     private int currentZoomPattern = 4;
76     private boolean userInputtedValue = false;
77     private JTextField zoomRatio;
78     private ZoomInAction zoomin;
79     private ZoomOutAction zoomout;
80
81     public MdsViewerPane(StigmataFrame stigmata, BirthmarkSet[] set, BirthmarkContext context){
82         this.stigmata = stigmata;
83         this.context = context;
84         this.set = set;
85
86         try{
87             initLayouts();
88         } catch(ResourceNotFoundException e){
89             e.printStackTrace();
90             throw new InternalError(e.getMessage());
91         }
92     }
93
94     @Override
95     public void zoomIn(){
96         currentZoomPattern++;
97         userInputtedValue = false;
98         zoom(ZOOM_PATTERN[currentZoomPattern]);
99     }
100
101     @Override
102     public void zoomOut(){
103         if(!userInputtedValue){
104             currentZoomPattern--;
105         }
106         userInputtedValue = false;
107         zoom(ZOOM_PATTERN[currentZoomPattern]);
108     }
109
110     @Override
111     public void zoom(int ratio){
112         for(int i = 0; i < ZOOM_PATTERN.length; i++){
113             if(ratio <= ZOOM_PATTERN[i]){
114                 currentZoomPattern = i;
115                 break;
116             }
117         }
118         if(userInputtedValue && ratio < ZOOM_PATTERN[0]){
119             currentZoomPattern = -1;
120         }
121         if(userInputtedValue && ratio > ZOOM_PATTERN[ZOOM_PATTERN.length - 1]){
122             currentZoomPattern = ZOOM_PATTERN.length - 1;
123         }
124         zoomin.setEnabled(currentZoomPattern < (ZOOM_PATTERN.length - 1));
125         zoomout.setEnabled(currentZoomPattern != 0);
126
127         zoomRatio.setText(ratio + " %");
128         mdspane.setZoomRatio(ratio);
129     }
130
131     @Override
132     public Messages getMessages(){
133         return stigmata.getMessages();
134     }
135
136     private Table<String> initData(BirthmarkSet[] set, BirthmarkContext context){
137         Table<String> table = new Table<String>();
138
139         for(int i = 0; i < set.length; i++){
140             for(int j = 0; j <= i; j++){
141                 ComparisonPair pair = new ComparisonPair(set[i], set[j], context);
142                 table.addValue(set[i].getName(), set[j].getName(), 1d - pair.calculateSimilarity());
143             }
144         }
145         return table;
146     }
147
148     private String getGroupName(URL location){
149         String url = location.toString();
150         if(url.startsWith("jar:")){
151             url = url.substring("jar:".length(), url.lastIndexOf('!'));
152         }
153         return url;
154     }
155
156     private void setGroups(){
157         labels = new LabelMap();
158         labels.setGroupEnabled(true);
159         Item[] items = mdspane.getItems();
160         Map<String, BirthmarkSet> map = new HashMap<String, BirthmarkSet>();
161         for(BirthmarkSet s: set) map.put(s.getName(), s);
162         
163         for(Item item: items){
164             BirthmarkSet s = map.get(item.getName());
165             if(s != null){
166                 labels.addLabel(s.getName());
167                 labels.setGroup(s.getName(), getGroupName(s.getLocation()));
168             }
169             item.setGroupId(labels.getGroupIdFromElementName(item.getName()));
170         }
171     }
172
173     /**
174      * This method must called after
175      * {@link #initData(BirthmarkSet[], BirthmarkEnvironment) <code>initData</code>}.
176      * Because this method uses calculated value in initData method.
177      */
178     private void initLayouts() throws ResourceNotFoundException{
179         Table<String> table = initData(set, context);
180
181         final Messages messages = stigmata.getMessages();
182         setting = new MdsGraphSetting();
183         mdspane = new MdsPane(new MdsMethod<String>(table), setting, messages);
184         setting.setShowLabels(true);
185         setGroups();
186
187         JCheckBox check = new JCheckBox(stigmata.getMessages().get("showlabel.button.label"), true);
188         check.addActionListener(new ActionListener(){
189             @Override
190             public void actionPerformed(ActionEvent e){
191                 JCheckBox c = (JCheckBox)e.getSource();
192                 setting.setShowLabels(c.isSelected());
193             }
194         });
195         Action openSelection = new OpenItemsAction(mdspane, this);
196
197         Action clusteringAction = new ClusteringAction(mdspane);
198
199         SaveAction exportMdsImageAction = new SaveAction(stigmata,
200                 new MdsImageExporter(mdspane));
201         exportMdsImageAction.setExtensions(stigmata.getMessages().getArray("savemds.extensions"));
202         exportMdsImageAction.setDescrpition(stigmata.getMessages().get("savemds.description"));
203
204         SaveAction exportItemsAction = new SaveAction(stigmata, new MdsItemsLocationExporter(mdspane));
205         exportItemsAction.setExtensions(stigmata.getMessages().getArray("savelocation.extensions"));
206         exportItemsAction.setDescrpition(stigmata.getMessages().get("savelocation.description"));
207
208         PopupButton saveButton = new PopupButton(GUIUtility.createButton(messages, "savemds", exportMdsImageAction));
209         saveButton.addMenuItem(GUIUtility.createJMenuItem(messages, "savelocation", exportItemsAction));
210
211         JLabel numberOfDotsLabel = new JLabel(String.valueOf(set.length));
212         GUIUtility.decorateJComponent(messages, numberOfDotsLabel, "mdsgraph.count");
213
214         zoomRatio = new JTextField("100%", 5);
215         GUIUtility.decorateJComponent(messages, zoomRatio, "mdszoomratio");
216         zoomRatio.setColumns(5);
217         zoomRatio.addActionListener(new ActionListener(){
218             @Override
219             public void actionPerformed(ActionEvent e){
220                 try{
221                     String label = zoomRatio.getText();
222                     if(label.endsWith("%")){
223                         label = label.substring(0, label.lastIndexOf('%'));
224                     }
225                     label = label.trim();
226                     int ratio = Integer.parseInt(label);
227                     userInputtedValue = true;
228                     zoom(ratio);
229                 } catch(NumberFormatException exception){
230                     zoomRatio.setText(mdspane.getZoomRatio() + " %");
231                 }
232             }
233         });
234         JComboBox combo = new JComboBox();
235         combo.setRenderer(new ClippedLRListCellRenderer(new Dimension(100, combo.getPreferredSize().height), 50));
236         DrawerFactory factory = DrawerFactory.getInstance();
237         for(Map.Entry<String, Integer> entry: labels.getGroupElementCounts().entrySet()){
238             int groupId = labels.getGroupId(entry.getKey());
239             ClippedLRListCellRenderer.LRItem item = new ClippedLRListCellRenderer.LRItem(entry.getKey(), entry.getValue());
240             item.setIcon(factory.createIcon(groupId));
241             combo.addItem(item);
242         }
243         GUIUtility.decorateJComponent(messages, combo, "mdsgraph.group");
244
245         JToolBar toolbar = new JToolBar();
246         toolbar.add(new ClockwiseRotateAction(mdspane));
247         toolbar.add(new AntiClockwiseRotateAction(mdspane));
248         toolbar.add(new HorizontalFlipAction(mdspane));
249         toolbar.add(new VerticalFlipAction(mdspane));
250         toolbar.add(zoomin = new ZoomInAction(this, this));
251         toolbar.add(zoomout = new ZoomOutAction(this, this));
252         toolbar.add(new ClearAction(mdspane));
253
254         JPanel south1 = new JPanel(new GridLayout(1, 3));
255         south1.add(numberOfDotsLabel);
256         south1.add(zoomRatio);
257         south1.add(combo);
258
259         Box south2 = Box.createHorizontalBox();
260         south2.add(Box.createHorizontalGlue());
261         south2.add(saveButton);
262         south2.add(Box.createHorizontalGlue());
263         south2.add(new JButton(openSelection));
264         south2.add(Box.createHorizontalGlue());
265         south2.add(new JButton(clusteringAction));
266         south2.add(Box.createHorizontalGlue());
267         south2.add(check);
268         south2.add(Box.createHorizontalGlue());
269
270         JPanel south = new JPanel(new GridLayout(2, 1));
271         south.add(south1);
272         south.add(south2);
273
274         JPanel center = new JPanel(new FlowLayout(FlowLayout.CENTER));
275         center.addComponentListener(new ComponentAdapter(){
276             @Override
277             public void componentResized(ComponentEvent e){
278                 Dimension d = e.getComponent().getSize();
279                 mdspane.setSize(d.width - 10, d.height - 10);
280             }
281         });
282         setLayout(new BorderLayout());
283
284         center.add(mdspane);
285         JScrollPane scroll = new JScrollPane(center);
286         scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
287         scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
288
289         add(toolbar, BorderLayout.NORTH);
290         add(scroll, BorderLayout.CENTER);
291         add(south, BorderLayout.SOUTH);
292     }
293 }