Clover coverage report - DrJava Test Coverage (drjava-20120304-r5456)
Coverage timestamp: Sun Mar 4 2012 03:13:23 CST
file stats: LOC: 389   Methods: 23
NCLOC: 208   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
RegionsListPanel.java 0% 0% 0% 0%
coverage
 1    /*BEGIN_COPYRIGHT_BLOCK
 2    *
 3    * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu)
 4    * All rights reserved.
 5    *
 6    * Redistribution and use in source and binary forms, with or without
 7    * modification, are permitted provided that the following conditions are met:
 8    * * Redistributions of source code must retain the above copyright
 9    * notice, this list of conditions and the following disclaimer.
 10    * * Redistributions in binary form must reproduce the above copyright
 11    * notice, this list of conditions and the following disclaimer in the
 12    * documentation and/or other materials provided with the distribution.
 13    * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
 14    * names of its contributors may be used to endorse or promote products
 15    * derived from this software without specific prior written permission.
 16    *
 17    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 20    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 21    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 22    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 23    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 24    * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 25    * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 26    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 27    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28    *
 29    * This software is Open Source Initiative approved Open Source Software.
 30    * Open Source Initative Approved is a trademark of the Open Source Initiative.
 31    *
 32    * This file is part of DrJava. Download the current version of this project
 33    * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
 34    *
 35    * END_COPYRIGHT_BLOCK*/
 36   
 37    package edu.rice.cs.drjava.ui;
 38   
 39    import java.util.ArrayList;
 40   
 41    import javax.swing.*;
 42    import javax.swing.event.*;
 43    import javax.swing.text.*;
 44    import java.awt.event.*;
 45    import java.awt.*;
 46   
 47    import edu.rice.cs.drjava.config.OptionConstants;
 48    import edu.rice.cs.drjava.model.IDocumentRegion;
 49    import edu.rice.cs.drjava.model.SingleDisplayModel;
 50    import edu.rice.cs.drjava.model.OpenDefinitionsDocument;
 51    import edu.rice.cs.drjava.DrJava;
 52    import edu.rice.cs.util.StringOps;
 53    import edu.rice.cs.util.swing.RightClickMouseAdapter;
 54   
 55    /** Panel for displaying regions in a list in the order specified by indices passes to addRegion.
 56    * This class is a swing view class and hence should only be accessed from the event-handling thread.
 57    * Not currently used because BrowserHistoryPanel is not used.
 58    * @version $Id: RegionsListPanel.java 5175 2010-01-20 08:46:32Z mgricken $
 59    */
 60    public abstract class RegionsListPanel<R extends IDocumentRegion> extends TabbedPanel {
 61    protected JPanel _leftPane;
 62   
 63    protected JList _list;
 64    protected DefaultListModel _listModel;
 65    protected String _title;
 66   
 67    protected final SingleDisplayModel _model;
 68    protected final MainFrame _frame;
 69   
 70    protected JPanel _buttonPanel;
 71   
 72    /** Constructs a new panel to display regions in a list.
 73    * This is swing view class and hence should only be accessed from the event-handling thread.
 74    * @param frame the MainFrame
 75    * @param title title of the pane
 76    */
 77  0 public RegionsListPanel(MainFrame frame, String title) {
 78  0 super(frame, title);
 79  0 _title = title;
 80  0 this.setLayout(new BorderLayout());
 81   
 82  0 _frame = frame;
 83  0 _model = frame.getModel();
 84   
 85  0 this.removeAll(); // override the behavior of TabbedPanel
 86   
 87    // remake closePanel
 88  0 _closePanel = new JPanel(new BorderLayout());
 89  0 _closePanel.add(_closeButton, BorderLayout.NORTH);
 90   
 91  0 _leftPane = new JPanel(new BorderLayout());
 92  0 _setupRegionList();
 93   
 94  0 this.add(_leftPane, BorderLayout.CENTER);
 95   
 96  0 _buttonPanel = new JPanel(new BorderLayout());
 97  0 _setupButtonPanel();
 98  0 this.add(_buttonPanel, BorderLayout.EAST);
 99  0 updateButtons();
 100   
 101    // Setup the color listeners.
 102  0 _setColors(_list);
 103   
 104  0 _list.addMouseListener(new RegionMouseAdapter());
 105    }
 106   
 107    /** Quick helper for setting up color listeners. */
 108  0 private static void _setColors(Component c) {
 109  0 new ForegroundColorListener(c);
 110  0 new BackgroundColorListener(c);
 111    }
 112   
 113    /** Close the panel and update buttons. */
 114  0 @Override
 115    protected void _close() {
 116  0 super._close();
 117  0 updateButtons();
 118    }
 119   
 120    /** Creates the region list. */
 121  0 private void _setupRegionList() {
 122  0 _listModel = new DefaultListModel();
 123  0 _list = new JList(_listModel) {
 124  0 public String getToolTipText(MouseEvent evt) {
 125    // Get item
 126  0 int index = locationToIndex(evt.getPoint());
 127   
 128  0 @SuppressWarnings("unchecked") RegionListUserObj<R> node = (RegionListUserObj<R>)getModel().getElementAt(index);
 129  0 R r = node.region();
 130  0 String tooltip = null;
 131   
 132  0 OpenDefinitionsDocument doc = r.getDocument();
 133  0 try {
 134  0 int lnr = doc.getLineOfOffset(r.getStartOffset())+1;
 135  0 int startOffset = doc._getOffset(lnr - 3);
 136  0 if (startOffset < 0) { startOffset = 0; }
 137  0 int endOffset = doc._getOffset(lnr + 3);
 138  0 if (endOffset < 0) { endOffset = doc.getLength()-1; }
 139   
 140    // convert to HTML (i.e. < to &lt; and > to &gt; and newlines to <br>)
 141  0 String s = doc.getText(startOffset, endOffset-startOffset);
 142   
 143    // this highlights the actual region in red
 144  0 int rStart = r.getStartOffset() - startOffset;
 145  0 if (rStart < 0) { rStart = 0; }
 146  0 int rEnd = r.getEndOffset() - startOffset;
 147  0 if (rEnd>s.length()) { rEnd = s.length(); }
 148  0 if ((rStart <= s.length()) && (rEnd >= rStart)) {
 149  0 String t1 = StringOps.encodeHTML(s.substring(0, rStart));
 150  0 String t2 = StringOps.encodeHTML(s.substring(rStart, rEnd));
 151  0 String t3 = StringOps.encodeHTML(s.substring(rEnd));
 152  0 s = t1 + "<font color=#ff0000>" + t2 + "</font>" + t3;
 153    }
 154    else {
 155  0 s = StringOps.encodeHTML(s);
 156    }
 157  0 tooltip = "<html><pre>" + s + "</pre></html>";
 158    }
 159  0 catch(javax.swing.text.BadLocationException ble) { tooltip = null; /* just don't give a tool tip */ }
 160  0 return tooltip;
 161    }
 162    };
 163  0 _list.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
 164  0 _list.addListSelectionListener(new ListSelectionListener() {
 165  0 public void valueChanged(ListSelectionEvent e) { updateButtons(); }
 166    });
 167  0 _list.addKeyListener(new KeyAdapter() {
 168  0 public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) performDefaultAction(); }
 169    });
 170  0 _list.setFont(DrJava.getConfig().getSetting(OptionConstants.FONT_DOCLIST));
 171   
 172  0 _leftPane.add(new JScrollPane(_list));
 173  0 ToolTipManager.sharedInstance().registerComponent(_list);
 174    }
 175   
 176    /** Update button state and text. Should be overridden if additional buttons are added besides "Go To", "Remove" and "Remove All". */
 177  0 protected void updateButtons() {
 178    }
 179   
 180    /** Action performed when the Enter key is pressed. Should be overridden. */
 181  0 protected void performDefaultAction() {
 182    }
 183   
 184    /** Creates the buttons for controlling the regions. Should be overridden. */
 185  0 protected JComponent[] makeButtons() {
 186  0 return new JComponent[0];
 187    }
 188   
 189    /** Creates the buttons for controlling the regions. */
 190  0 private void _setupButtonPanel() {
 191  0 JPanel mainButtons = new JPanel();
 192  0 JPanel emptyPanel = new JPanel();
 193  0 JPanel closeButtonPanel = new JPanel(new BorderLayout());
 194  0 GridBagLayout gbLayout = new GridBagLayout();
 195  0 GridBagConstraints c = new GridBagConstraints();
 196  0 mainButtons.setLayout(gbLayout);
 197   
 198  0 JComponent[] buts = makeButtons();
 199   
 200  0 closeButtonPanel.add(_closeButton, BorderLayout.NORTH);
 201  0 for (JComponent b: buts) { mainButtons.add(b); }
 202  0 mainButtons.add(emptyPanel);
 203   
 204  0 c.fill = GridBagConstraints.HORIZONTAL;
 205  0 c.anchor = GridBagConstraints.NORTH;
 206  0 c.gridwidth = GridBagConstraints.REMAINDER;
 207  0 c.weightx = 1.0;
 208   
 209  0 for (JComponent b: buts) { gbLayout.setConstraints(b, c); }
 210   
 211  0 c.fill = GridBagConstraints.BOTH;
 212  0 c.anchor = GridBagConstraints.SOUTH;
 213  0 c.gridheight = GridBagConstraints.REMAINDER;
 214  0 c.weighty = 1.0;
 215   
 216  0 gbLayout.setConstraints(emptyPanel, c);
 217   
 218  0 _buttonPanel.add(mainButtons, BorderLayout.CENTER);
 219  0 _buttonPanel.add(closeButtonPanel, BorderLayout.EAST);
 220    }
 221   
 222    /** Gets the currently selected regions in the region list, or an empty array if no regions are selected.
 223    * @return list of selected regions in the list
 224    */
 225  0 protected ArrayList<R> getSelectedRegions() {
 226  0 ArrayList<R> regs = new ArrayList<R>();
 227  0 int[] indices = _list.getSelectedIndices();
 228  0 if (indices != null) {
 229  0 for (int index: indices) {
 230  0 @SuppressWarnings("unchecked") RegionListUserObj<R> userObj = ((RegionListUserObj<R>)_listModel.elementAt(index));
 231  0 R r = userObj.region();
 232  0 regs.add(r);
 233    }
 234    }
 235  0 return regs;
 236    }
 237   
 238    /** Go to region. */
 239  0 protected void goToRegion() {
 240  0 ArrayList<R> r = getSelectedRegions();
 241  0 if (r.size() == 1) {
 242  0 RegionListUserObj<R> userObj = getUserObjForRegion(r.get(0));
 243  0 if (userObj != null) { _list.ensureIndexIsVisible(_listModel.indexOf(userObj)); }
 244  0 _frame.scrollToDocumentAndOffset(r.get(0).getDocument(), r.get(0).getStartOffset(), false);
 245    }
 246    }
 247   
 248    /** @return the usser object in the list associated with the region, or null if not found */
 249  0 protected RegionListUserObj<R> getUserObjForRegion(R r) {
 250  0 for(int i = 0; i < _listModel.size(); ++i) {
 251  0 @SuppressWarnings("unchecked")
 252    RegionListUserObj<R> userObj = (RegionListUserObj<R>)_listModel.get(i);
 253  0 if ((userObj.region().getStartOffset() == r.getStartOffset()) &&
 254    (userObj.region().getEndOffset() == r.getEndOffset()) &&
 255    (userObj.region().getDocument().equals(r.getDocument()))) {
 256  0 return userObj;
 257    }
 258    }
 259  0 return null;
 260    }
 261   
 262    /** Add a region to the list. Must be executed in event thread.
 263    * @param r the region
 264    * @param index the index where the region should be inserted
 265    */
 266  0 public void addRegion(final R r, final int index) {
 267  0 assert EventQueue.isDispatchThread();
 268    // Only change GUI from event-dispatching thread
 269    // Runnable doCommand = new Runnable() {
 270    // public void run() {
 271    // edu.rice.cs.drjava.model.AbstractGlobalModel.log.log("RegionsListPanel.addRegion: in list were...");
 272    // for(int i = 0; i < _listModel.getSize();++i) { edu.rice.cs.drjava.model.AbstractGlobalModel.log.log("\t" + _listModel.elementAt(i)); }
 273   
 274    // String name = "";
 275    // try { name = r.getDocument().getQualifiedClassName(); }
 276    // catch (ClassNameNotFoundException cnnfe) { name = r.getDocument().toString(); }
 277   
 278  0 RegionListUserObj<R> userObj = makeRegionListUserObj(r);
 279  0 _listModel.add(index, userObj);
 280  0 _list.ensureIndexIsVisible(_listModel.indexOf(userObj));
 281   
 282  0 updateButtons();
 283    // }
 284    // };
 285    // Utilities.invokeLater(doCommand);
 286    }
 287   
 288    /** Remove a region from the tree. Must be executed in event thread.
 289    * @param r the region
 290    */
 291  0 public void removeRegion(final R r) {
 292    // Only change GUI from event-dispatching thread
 293    // Runnable doCommand = new Runnable() {
 294    // public void run() {
 295    // String name = "";
 296    // try {
 297    // name = r.getDocument().getQualifiedClassName();
 298    // }
 299    // catch (ClassNameNotFoundException cnnfe) {
 300    // name = r.getDocument().toString();
 301    // }
 302   
 303  0 for (int i = 0; i < _listModel.size(); ++i) {
 304  0 @SuppressWarnings("unchecked") RegionListUserObj<R> userObj = (RegionListUserObj<R>)_listModel.get(i);
 305  0 if (userObj.region() == r) {
 306  0 _listModel.removeElementAt(i);
 307  0 break;
 308    }
 309    }
 310   
 311  0 updateButtons();
 312    // }
 313    // };
 314    // Utilities.invokeLater(doCommand);
 315    }
 316   
 317    // /** Remove all regions for this document from the tree. Must be executed in event thread. */
 318    // public void removeRegions(final OpenDefinitionsDocument odd) {
 319    // // Only change GUI from event-dispatching thread
 320    // Runnable doCommand = new Runnable() {
 321    // public void run() {
 322    //// String name = "";
 323    //// try { name = odd.getQualifiedClassName(); }
 324    //// catch (ClassNameNotFoundException cnnfe) { name = odd.toString(); }
 325    //
 326    // for (int i = 0; i < _listModel.size(); ++i) {
 327    // @SuppressWarnings("unchecked") RegionListUserObj<R> userObj = (RegionListUserObj<R>)_listModel.get(i);
 328    //
 329    // if (userObj.region().getDocument().equals(odd)) {
 330    // _listModel.removeElementAt(i);
 331    // }
 332    // }
 333    //
 334    // updateButtons();
 335    // }
 336    // };
 337    // Utilities.invokeLater(doCommand);
 338    // }
 339   
 340    /** Factory method to create user objects put in the list.
 341    * If subclasses extend RegionListUserObj, they need to override this method. */
 342  0 protected RegionListUserObj<R> makeRegionListUserObj(R r) {
 343  0 return new RegionListUserObj<R>(r);
 344    }
 345   
 346    /** Class that gets put into the list. The toString() method determines what's displayed in the three. */
 347    protected static class RegionListUserObj<R extends IDocumentRegion> {
 348    protected R _region;
 349  0 public int lineNumber() { return _region.getDocument().getLineOfOffset(_region.getStartOffset())+1; }
 350  0 public R region() { return _region; }
 351  0 public RegionListUserObj(R r) { _region = r; }
 352  0 public String toString() {
 353  0 final StringBuilder sb = new StringBuilder();
 354  0 sb.append(_region.getDocument().toString());
 355  0 sb.append(':');
 356  0 sb.append(lineNumber());
 357  0 try {
 358  0 sb.append(": ");
 359  0 int length = Math.min(120, _region.getEndOffset() - _region.getStartOffset());
 360  0 sb.append(_region.getDocument().getText(_region.getStartOffset(), length).trim());
 361    } catch(BadLocationException bpe) { /* ignore, just don't display line */ }
 362  0 return sb.toString();
 363    }
 364    // public boolean equals(Object other) {
 365    // if ((other == null) || ! (other instanceof RegionListUserObj)) { return false; }
 366    // @SuppressWarnings("unchecked") RegionListUserObj<R> o = (RegionListUserObj<R>)other;
 367    // return (o.region().getDocument().equals(region().getDocument())) &&
 368    // (o.region().getStartOffset() == region().getStartOffset()) &&
 369    // (o.region().getEndOffset() == region().getEndOffset());
 370    // }
 371    // public int hashCode() { return (_region != null ? _region.hashCode() : 0); }
 372    }
 373   
 374   
 375    /** Mouse adapter for the region tree. */
 376    protected class RegionMouseAdapter extends RightClickMouseAdapter {
 377  0 protected void _popupAction(MouseEvent e) {
 378    // TODO: add popup
 379    }
 380   
 381  0 public void mousePressed(MouseEvent e) {
 382  0 super.mousePressed(e);
 383  0 if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
 384  0 performDefaultAction();
 385    }
 386    }
 387    }
 388   
 389    }