001: /*BEGIN_COPYRIGHT_BLOCK
002: *
003: * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions are met:
008: * * Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: * * Redistributions in binary form must reproduce the above copyright
011: * notice, this list of conditions and the following disclaimer in the
012: * documentation and/or other materials provided with the distribution.
013: * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014: * names of its contributors may be used to endorse or promote products
015: * derived from this software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: *
029: * This software is Open Source Initiative approved Open Source Software.
030: * Open Source Initative Approved is a trademark of the Open Source Initiative.
031: *
032: * This file is part of DrJava. Download the current version of this project
033: * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034: *
035: * END_COPYRIGHT_BLOCK*/
036:
037: package edu.rice.cs.util.swing;
038:
039: import edu.rice.cs.drjava.ui.MainFrame;
040: import java.awt.EventQueue;
041: import java.awt.*;
042: import java.awt.event.*;
043: import javax.swing.*;
044: import javax.swing.border.Border;
045: import java.awt.datatransfer.*;
046:
047: import edu.rice.cs.util.UnexpectedException;
048: import edu.rice.cs.util.StringOps;
049:
050: import edu.rice.cs.drjava.ui.DrJavaErrorHandler;
051:
052: public class Utilities {
053:
054: /** True if the program is run in non-interactive test mode. */
055: public static volatile boolean TEST_MODE = false;
056:
057: /** Runs the task synchronously if the current thread is the event thread; otherwise passes it to the
058: * event thread to be run asynchronously after all events already on the queue have been processed.
059: */
060: public static void invokeLater(Runnable task) {
061: if (EventQueue.isDispatchThread()) {
062: task.run();
063: return;
064: }
065: EventQueue.invokeLater(task);
066: }
067:
068: public static void invokeAndWait(Runnable task) {
069: if (EventQueue.isDispatchThread()) {
070: task.run();
071: return;
072: }
073: try {
074: EventQueue.invokeAndWait(task);
075: } catch (Exception e) {
076: throw new UnexpectedException(e);
077: }
078: }
079:
080: public static void main(String[] args) {
081: clearEventQueue();
082: }
083:
084: public static void clearEventQueue() {
085: Utilities.invokeAndWait(new Runnable() {
086: public void run() {
087: }
088: });
089: }
090:
091: /** Show a modal debug message box with an OK button regardless of TEST_MODE.
092: * @param msg string to display
093: */
094: public static void show(final String msg) {
095: Utilities.invokeAndWait(new Runnable() {
096: public void run() {
097: JOptionPane.showMessageDialog(null, msg);
098: }
099: });
100: }
101:
102: /** Show a modal debug message box containing a backtrace for the Throwable t.
103: * @param t the Throwable to be back traced.
104: */
105: public static void showTrace(final Throwable t) {
106: Utilities.invokeAndWait(new Runnable() {
107: public void run() {
108: new DrJavaErrorHandler().handle(t);
109: }
110: });
111: }
112:
113: /** Show a modal debug message box with an OK button when not in TEST_MODE.
114: * @param msg string to display
115: */
116: public static void showDebug(String msg) {
117: showMessageBox(msg, "Debug Message");
118: }
119:
120: /** Show a modal message box with an OK button.
121: * @param msg string to display
122: */
123: public static void showMessageBox(final String msg,
124: final String title) {
125: //Utilities.invokeAndWait(new Runnable() { public void run() { JOptionPane.showMessageDialog(null, msg); } } );
126: Utilities.invokeAndWait(new Runnable() {
127: public void run() {
128: Utilities.TextAreaMessageDialog.showDialog(null, title,
129: msg);
130: }
131: });
132: }
133:
134: public static void showStackTrace(final Throwable t) {
135: Utilities.invokeAndWait(new Runnable() {
136: public void run() {
137: JOptionPane.showMessageDialog(null, StringOps
138: .getStackTrace(t));
139: }
140: });
141: }
142:
143: /** Message dialog with a word-wrapping text area that allows copy & paste. */
144: public static class TextAreaMessageDialog extends JDialog {
145:
146: /** Show the initialized dialog.
147: * @param comp parent component, or null
148: * @param title dialog title
149: * @param message message for the text area
150: */
151: public static void showDialog(Component comp, String title,
152: String message) {
153: if (TEST_MODE)
154: System.out.println(title + ": " + message);
155: else {
156: Frame frame = JOptionPane.getFrameForComponent(comp);
157: TextAreaMessageDialog dialog = new TextAreaMessageDialog(
158: frame, comp, title, message);
159: MainFrame.setPopupLoc(dialog, frame);
160: dialog.setVisible(true);
161: }
162: }
163:
164: /** Private constructor for this dialog. Only gets used in the static showDialog method.
165: * @param frame owner frame
166: * @param comp parent component
167: * @param title dialog title
168: * @param message message for the text area
169: */
170: private TextAreaMessageDialog(Frame frame, Component comp,
171: String title, String message) {
172: super (frame, title, true);
173: setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
174:
175: //buttons
176: JButton okButton = new JButton("OK");
177: okButton.addActionListener(new ActionListener() {
178: public void actionPerformed(ActionEvent e) {
179: TextAreaMessageDialog.this .dispose();
180: }
181: });
182: getRootPane().setDefaultButton(okButton);
183:
184: JTextArea textArea = new JTextArea(message);
185: textArea.setEditable(false);
186: textArea.setLineWrap(true);
187: textArea.setWrapStyleWord(false);
188: textArea.setBackground(SystemColor.window);
189:
190: Border emptyBorder = BorderFactory.createEmptyBorder(10,
191: 10, 10, 10);
192: textArea.setBorder(emptyBorder);
193:
194: Container contentPane = getContentPane();
195: contentPane.add(textArea, BorderLayout.CENTER);
196: contentPane.add(okButton, BorderLayout.SOUTH);
197:
198: Dimension parentDim = (comp != null) ? (comp.getSize())
199: : getToolkit().getScreenSize();
200: int xs = (int) parentDim.getWidth() / 4;
201: int ys = (int) parentDim.getHeight() / 5;
202: setSize(Math.max(xs, 350), Math.max(ys, 250));
203: setLocationRelativeTo(comp);
204: }
205: }
206:
207: /** @return a string with the current clipboard selection, or null if not available. */
208: public static String getClipboardSelection(Component c) {
209: Clipboard cb = c.getToolkit().getSystemClipboard();
210: if (cb == null)
211: return null;
212: Transferable t = cb.getContents(null);
213: if (t == null)
214: return null;
215: String s = null;
216: try {
217: java.io.Reader r = DataFlavor.stringFlavor
218: .getReaderForText(t);
219: int ch;
220: final StringBuilder sb = new StringBuilder();
221: while ((ch = r.read()) != -1) {
222: sb.append((char) ch);
223: }
224: s = sb.toString();
225: } catch (UnsupportedFlavorException ufe) { /* ignore, return null */
226: } catch (java.io.IOException ioe) { /* ignore, return null */
227: }
228: return s;
229: }
230:
231: /** @return an action with a new name that delegates to another action. */
232: public static AbstractAction createDelegateAction(String newName,
233: final Action delegate) {
234: return new AbstractAction(newName) {
235: public void actionPerformed(ActionEvent ae) {
236: delegate.actionPerformed(ae);
237: }
238: };
239: }
240: }
|