1   /*
2    *  NLGLexiconVR.java
3    *
4    *  Copyright (c) 1998-2001, The University of Sheffield.
5    *
6    *  This file is part of GATE (see http://gate.ac.uk/), and is free
7    *  software, licenced under the GNU Library General Public License,
8    *  Version 2, June 1991 (in the distribution as file licence.html,
9    *  and also available at http://gate.ac.uk/gate/licence.html).
10   *
11   *  Kalina Bontcheva, 20/02/2003
12   *
13   *  $Id: NLGLexiconVR.java,v 1.5 2003/03/03 19:07:22 kalina Exp $
14   */
15  package gate.gui.lexicon;
16  
17  import gate.creole.*;
18  import gate.lexicon.*;
19  import gate.util.GateRuntimeException;
20  import javax.swing.*;
21  import java.awt.*;
22  import java.awt.event.ActionEvent;
23  import java.awt.event.ActionListener;
24  import java.awt.event.*;
25  import java.util.*;
26  import gate.util.*;
27  import gate.gui.OkCancelDialog;
28  import javax.swing.event.ListSelectionListener;
29  import javax.swing.event.ListSelectionEvent;
30  
31  public class NLGLexiconVR extends AbstractVisualResource {
32    public NLGLexiconVR() {
33      initLocalData();
34      initGuiComponents();
35      initListeners();
36    }
37  
38    protected void initLocalData(){
39      this.addSenseAction = new AddSenseAction();
40      this.lookupLemmaAction = new LookupLemmaAction();
41      this.addWordAction = new AddWordAction();
42      this.removeSenseAction = new RemoveSenseAction();
43    }
44  
45    protected void initGuiComponents(){
46      sensesListModel = new DefaultListModel();
47      sensesList = new JList(sensesListModel);
48      synsetListModel = new DefaultListModel();
49      synsetEntriesList = new JList(synsetListModel);
50      mainBox = Box.createHorizontalBox();
51      leftBox = Box.createVerticalBox();
52      rightBox = Box.createVerticalBox();
53      buttonBox = Box.createHorizontalBox();
54      definitionTextArea.setPreferredSize(new Dimension(69, 50));
55      definitionTextArea.setToolTipText("");
56      definitionTextArea.setText("");
57      definitionTextArea.setWrapStyleWord(true);
58      definitionTextLabel.setText("Definition");
59      lemmaTextLabel.setText("Lemma");
60      this.setLayout(gridLayout1);
61      this.setAlignmentX((float) 0.5);
62      this.setDebugGraphicsOptions(0);
63      lemmaTextField.setText("");
64      lemmaTextField.setMaximumSize(new Dimension(Integer.MAX_VALUE,
65                                      lemmaTextField.getPreferredSize().height));
66      SynsetTextLabel.setText("Synset Entries");
67      synsetEntriesList.setSelectedIndex(-1);
68      synsetEntriesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
69      POSTextLabel.setText("Part of Speech");
70  
71      posString.setMaximumSize(new Dimension(Integer.MAX_VALUE,
72                                      posString.getPreferredSize().height));
73  
74      sensesTextLabel.setText("Senses");
75      addSenseButton = new JButton(addSenseAction);
76      addSenseButton.setText("Add Sense");
77      removeSenseButton = new JButton(removeSenseAction);
78      removeSenseButton.setText("Remove Sense");
79  
80      addWordButton = new JButton(addWordAction);
81      addWordButton.setText("Add Word");
82  
83      lookupButton = new JButton(lookupLemmaAction);
84      lookupButton.setText("Lookup");
85  
86      this.add(mainBox, null);
87      mainBox.add(leftBox, null);
88      leftBox.add(lemmaTextLabel, null);
89      leftBox.add(lemmaTextField, null);
90  
91      buttonBox.add(lookupButton);
92      buttonBox.add(Box.createHorizontalStrut(20));
93      buttonBox.add(addWordButton);
94  
95      leftBox.add(buttonBox);
96      mainBox.add(rightBox, null);
97      rightBox.add(POSTextLabel, null);
98      rightBox.add(posString, null);
99      rightBox.add(SynsetTextLabel, null);
100     rightBox.add(synsetScrollPane, null);
101     synsetScrollPane.getViewport().add(synsetEntriesList, null);
102     rightBox.add(definitionTextLabel, null);
103     rightBox.add(definitionTextArea, null);
104     leftBox.add(sensesTextLabel, null);
105     leftBox.add(sensesScrollPane, null);
106     sensesScrollPane.getViewport().add(sensesList, null);
107 
108     Box senseButtonsBox = Box.createHorizontalBox();
109     senseButtonsBox.add(addSenseButton, null);
110     senseButtonsBox.add(Box.createHorizontalStrut(20));
111     senseButtonsBox.add(removeSenseButton, null);
112     leftBox.add(senseButtonsBox);
113 
114     leftBox.add(Box.createVerticalGlue());
115     rightBox.add(Box.createVerticalGlue());
116     mainBox.add(Box.createVerticalGlue());
117   }
118 
119   protected void initListeners(){
120     this.sensesList.addListSelectionListener(new ListSelectionListener(){
121       public void valueChanged(ListSelectionEvent event) {
122         LexKBWordSense wordSense = (LexKBWordSense) sensesList.getSelectedValue();
123         updateRightGUI(wordSense);
124       }
125     });
126   }
127 
128   /**
129  * Called by the GUI when this viewer/editor has to initialise itself for a
130  * specific object.
131  * @param target the object (be it a {@link gate.Resource},
132  * {@link gate.DataStore} or whatever) this viewer has to display
133  */
134   public void setTarget(Object target) {
135     if(target == null) return;
136     if(!(target instanceof gate.lexicon.MutableLexicalKnowledgeBase)){
137       throw new GateRuntimeException(this.getClass().getName() +
138                                      " can only be used to display " +
139                                      MutableLexicalKnowledgeBase.class.getName() +
140                                      "\n" + target.getClass().getName() +
141                                      " is not a " +
142                                      MutableLexicalKnowledgeBase.class.getName() + "!");
143     }
144 
145     this.lexKB = (MutableLexicalKnowledgeBase)target;
146   }
147 
148   public void cleanup() {
149     super.cleanup();
150     lexKB = null;
151   }
152 
153   public static void main(String[] args) {
154 
155   JFrame frame = new JFrame();
156 
157   frame.setSize(250, 200);
158 
159   frame.setLocation(200, 300);
160   frame.getContentPane().add(new NLGLexiconVR());
161   frame.pack();
162 
163   frame.setVisible(true);
164 
165   }//main
166 
167   protected void updateLeftGUI(String lemma){
168     if (lexKB == null) return;
169     java.util.List senses = lexKB.lookupWord(lemma);
170 
171     sensesListModel.clear();
172     synsetListModel.clear();
173     definitionTextArea.setText("");
174     posString.setText("");
175     if (senses == null || senses.isEmpty()) {
176     } else {
177       for (int i= 0; i < senses.size(); i++) {
178         LexKBWordSense sense = (LexKBWordSense) senses.get(i);
179         NLGLexiconVR.this.sensesListModel.addElement(sense);
180         if (senses.size() == 1)
181           updateRightGUI(sense);
182       }//for loop through senses
183     }
184   }
185 
186   protected void updateRightGUI(LexKBWordSense sense) {
187     synsetListModel.clear();
188     posString.setText("");
189     if (sense == null || lexKB == null)
190       return;
191     LexKBSynset synset = sense.getSynset();
192     this.definitionTextArea.setText(synset.getDefinition());
193     this.posString.setText(synset.getPOS().toString());
194     this.posString.setEnabled(false);
195     for (int i = 0; i < synset.getWordSenses().size(); i++) {
196       LexKBWordSense senseI = synset.getWordSense(i);
197       synsetListModel.addElement(senseI);
198     }
199 
200   }//updateRightGUI
201 
202   /**
203    * Adds an element to the list from the editing component located at the top
204    * of this dialog.
205    */
206   protected class AddSenseAction extends AbstractAction{
207     AddSenseAction(){
208       super("AddSense");
209       putValue(SHORT_DESCRIPTION, "Add a sense");
210     }
211     public void actionPerformed(ActionEvent e){
212       if (NLGLexiconVR.this.lexKB == null)
213         return;
214 
215       String lemma = NLGLexiconVR.this.lemmaTextField.getText();
216       java.util.List wordSenses = (java.util.List) lexKB.lookupWord(lemma);
217       if (wordSenses == null || wordSenses.isEmpty()) {
218         JOptionPane.showMessageDialog(
219             NLGLexiconVR.this,
220             "Please add this word to the lexicon first",
221             "Message", JOptionPane.INFORMATION_MESSAGE);
222         return;
223       }
224 
225       Word theWord = ((LexKBWordSense) wordSenses.get(0)).getWord();
226       if (! (theWord instanceof MutableWord))
227         throw new GateRuntimeException("Cannot modify read-only lexicon!");
228 
229       MutableWord myWord = (MutableWord) theWord;
230 
231       ChooseSynsetPanel chooseSynsetPanel = new ChooseSynsetPanel(lexKB);
232       OkCancelDialog.showDialog(NLGLexiconVR.this, chooseSynsetPanel,
233                                 "Choose/Add synset for new word sense of: "
234                                 + theWord.getLemma());
235 
236       LexKBSynset newSynset = chooseSynsetPanel.getSelectedSynset();
237       if (! (newSynset instanceof MutableLexKBSynset))
238         throw new GateRuntimeException("Cannot modify read-only lexicon!");
239 
240       //now add the new sense for this word given the synset
241       myWord.addSense((MutableLexKBSynset) newSynset);
242 
243       NLGLexiconVR.this.updateLeftGUI(lemma);
244     }//actionPerformed
245   }
246 
247   /**
248    * Removes the selected sense from the lexicon
249    */
250   protected class RemoveSenseAction extends AbstractAction{
251     RemoveSenseAction(){
252       super("RemoveSense");
253       putValue(SHORT_DESCRIPTION, "Remove the selected sense");
254     }
255     public void actionPerformed(ActionEvent e){
256       if (NLGLexiconVR.this.lexKB == null)
257         return;
258       LexKBWordSense theSense = (LexKBWordSense) sensesList.getSelectedValue();
259       Word theWord = theSense.getWord();
260       if (!( theWord instanceof MutableWord)) {
261         Out.prln("Cannot edit a read-only word/lexicon");
262         return;
263       }
264       ((MutableWord)theWord).removeSense(theSense);
265 
266       NLGLexiconVR.this.updateLeftGUI(lemmaTextField.getText());
267     }//actionPerformed
268   }
269 
270 
271   /**
272    * Adds an element to the list from the editing component located at the top
273    * of this dialog.
274    */
275   protected class AddWordAction extends AbstractAction{
276     AddWordAction(){
277       super("AddWord");
278       putValue(SHORT_DESCRIPTION, "Add a word to the lexicon");
279     }
280     public void actionPerformed(ActionEvent e){
281       if (NLGLexiconVR.this.lexKB == null)
282         return;
283 
284       String lemma = NLGLexiconVR.this.lemmaTextField.getText();
285       MutableWord newWord =
286         NLGLexiconVR.this.lexKB.addWord(lemma);
287 
288     ChooseSynsetPanel chooseSynsetPanel = new ChooseSynsetPanel(lexKB);
289     boolean okPressed =
290         OkCancelDialog.showDialog(NLGLexiconVR.this, chooseSynsetPanel,
291                               "Choose/Add synset for new word sense of: "
292                               + newWord.getLemma());
293     if (! okPressed)
294       return;
295 
296     LexKBSynset newSynset = chooseSynsetPanel.getSelectedSynset();
297     if (newSynset == null)
298       return;
299     if (! (newSynset instanceof MutableLexKBSynset))
300       throw new GateRuntimeException("Cannot modify read-only lexicon!");
301 
302       //now add the new sense for this word given the synset
303       newWord.addSense((MutableLexKBSynset)newSynset);
304 
305       NLGLexiconVR.this.updateLeftGUI(lemma);
306     }//actionPerformed
307   }
308 
309   /**
310    * Lookup the lemma in the lexicon
311    */
312   protected class LookupLemmaAction extends AbstractAction{
313     LookupLemmaAction(){
314       super("LookupLemma");
315       putValue(SHORT_DESCRIPTION, "Lookup a lemma");
316     }
317     public void actionPerformed(ActionEvent e){
318       String lemma = lemmaTextField.getText();
319       updateLeftGUI(lemma);
320     }//actionPerformed
321   }
322 
323   protected MutableLexicalKnowledgeBase lexKB;
324   protected GridLayout gridLayout1 = new GridLayout();
325   protected Box mainBox;
326   protected Box leftBox;
327   protected Box rightBox;
328   protected Box buttonBox;
329   protected JLabel lemmaTextLabel = new JLabel();
330   protected JTextField lemmaTextField = new JTextField(30);
331   protected JLabel SynsetTextLabel = new JLabel();
332   protected JScrollPane synsetScrollPane = new JScrollPane();
333   protected JLabel definitionTextLabel = new JLabel();
334   protected JTextArea definitionTextArea = new JTextArea();
335   protected JList synsetEntriesList = new JList();
336   protected DefaultListModel synsetListModel;
337   protected JLabel POSTextLabel = new JLabel();
338   protected JTextField posString = new JTextField(30);
339   protected JLabel sensesTextLabel = new JLabel();
340   protected JScrollPane sensesScrollPane = new JScrollPane();
341   protected JList sensesList;
342   protected DefaultListModel sensesListModel;
343   protected JButton addSenseButton;
344   /**
345     * An action that adds a new sense to the lexicon
346     */
347    protected Action addSenseAction;
348 
349    protected JButton removeSenseButton;
350    /**
351      * An action that removes a sense from the lexicon
352      */
353     protected Action removeSenseAction;
354 
355    protected JButton lookupButton;
356    /**
357      * An action that looks up a lemma in the lexicon
358      */
359     protected Action lookupLemmaAction;
360 
361     protected JButton addWordButton;
362     /**
363       * An action that adds a new word to the lexicon
364       */
365      protected Action addWordAction;
366 
367 }
368 
369