1   /*
2    *  Copyright (c) 1998-2005, The University of Sheffield.
3    *
4    *  This file is part of GATE (see http://gate.ac.uk/), and is free
5    *  software, licenced under the GNU Library General Public License,
6    *  Version 2, June 1991 (in the distribution as file licence.html,
7    *  and also available at http://gate.ac.uk/gate/licence.html).
8    *
9    *  Valentin Tablan 12/07/2001
10   *
11   *  $Id: CorpusEditor.java,v 1.22 2005/01/11 13:51:34 ian Exp $
12   *
13   */
14  package gate.gui;
15  
16  import java.awt.BorderLayout;
17  import java.awt.Component;
18  import java.awt.event.*;
19  import java.util.Iterator;
20  import java.util.Vector;
21  
22  import javax.swing.*;
23  
24  import gate.*;
25  import gate.creole.AbstractVisualResource;
26  import gate.event.CorpusEvent;
27  import gate.event.CorpusListener;
28  import gate.util.GateException;
29  import gate.util.GateRuntimeException;
30  
31  /**
32   * A simple viewer/editor for corpora. It will allow the visualisation of the
33   * list of documents inside a corpus along withe their features.
34   * It will also allow addition and removal of documents.
35   */
36  public class CorpusEditor extends AbstractVisualResource implements CorpusListener {
37  
38    public Resource init(){
39      initLocalData();
40      initGuiComponents();
41      initListeners();
42      return this;
43    }
44  
45  
46    protected void initLocalData(){
47      docListModel = new DefaultListModel();
48    }
49  
50    protected void initGuiComponents(){
51      setLayout(new BorderLayout());
52  
53      documentsList = new JList(docListModel);
54      documentsList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
55      listRenderer = new DocumentListCellRenderer();
56      documentsList.setCellRenderer(listRenderer);
57      JScrollPane listScroll = new JScrollPane(documentsList);
58  
59  //    featuresEditor = new FeaturesEditor();
60  //    JScrollPane fEdScroll = new JScrollPane(featuresEditor);
61  //
62  //    JSplitPane mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
63  //                                          listScroll, fEdScroll);
64  //    mainSplit.setDividerLocation(0.30);
65  //    add(mainSplit, BorderLayout.CENTER);
66  
67      add(listScroll, BorderLayout.CENTER);
68  
69      toolbar = new JToolBar();
70      toolbar.setFloatable(false);
71      toolbar.add(new NewDocumentAction());
72      toolbar.add(new RemoveDocumentsAction());
73  
74      add(toolbar, BorderLayout.NORTH);
75    }
76  
77    protected void initListeners(){
78  /*
79  //kalina: I commented it, because we want the corpus viewer to show only the
80  //document names and not add the documents to memory
81      documentsList.addListSelectionListener(new ListSelectionListener(){
82        public void valueChanged(ListSelectionEvent e){
83          featuresEditor.setTarget(
84            (docListModel.isEmpty() || documentsList.getSelectedIndex() == -1) ?
85            null : docListModel.get(documentsList.getSelectedIndex())
86          );
87        }
88      });
89  */
90      documentsList.addMouseListener(new MouseAdapter() {
91        public void mouseClicked(MouseEvent e) {
92          if(SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2){
93            int row = documentsList.locationToIndex(e.getPoint());
94            if(row != -1){
95              Document doc = (Document) corpus.get(row);
96              //try to select the document in the main frame
97              Component root = SwingUtilities.getRoot(CorpusEditor.this);
98              if(root instanceof MainFrame){
99                MainFrame mainFrame = (MainFrame)root;
100               mainFrame.select(doc);
101             }
102           }
103         }
104       }
105 
106       public void mousePressed(MouseEvent e) {
107       }
108 
109       public void mouseReleased(MouseEvent e) {
110       }
111 
112       public void mouseEntered(MouseEvent e) {
113       }
114 
115       public void mouseExited(MouseEvent e) {
116       }
117     });
118   }
119 
120   public void cleanup(){
121     super.cleanup();
122     corpus = null;
123 
124   }
125 
126   public void setTarget(Object target){
127     if(!(target instanceof Corpus)){
128       throw new IllegalArgumentException(
129         "The GATE corpus editor can only be used with a GATE corpus!\n" +
130         target.getClass().toString() + " is not a GATE corpus!");
131     }
132     this.corpus = (Corpus)target;
133     corpus.addCorpusListener(this);
134 
135     docListModel.clear();
136     java.util.List docNamesList = corpus.getDocumentNames();
137     Iterator namesIter = docNamesList.iterator();
138     while(namesIter.hasNext()){
139       String docName = (String) namesIter.next();
140       docListModel.addElement(docName);
141     }
142 
143     if(!docListModel.isEmpty())
144       SwingUtilities.invokeLater(new Runnable(){
145         public void run(){
146           documentsList.setSelectedIndex(0);
147         }
148       });
149   }
150 
151   public void documentAdded(final CorpusEvent e) {
152     SwingUtilities.invokeLater(new Runnable(){
153       public void run(){
154         //a new document has been added to the corpus
155         Document doc = e.getDocument();
156         docListModel.addElement(doc.getName());
157       }
158     });
159   }
160 
161   public void documentRemoved(final CorpusEvent e) {
162     SwingUtilities.invokeLater(new Runnable(){
163       public void run(){
164         docListModel.removeElementAt(e.getDocumentIndex());
165       }
166     });
167   }
168 
169 
170   class DocumentListCellRenderer extends DefaultListCellRenderer{
171     public Component getListCellRendererComponent(JList list,
172                                               Object value,
173                                               int index,
174                                               boolean isSelected,
175                                               boolean cellHasFocus){
176       //prepare the renderer
177       String docName = (String)value;
178       super.getListCellRendererComponent(list, docName, index,
179                                          isSelected, cellHasFocus);
180       setIcon(MainFrame.getIcon("lr.gif"));
181       return this;
182     }
183   }
184 
185 
186   class NewDocumentAction extends AbstractAction{
187     public NewDocumentAction(){
188       super("Add document", MainFrame.getIcon("add.gif"));
189       putValue(SHORT_DESCRIPTION, "Add a new document to this corpus");
190     }
191 
192     public void actionPerformed(ActionEvent e){
193       try{
194         //get all the documents loaded in the system
195         java.util.List loadedDocuments = Gate.getCreoleRegister().
196                                getAllInstances("gate.Document");
197         if(loadedDocuments == null || loadedDocuments.isEmpty()){
198           JOptionPane.showMessageDialog(
199               CorpusEditor.this,
200               "There are no documents available in the system!\n" +
201               "Please load some and try again!" ,
202               "GATE", JOptionPane.ERROR_MESSAGE);
203           return;
204         }
205 
206         Vector docNames = new Vector(loadedDocuments.size());
207         for (int i = 0; i< loadedDocuments.size(); i++) {
208           docNames.add(((Document)loadedDocuments.get(i)).getName());
209         }
210         JList docList = new JList(docNames);
211         docList.setCellRenderer(listRenderer);
212 
213         JOptionPane dialog = new JOptionPane(new JScrollPane(docList),
214                                              JOptionPane.QUESTION_MESSAGE,
215                                              JOptionPane.OK_CANCEL_OPTION);
216         dialog.createDialog(CorpusEditor.this,
217                             "Add document(s) to corpus").setVisible(true);
218 
219         if(((Integer)dialog.getValue()).intValue() == JOptionPane.OK_OPTION){
220           int[] selection = docList.getSelectedIndices();
221           for (int i = 0; i< selection.length ; i++) {
222             corpus.add(loadedDocuments.get(selection[i]));
223           }
224         }
225       }catch(GateException ge){
226         //gate.Document is not registered in creole.xml....what is!?
227         throw new GateRuntimeException(
228           "gate.Document is not registered in the creole register!\n" +
229           "Something must be terribly wrong...take a vacation!");
230       }
231     }
232   }//class NewDocumentAction extends AbstractAction
233 
234   class RemoveDocumentsAction extends AbstractAction{
235     public RemoveDocumentsAction(){
236       super("Remove documents", MainFrame.getIcon("remove.gif"));
237       putValue(SHORT_DESCRIPTION, "Removes selected documents from this corpus");
238     }
239 
240     public void actionPerformed(ActionEvent e){
241       int[] selectedIndexes = documentsList.getSelectedIndices();
242       for(int i = selectedIndexes.length-1; i >= 0; i--){
243         corpus.remove(selectedIndexes[i]);
244       }
245       documentsList.clearSelection();
246     }
247   }//class RemoveDocumentsAction extends AbstractAction
248 
249 
250   JList documentsList;
251   DocumentListCellRenderer listRenderer;
252   FeaturesEditor featuresEditor;
253   JToolBar toolbar;
254   Corpus corpus;
255   DefaultListModel docListModel;
256 }
257