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