KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > rice > cs > drjava > ui > RegionsListPanel


1 /*BEGIN_COPYRIGHT_BLOCK
2  *
3  * This file is part of DrJava. Download the current version of this project from http://www.drjava.org/
4  * or http://sourceforge.net/projects/drjava/
5  *
6  * DrJava Open Source License
7  *
8  * Copyright (C) 2001-2005 JavaPLT group at Rice University (javaplt@rice.edu). All rights reserved.
9  *
10  * Developed by: Java Programming Languages Team, Rice University, http://www.cs.rice.edu/~javaplt/
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13  * documentation files (the "Software"), to deal with the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
15  * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16  *
17  * - Redistributions of source code must retain the above copyright notice, this list of conditions and the
18  * following disclaimers.
19  * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
20  * following disclaimers in the documentation and/or other materials provided with the distribution.
21  * - Neither the names of DrJava, the JavaPLT, Rice University, nor the names of its contributors may be used to
22  * endorse or promote products derived from this Software without specific prior written permission.
23  * - Products derived from this software may not be called "DrJava" nor use the term "DrJava" as part of their
24  * names without prior written permission from the JavaPLT group. For permission, write to javaplt@rice.edu.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
27  * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28  * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
29  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30  * WITH THE SOFTWARE.
31  *
32  *END_COPYRIGHT_BLOCK*/

33
34 package edu.rice.cs.drjava.ui;
35
36 import java.util.List JavaDoc;
37 import java.util.ArrayList JavaDoc;
38 import java.util.LinkedList JavaDoc;
39 import java.util.Enumeration JavaDoc;
40 import java.io.*;
41
42 import javax.swing.*;
43 import javax.swing.event.*;
44 import javax.swing.table.*;
45 import javax.swing.text.*;
46 import javax.swing.plaf.*;
47 import javax.swing.plaf.basic.BasicToolTipUI JavaDoc;
48 import java.awt.event.*;
49 import java.awt.font.*;
50 import java.awt.*;
51
52 import edu.rice.cs.drjava.config.OptionConstants;
53 import edu.rice.cs.drjava.model.DocumentRegion;
54 import edu.rice.cs.drjava.model.SingleDisplayModel;
55 import edu.rice.cs.drjava.model.debug.*;
56 import edu.rice.cs.drjava.model.OpenDefinitionsDocument;
57 import edu.rice.cs.drjava.model.definitions.ClassNameNotFoundException;
58 import edu.rice.cs.drjava.config.*;
59 import edu.rice.cs.drjava.DrJava;
60 import edu.rice.cs.util.swing.Utilities;
61 import edu.rice.cs.util.UnexpectedException;
62 import edu.rice.cs.util.StringOps;
63 import edu.rice.cs.util.swing.RightClickMouseAdapter;
64
65 /**
66  * Panel for displaying regions in a list sorted by time of creation.
67  * This class is a swing view class and hence should only be accessed from the event-handling thread.
68  * @version $Id$
69  */

70 public abstract class RegionsListPanel<R extends DocumentRegion> extends TabbedPanel {
71   protected JPanel _leftPane;
72   
73   protected JList _list;
74   protected DefaultListModel _listModel;
75   protected String JavaDoc _title;
76   
77   protected final SingleDisplayModel _model;
78   protected final MainFrame _frame;
79   
80   protected JPanel _buttonPanel;
81   
82   /** Constructs a new panel to display regions in a list.
83    * This is swing view class and hence should only be accessed from the event-handling thread.
84    * @param frame the MainFrame
85    * @param title title of the pane
86    */

87   public RegionsListPanel(MainFrame frame, String JavaDoc title) {
88     super(frame, title);
89     _title = title;
90     this.setLayout(new BorderLayout());
91     
92     _frame = frame;
93     _model = frame.getModel();
94     
95     this.removeAll(); // override the behavior of TabbedPanel
96

97     // remake closePanel
98
_closePanel = new JPanel(new BorderLayout());
99     _closePanel.add(_closeButton, BorderLayout.NORTH);
100     
101     _leftPane = new JPanel(new BorderLayout());
102     _setupRegionList();
103     
104     this.add(_leftPane, BorderLayout.CENTER);
105     
106     _buttonPanel = new JPanel(new BorderLayout());
107     _setupButtonPanel();
108     this.add(_buttonPanel, BorderLayout.EAST);
109     updateButtons();
110     
111     // Setup the color listeners.
112
_setColors(_list);
113     
114     _list.addMouseListener(new RegionMouseAdapter());
115   }
116   
117   /** Quick helper for setting up color listeners. */
118   private static void _setColors(Component c) {
119     new ForegroundColorListener(c);
120     new BackgroundColorListener(c);
121   }
122   
123   /** Close the pane. */
124   protected void _close() {
125     super._close();
126     updateButtons();
127   }
128   
129   /** Creates the region list. */
130   private void _setupRegionList() {
131     _listModel = new DefaultListModel();
132     _list = new JList(_listModel) {
133       public String JavaDoc getToolTipText(MouseEvent evt) {
134         // Get item
135
int index = locationToIndex(evt.getPoint());
136         
137         @SuppressWarnings JavaDoc("unchecked") RegionListUserObj<R> node = (RegionListUserObj<R>)getModel().getElementAt(index);
138         R r = node.region();
139         String JavaDoc tooltip = null;
140         
141         OpenDefinitionsDocument doc = r.getDocument();
142         doc.acquireReadLock();
143         try {
144           int lnr = doc.getLineOfOffset(r.getStartOffset())+1;
145           int startOffset = doc.getOffset(lnr-3);
146           if (startOffset<0) { startOffset = 0; }
147           int endOffset = doc.getOffset(lnr+3);
148           if (endOffset<0) { endOffset = doc.getLength()-1; }
149           
150           // convert to HTML (i.e. < to &lt; and > to &gt; and newlines to <br>)
151
String JavaDoc s = doc.getText(startOffset, endOffset-startOffset);
152           
153           // this highlights the actual region in red
154
int rStart = r.getStartOffset()-startOffset;
155           if (rStart<0) { rStart = 0; }
156           int rEnd = r.getEndOffset()-startOffset;
157           if (rEnd>s.length()) { rEnd = s.length(); }
158           if ((rStart<=s.length()) && (rEnd>=rStart)) {
159             String JavaDoc t1 = StringOps.encodeHTML(s.substring(0,rStart));
160             String JavaDoc t2 = StringOps.encodeHTML(s.substring(rStart,rEnd));
161             String JavaDoc t3 = StringOps.encodeHTML(s.substring(rEnd));
162             s = t1 + "<font color=#ff0000>" + t2 + "</font>" + t3;
163           }
164           else {
165             s = StringOps.encodeHTML(s);
166           }
167           tooltip = "<html><pre>"+s+"</pre></html>";
168         }
169         catch(javax.swing.text.BadLocationException JavaDoc ble) { tooltip = null; /* just don't give a tool tip */ }
170         finally { doc.releaseReadLock(); }
171         return tooltip;
172       }
173     };
174     _list.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
175     _list.addListSelectionListener(new ListSelectionListener() {
176       public void valueChanged(ListSelectionEvent e) {
177         updateButtons();
178       }
179     });
180     _list.addKeyListener(new KeyAdapter() {
181       public void keyPressed(KeyEvent e) {
182         if (e.getKeyCode() == KeyEvent.VK_ENTER) {
183           performDefaultAction();
184         }
185       }
186     });
187     _list.setFont(DrJava.getConfig().getSetting(OptionConstants.FONT_DOCLIST));
188     
189     _leftPane.add(new JScrollPane(_list));
190     ToolTipManager.sharedInstance().registerComponent(_list);
191   }
192   
193   /** Update button state and text. Should be overridden if additional buttons are added besides "Go To", "Remove" and "Remove All". */
194   protected void updateButtons() {
195   }
196   
197   /** Action performed when the Enter key is pressed. Should be overridden. */
198   protected void performDefaultAction() {
199   }
200   
201   /** Creates the buttons for controlling the regions. Should be overridden. */
202   protected JComponent[] makeButtons() {
203     return new JComponent[0];
204   }
205   
206   /** Creates the buttons for controlling the regions. */
207   private void _setupButtonPanel() {
208     JPanel mainButtons = new JPanel();
209     JPanel emptyPanel = new JPanel();
210     JPanel closeButtonPanel = new JPanel(new BorderLayout());
211     GridBagLayout gbLayout = new GridBagLayout();
212     GridBagConstraints c = new GridBagConstraints();
213     mainButtons.setLayout(gbLayout);
214     
215     JComponent[] buts = makeButtons();
216
217     closeButtonPanel.add(_closeButton, BorderLayout.NORTH);
218     for (JComponent b: buts) { mainButtons.add(b); }
219     mainButtons.add(emptyPanel);
220     
221     c.fill = GridBagConstraints.HORIZONTAL;
222     c.anchor = GridBagConstraints.NORTH;
223     c.gridwidth = GridBagConstraints.REMAINDER;
224     c.weightx = 1.0;
225
226     for (JComponent b: buts) { gbLayout.setConstraints(b, c); }
227     
228     c.fill = GridBagConstraints.BOTH;
229     c.anchor = GridBagConstraints.SOUTH;
230     c.gridheight = GridBagConstraints.REMAINDER;
231     c.weighty = 1.0;
232     
233     gbLayout.setConstraints(emptyPanel, c);
234     
235     _buttonPanel.add(mainButtons, BorderLayout.CENTER);
236     _buttonPanel.add(closeButtonPanel, BorderLayout.EAST);
237   }
238   
239   /** Gets the currently selected regions in the region list, or an empty array if no regions are selected.
240    * @return list of selected regions in the list
241    */

242   protected ArrayList JavaDoc<R> getSelectedRegions() {
243     ArrayList JavaDoc<R> regs = new ArrayList JavaDoc<R>();
244     int[] indices = _list.getSelectedIndices();
245     if (indices!=null) {
246       for (int index: indices) {
247         @SuppressWarnings JavaDoc("unchecked") RegionListUserObj<R> userObj = ((RegionListUserObj<R>)_listModel.elementAt(index));
248         R r = userObj.region();
249         regs.add(r);
250       }
251     }
252     return regs;
253   }
254   
255   /** Go to region. */
256   protected void goToRegion() {
257     ArrayList JavaDoc<R> r = getSelectedRegions();
258     if (r.size() == 1) {
259       RegionListUserObj<R> userObj = getUserObjForRegion(r.get(0));
260       if (userObj!=null) { _list.ensureIndexIsVisible(_listModel.indexOf(userObj)); }
261       _frame.scrollToDocumentAndOffset(r.get(0).getDocument(), r.get(0).getStartOffset(), false);
262     }
263   }
264   
265   /** @return the usser object in the list associated with the region, or null if not found */
266   protected RegionListUserObj<R> getUserObjForRegion(R r) {
267     for(int i=0; i<_listModel.size(); ++i) {
268       @SuppressWarnings JavaDoc("unchecked") RegionListUserObj<R> userObj = (RegionListUserObj<R>)_listModel.get(i);
269       if ((userObj.region().getStartOffset()==r.getStartOffset()) &&
270           (userObj.region().getEndOffset()==r.getEndOffset()) &&
271           (userObj.region().getDocument().equals(r.getDocument()))) {
272         return userObj;
273       }
274     }
275     return null;
276   }
277     
278   /** Add a region to the list. Must be executed in event thread.
279    * @param r the region
280    * @param index the index where the region should be inserted
281    */

282   public void addRegion(final R r, final int index) {
283     // Only change GUI from event-dispatching thread
284
Runnable JavaDoc doCommand = new Runnable JavaDoc() {
285       public void run() {
286 // edu.rice.cs.drjava.model.AbstractGlobalModel.log.log("RegionsListPanel.addRegion: in list were...");
287
// for(int i=0;i<_listModel.getSize();++i) { edu.rice.cs.drjava.model.AbstractGlobalModel.log.log("\t"+_listModel.elementAt(i)); }
288

289         String JavaDoc name = "";
290         try { name = r.getDocument().getQualifiedClassName(); }
291         catch (ClassNameNotFoundException cnnfe) { name = r.getDocument().toString(); }
292         
293         RegionListUserObj<R> userObj = makeRegionListUserObj(r);
294         _listModel.add(index, userObj);
295         _list.ensureIndexIsVisible(_listModel.indexOf(userObj));
296         
297         updateButtons();
298       }
299     };
300     Utilities.invokeLater(doCommand);
301   }
302   
303   /** Remove a region from the tree. Must be executed in event thread.
304    * @param r the region
305    */

306   public void removeRegion(final R r) {
307     // Only change GUI from event-dispatching thread
308
Runnable JavaDoc doCommand = new Runnable JavaDoc() {
309       public void run() {
310         String JavaDoc name = "";
311         try {
312           name = r.getDocument().getQualifiedClassName();
313         }
314         catch (ClassNameNotFoundException cnnfe) {
315           name = r.getDocument().toString();
316         }
317         
318         for(int i=0; i<_listModel.size(); ++i) {
319           @SuppressWarnings JavaDoc("unchecked") RegionListUserObj<R> userObj = (RegionListUserObj<R>)_listModel.get(i);
320           if (userObj.region()==r) {
321             _listModel.removeElementAt(i);
322             break;
323           }
324         }
325         
326         updateButtons();
327       }
328     };
329     Utilities.invokeLater(doCommand);
330   }
331   
332   /** Remove all regions for this document from the tree. Must be executed in event thread.
333    */

334   public void removeRegions(final OpenDefinitionsDocument odd) {
335     // Only change GUI from event-dispatching thread
336
Runnable JavaDoc doCommand = new Runnable JavaDoc() {
337       public void run() {
338         String JavaDoc name = "";
339         try {
340           name = odd.getQualifiedClassName();
341         }
342         catch (ClassNameNotFoundException cnnfe) {
343           name = odd.toString();
344         }
345         
346         for(int i=0; i<_listModel.size(); ++i) {
347           @SuppressWarnings JavaDoc("unchecked") RegionListUserObj<R> userObj = (RegionListUserObj<R>)_listModel.get(i);
348           
349           if (userObj.region().getDocument().equals(odd)) {
350             _listModel.removeElementAt(i);
351           }
352         }
353
354         updateButtons();
355       }
356     };
357     Utilities.invokeLater(doCommand);
358   }
359   
360   /** Factory method to create user objects put in the list.
361    * If subclasses extend RegionListUserObj, they need to override this method. */

362   protected RegionListUserObj<R> makeRegionListUserObj(R r) {
363     return new RegionListUserObj<R>(r);
364   }
365   
366   /** Class that gets put into the list. The toString() method determines what's displayed in the three. */
367   protected static class RegionListUserObj<R extends DocumentRegion> {
368     protected R _region;
369     public int lineNumber() { return _region.getDocument().getLineOfOffset(_region.getStartOffset())+1; }
370     public R region() { return _region; }
371     public RegionListUserObj(R r) { _region = r; }
372     public String JavaDoc toString() {
373       final StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
374       _region.getDocument().acquireReadLock();
375       try {
376         sb.append(_region.getDocument().toString());
377         sb.append(':');
378         sb.append(lineNumber());
379         try {
380           sb.append(": ");
381           int length = Math.min(120, _region.getEndOffset()-_region.getStartOffset());
382           sb.append(_region.getDocument().getText(_region.getStartOffset(), length).trim());
383         } catch(BadLocationException bpe) { /* ignore, just don't display line */ }
384       } finally { _region.getDocument().releaseReadLock(); }
385       return sb.toString();
386     }
387     public boolean equals(Object JavaDoc other) {
388       @SuppressWarnings JavaDoc("unchecked") RegionListUserObj<R> o = (RegionListUserObj<R>)other;
389       return (o.region().getDocument().equals(region().getDocument())) &&
390         (o.region().getStartOffset()==region().getStartOffset()) &&
391         (o.region().getEndOffset()==region().getEndOffset());
392     }
393   }
394   
395   
396   /**
397    * Mouse adapter for the region tree.
398    */

399   protected class RegionMouseAdapter extends RightClickMouseAdapter {
400     protected void _popupAction(MouseEvent e) {
401       // TODO: add popup
402
}
403     
404     public void mousePressed(MouseEvent e) {
405       super.mousePressed(e);
406       if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
407         performDefaultAction();
408       }
409     }
410   }
411
412 }
413
Popular Tags