Clover coverage report - DrJava Test Coverage (drjava-20120422-r5456)
Coverage timestamp: Sun Apr 22 2012 03:13:25 CDT
file stats: LOC: 282   Methods: 20
NCLOC: 163   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
Utilities.java 37.5% 54.5% 35% 47.8%
coverage 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.util.swing;
 38   
 39    import java.awt.*;
 40    import java.awt.event.*;
 41    import javax.swing.*;
 42    import java.awt.datatransfer.*;
 43    import java.beans.PropertyChangeListener;
 44    import java.beans.PropertyChangeEvent;
 45   
 46    import edu.rice.cs.plt.lambda.LambdaUtil;
 47    import edu.rice.cs.util.UnexpectedException;
 48    import edu.rice.cs.util.StringOps;
 49   
 50    public class Utilities {
 51   
 52    /** True if the program is run in non-interactive test mode. */
 53    public static volatile boolean TEST_MODE = false;
 54   
 55    public static final String JGOODIES_PACKAGE = "com.jgoodies.looks";
 56   
 57    /** Runs the task synchronously if the current thread is the event thread; otherwise passes it to the
 58    * event thread to be run asynchronously after all events already on the queue have been processed.
 59    */
 60  6122 public static void invokeLater(Runnable task) {
 61  6122 if (EventQueue.isDispatchThread()) {
 62  2354 task.run();
 63  2354 return;
 64    }
 65  3768 EventQueue.invokeLater(task);
 66    }
 67   
 68  2596 public static void invokeAndWait(Runnable task) {
 69  2596 if (EventQueue.isDispatchThread()) {
 70  405 task.run();
 71  405 return;
 72    }
 73  2191 try { EventQueue.invokeAndWait(task); }
 74  0 catch(Exception e) { throw new UnexpectedException(e); }
 75    }
 76   
 77    // public static void main(String[] args) { clearEventQueue(); }
 78   
 79    /** Clears the event queue by waiting until all events currently in the queue
 80    * have been processed. Calls clearEventQueue(true);
 81    */
 82  605 public static void clearEventQueue() { clearEventQueue(true); }
 83   
 84    /** Clears the event queue by waiting until all events currently in the queue
 85    * have been processed. If newEvents is set to true, the method will also wait for
 86    * all events that have been put in the queue by the events that were just
 87    * processed, and so on.
 88    * @param newEvents true if the method should also clear new events that were added by the events just cleared
 89    */
 90  605 public static void clearEventQueue(boolean newEvents) {
 91  605 assert ! EventQueue.isDispatchThread();
 92  605 final EventQueue q = Toolkit.getDefaultToolkit().getSystemEventQueue();
 93  605 do {
 94    // it is an error to be in the event queue, so Utilties.invokeAndWait shouldn't be used
 95  626 try { EventQueue.invokeAndWait(LambdaUtil.NO_OP); }
 96  0 catch (Exception e) { throw new UnexpectedException(e); }
 97  626 } while (newEvents && (null != q.peekEvent()));
 98    }
 99   
 100    /** Show a modal debug message box with an OK button regardless of TEST_MODE.
 101    * @param msg string to display
 102    */
 103  0 public static void show(final String msg) {
 104  0 Utilities.invokeAndWait(new Runnable() { public void run() {
 105  0 new edu.rice.cs.drjava.ui.DrJavaScrollableDialog(null,
 106    "Debug Message",
 107    "Debug Message from Utilities.show():",
 108    msg,
 109    false).show(); } } );
 110    }
 111   
 112    /** Shows a modal debug message box with an OK button when not in TEST_MODE.
 113    * @param msg string to display
 114    */
 115  0 public static void showDebug(String msg) { showMessageBox(msg, "Debug Message"); }
 116   
 117    /** Shows a modal message box with an OK button.
 118    * @param msg string to display
 119    */
 120  0 public static void showMessageBox(final String msg, final String title) {
 121  0 if (TEST_MODE) System.out.println(title + ": " + msg); else {
 122    //Utilities.invokeAndWait(new Runnable() { public void run() { JOptionPane.showMessageDialog(null, msg); } } );
 123  0 Utilities.invokeAndWait(new Runnable() { public void run() {
 124  0 new edu.rice.cs.drjava.ui.DrJavaScrollableDialog(null,
 125    title,
 126    "Message:",
 127    msg,
 128    false).show();
 129    } } );
 130    }
 131    }
 132   
 133  0 public static void showStackTrace(final Throwable t) {
 134  0 Utilities.invokeAndWait(new Runnable() { public void run() {
 135  0 new edu.rice.cs.drjava.ui.DrJavaScrollableDialog(null,
 136    "Stack Trace",
 137    "Stack Trace:",
 138    StringOps.getStackTrace(t),
 139    false).show();
 140    } } );
 141    }
 142   
 143    /** @return a string with the current clipboard selection, or null if not available. */
 144  0 public static String getClipboardSelection(Component c) {
 145  0 Clipboard cb = c.getToolkit().getSystemClipboard();
 146  0 if (cb == null) return null;
 147  0 Transferable t = cb.getContents(null);
 148  0 if (t == null) return null;
 149  0 String s = null;
 150  0 try {
 151  0 java.io.Reader r = DataFlavor.stringFlavor.getReaderForText(t);
 152  0 int ch;
 153  0 final StringBuilder sb = new StringBuilder();
 154  0 while ((ch=r.read()) !=-1 ) { sb.append((char)ch); }
 155  0 s = sb.toString();
 156    }
 157    catch(UnsupportedFlavorException ufe) { /* ignore, return null */ }
 158    catch(java.io.IOException ioe) { /* ignore, return null */ }
 159  0 return s;
 160    }
 161   
 162    /** @return an action with a new name that delegates to another action. */
 163  0 public static AbstractAction createDelegateAction(String newName, final Action delegate) {
 164  0 return new AbstractAction(newName) {
 165  0 public void actionPerformed(ActionEvent ae) { delegate.actionPerformed(ae); }
 166    };
 167    }
 168   
 169    /** @return whether the current LookAndFeel is a Plastic (i.e. JGoodies) LookAndFeel */
 170  114 public static boolean isPlasticLaf() {
 171  114 LookAndFeel laf = UIManager.getLookAndFeel();
 172  114 return laf != null && laf.getClass().getName().startsWith(JGOODIES_PACKAGE);
 173    }
 174   
 175    /** @return whether a given LookAndFeel name is a Plastic (i.e. JGoodies) LookAndFeel
 176    * @param name the fully-qualified classname of the LookAndFeel */
 177  0 public static boolean isPlasticLaf(String name) {
 178  0 return name != null && name.startsWith(JGOODIES_PACKAGE);
 179    }
 180   
 181    /** Determines the location of the popup using a simple, uniform protocol. If the popup has an owner, the popup is
 182    * centered over the owner. If the popup has no owner(owner == null), the popup is centered over the first monitor.
 183    * In either case, the popup is moved and scaled if any part of it is not on the screen. This method should be
 184    * called for all popups to maintain uniformity in the DrJava UI.
 185    * @param popup the popup window
 186    * @param owner the parent component for the popup
 187    */
 188  418 public static void setPopupLoc(Window popup, Component owner) {
 189  418 Rectangle frameRect = popup.getBounds();
 190   
 191  418 Point ownerLoc = null;
 192  418 Dimension ownerSize = null;
 193  418 if (owner != null && owner.isVisible()) {
 194  0 ownerLoc = owner.getLocation();
 195  0 ownerSize = owner.getSize();
 196    }
 197    else {
 198    //for multi-monitor support
 199    //Question: do we want it to popup on the first monitor always?
 200  418 GraphicsDevice[] dev = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
 201  418 Rectangle rec = dev[0].getDefaultConfiguration().getBounds();
 202  418 ownerLoc = rec.getLocation();
 203  418 ownerSize = rec.getSize();
 204    }
 205   
 206    // center it on owner
 207  418 Point loc = new Point(ownerLoc.x + (ownerSize.width - frameRect.width) / 2,
 208    ownerLoc.y + (ownerSize.height - frameRect.height) / 2);
 209  418 frameRect.setLocation(loc);
 210   
 211    // now find the GraphicsConfiguration the popup is on
 212  418 GraphicsConfiguration gcBest = null;
 213  418 int gcBestArea = -1;
 214  418 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
 215  418 GraphicsDevice[] gs = ge.getScreenDevices();
 216  418 for (GraphicsDevice gd: gs) {
 217  418 GraphicsConfiguration gc = gd.getDefaultConfiguration();
 218  418 Rectangle isect = frameRect.intersection(gc.getBounds());
 219  418 int gcArea = isect.width*isect.height;
 220  418 if (gcArea > gcBestArea) {
 221  418 gcBest = gc;
 222  418 gcBestArea = gcArea;
 223    }
 224    }
 225   
 226    // make it fit on the screen
 227  418 Rectangle screenRect = gcBest.getBounds();
 228  418 Dimension screenSize = screenRect.getSize();
 229  418 Dimension frameSize = popup.getSize();
 230   
 231  0 if (frameSize.height > screenSize.height) frameSize.height = screenSize.height;
 232  0 if (frameSize.width > screenSize.width) frameSize.width = screenSize.width;
 233   
 234  418 frameRect.setSize(frameSize);
 235   
 236    // center it on owner again
 237  418 loc = new Point(ownerLoc.x + (ownerSize.width - frameRect.width) / 2,
 238    ownerLoc.y + (ownerSize.height - frameRect.height) / 2);
 239  418 frameRect.setLocation(loc);
 240   
 241    // now fit it on the screen
 242  0 if (frameRect.x < screenRect.x) frameRect.x = screenRect.x;
 243  418 if (frameRect.x + frameRect.width > screenRect.x + screenRect.width)
 244  0 frameRect.x = screenRect.x + screenRect.width - frameRect.width;
 245   
 246  0 if (frameRect.y < screenRect.y) frameRect.y = screenRect.y;
 247  418 if (frameRect.y + frameRect.height > screenRect.y + screenRect.height)
 248  0 frameRect.y = screenRect.y + screenRect.height - frameRect.height;
 249   
 250  418 popup.setSize(frameRect.getSize());
 251  418 popup.setLocation(frameRect.getLocation());
 252    }
 253   
 254    /** Enables/disables the second action whenever the first action is enabled/disabled.
 255    * @param observable the action that is observed (leads)
 256    * @param observer the action that follows
 257    * @return the PropertyChangeListener used to do the observation */
 258  76 public static PropertyChangeListener enableDisableWith(Action observable, final Action observer) {
 259  76 PropertyChangeListener pcl = new PropertyChangeListener() {
 260  0 public void propertyChange(PropertyChangeEvent e) {
 261  0 if (e.getPropertyName().equals("enabled")) { observer.setEnabled((Boolean)e.getNewValue()); }
 262    }
 263    };
 264  76 observable.addPropertyChangeListener(pcl);
 265  76 return pcl;
 266    }
 267   
 268    /** Return the index of the component in the parent container, or -1 if no parent or not found.
 269    * @param component
 270    * @return index of the component in the parent container, or -1 if not found */
 271  0 public static int getComponentIndex(Component component) {
 272  0 if (component != null && component.getParent() != null) {
 273  0 Container c = component.getParent();
 274  0 for (int i = 0; i < c.getComponentCount(); i++) {
 275  0 if (c.getComponent(i) == component)
 276  0 return i;
 277    }
 278    }
 279   
 280  0 return -1;
 281    }
 282    }