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.drjava.ui;
038:
039: import edu.rice.cs.drjava.platform.PlatformFactory;
040: import edu.rice.cs.util.swing.*;
041: import edu.rice.cs.util.UnexpectedException;
042: import edu.rice.cs.util.StringOps;
043: import edu.rice.cs.drjava.DrJava;
044: import edu.rice.cs.drjava.Version;
045: import javax.swing.*;
046: import javax.swing.border.*;
047: import javax.swing.text.*;
048: import javax.swing.event.ChangeListener;
049: import javax.swing.event.ChangeEvent;
050: import java.awt.datatransfer.Clipboard;
051: import java.awt.datatransfer.StringSelection;
052: import java.awt.event.*;
053: import java.awt.*;
054:
055: import java.io.*;
056: import java.net.URL;
057: import java.util.Map;
058:
059: /** About dialog.
060: * @version $Id: AboutDialog.java 4255 2007-08-28 19:17:37Z mgricken $
061: */
062: public class AboutDialog extends JDialog implements ActionListener {
063:
064: private static ImageInfo CSLOGO = new ImageInfo("RiceCS.gif",
065: new Color(0x423585)), SF = new ImageInfo("SourceForge.gif",
066: Color.black), DRJAVA = new ImageInfo("DrJava.png",
067: new Color(0xCCCCFF));
068:
069: private final JButton _okButton = new JButton("OK");
070:
071: /** the button that copies the system properties to the clipboard */
072: private JButton _copyButton;
073:
074: /** the table with the System Properties information */
075: private JTable _propertiesTable;
076:
077: /** index the System Properties tab, one of the tabs in _tabs */
078: private int _propertiesTabIndex;
079:
080: /** the pane with tabs to select */
081: private final JTabbedPane _tabs = new JTabbedPane();
082:
083: public AboutDialog(JFrame owner) {
084: super (owner, "About DrJava", true); // (changed to non-modal for now)
085:
086: buildGUI(getContentPane());
087: getRootPane().setDefaultButton(_okButton);
088: // pack();
089: // setSize((int) (.8f*owner.getWidth()),(int) (.8f*owner.getHeight()));
090: setSize(550, 400);
091: // suggested from zaq@nosi.com, to keep the frame on the screen!
092: //System.out.println("Dialog created...");
093: }
094:
095: public void setVisible(boolean vis) {
096: _tabs.remove(0);
097: addTab(_tabs, "About", createCopyrightTab(), 0);
098: _tabs.setSelectedIndex(0);
099:
100: if (vis) {
101: // suggested from zaq@nosi.com, to keep the frame on the screen!
102: //Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
103: //Dimension frameSize = this.getSize();
104: MainFrame.setPopupLoc(this , getOwner());
105: }
106: super .setVisible(vis);
107: }
108:
109: public void buildGUI(Container cp) {
110: cp.setLayout(new BorderLayout());
111: JLabel drjava = createImageLabel(DRJAVA, JLabel.LEFT);
112: if (drjava != null) {
113: drjava.setBorder(new CompoundBorder(new EmptyBorder(5, 5,
114: 5, 5), drjava.getBorder()));
115: drjava.setCursor(new Cursor(Cursor.HAND_CURSOR));
116: final String url = "http://drjava.org/";
117: drjava.setToolTipText(url);
118: drjava.addMouseListener(new MouseListener() {
119: public void mousePressed(MouseEvent e) {
120: }
121:
122: public void mouseReleased(MouseEvent e) {
123: }
124:
125: public void mouseEntered(MouseEvent e) {
126: }
127:
128: public void mouseExited(MouseEvent e) {
129: }
130:
131: public void mouseClicked(MouseEvent e) {
132: try {
133: PlatformFactory.ONLY.openURL(new URL(url));
134: } catch (Exception ex) { /* ignore, just not open web page */
135: }
136: }
137: });
138:
139: JPanel djPanel = new JPanel(new GridLayout(1, 1));
140: djPanel.add(drjava);
141: djPanel.setBorder(new CompoundBorder(new EmptyBorder(5, 5,
142: 5, 5), new EtchedBorder()));
143: cp.add(djPanel, BorderLayout.NORTH);
144: }
145: addTab(_tabs, "About", createCopyrightTab());
146: LICENSE = getLicense();
147: if (LICENSE != null)
148: addTab(_tabs, "DrJava License", createTextScroller(LICENSE));
149:
150: addTab(_tabs, "DynamicJava License",
151: createTextScroller(DYADE_LICENSE));
152: addTab(_tabs, "System Properties", createSysPropTab());
153: _propertiesTabIndex = _tabs.getTabCount() - 1;
154: cp.add(createBottomBar(), BorderLayout.SOUTH);
155: cp.add(_tabs, BorderLayout.CENTER);
156: }
157:
158: private JComponent createSysPropTab() {
159: java.util.Properties props = System.getProperties();
160: int size = props.size();
161: String[][] rowData = new String[size][2];
162: java.util.Iterator entries = props.entrySet().iterator();
163: int rowNum = 0;
164: while (entries.hasNext()) {
165: Map.Entry entry = (Map.Entry) entries.next();
166: rowData[rowNum][0] = (String) entry.getKey();
167: rowData[rowNum][1] = (String) entry.getValue();
168: rowNum++;
169: }
170: java.util.Arrays.sort(rowData,
171: new java.util.Comparator<String[]>() {
172: public int compare(String[] o1, String[] o2) {
173: return o1[0].compareTo(o2[0]);
174: }
175: });
176: String[] nvStrings = new String[] { "Name", "Value" };
177: UneditableTableModel model = new UneditableTableModel(rowData,
178: nvStrings);
179: _propertiesTable = new JTable(model);
180: JScrollPane scroller = new BorderlessScrollPane(
181: _propertiesTable);
182: wrapBorder(scroller, new EmptyBorder(5, 0, 0, 0));
183: JPanel propTab = new JPanel(new BorderLayout());
184: propTab.add(new JLabel("Current system properties:"),
185: BorderLayout.NORTH);
186: propTab.add(scroller, BorderLayout.CENTER);
187: return propTab;
188: }
189:
190: private static void addTab(JTabbedPane tabs, String title,
191: JComponent tab) {
192: wrapBorder(tab, new EmptyBorder(5, 6, 6, 5));
193: tabs.addTab(title, tab);
194: }
195:
196: private static void addTab(JTabbedPane tabs, String title,
197: JComponent tab, int i) {
198: wrapBorder(tab, new EmptyBorder(5, 6, 6, 5));
199: tabs.insertTab(title, null, tab, "", i);
200: }
201:
202: public static JComponent createCopyrightTab() {
203: final JPanel panel = new JPanel(new BorderLayout());
204:
205: final StringBuilder sb = new StringBuilder("DrJava Version : ");
206: sb.append(Version.getBuildTimeString());
207: sb.append("\n\nDrJava Configuration file: ");
208: sb.append(DrJava.getPropertiesFile().getAbsolutePath());
209: sb.append("\n\nUsed memory: about ");
210: sb.append(StringOps.memSizeToString(Runtime.getRuntime()
211: .totalMemory()
212: - Runtime.getRuntime().freeMemory()));
213: sb.append("\nFree memory: about ");
214: sb.append(StringOps.memSizeToString(Runtime.getRuntime()
215: .freeMemory()));
216: sb.append("\nTotal memory: about ");
217: sb.append(StringOps.memSizeToString(Runtime.getRuntime()
218: .totalMemory()));
219: sb.append("\nTotal memory can expand to: about ");
220: sb.append(StringOps.memSizeToString(Runtime.getRuntime()
221: .maxMemory()));
222: sb.append("\n\n");
223: sb.append(COPYRIGHT);
224: final JComponent copy = createTextScroller(sb.toString());
225: wrapBorder(copy, new EmptyBorder(0, 0, 5, 0));
226:
227: // deal with logos now (calibrate size)
228: final LogoList logos = new LogoList();
229: logos.addLogo(createBorderedLabel(CSLOGO, new EmptyBorder(5, 5,
230: 5, 5)), "http://compsci.rice.edu/");
231: logos.addLogo(createBorderedLabel(SF, null),
232: "http://sourceforge.net/projects/drjava/");
233: logos.resizeLogos();
234:
235: // add to panel
236: final JPanel logoPanel = new JPanel();
237: logoPanel.setLayout(new BoxLayout(logoPanel, BoxLayout.X_AXIS));
238: logoPanel.add(Box.createHorizontalGlue());
239: java.util.Iterator it = logos.iterator();
240: while (it.hasNext()) {
241: final JComponent l = (JComponent) it.next();
242: logoPanel.add(l);
243: l.setCursor(new Cursor(Cursor.HAND_CURSOR));
244: final String url = (String) l.getClientProperty("url");
245: if (url != null) {
246: l.setToolTipText(url);
247: l.addMouseListener(new MouseListener() {
248: public void mousePressed(MouseEvent e) {
249: }
250:
251: public void mouseReleased(MouseEvent e) {
252: }
253:
254: public void mouseEntered(MouseEvent e) {
255: }
256:
257: public void mouseExited(MouseEvent e) {
258: }
259:
260: public void mouseClicked(MouseEvent e) {
261: try {
262: PlatformFactory.ONLY.openURL(new URL(url));
263: } catch (Exception ex) { /* ignore, just not open web page */
264: }
265: }
266: });
267: }
268: logoPanel.add(Box.createHorizontalGlue());
269: }
270: panel.add(logoPanel, BorderLayout.SOUTH);
271: panel.add(copy, BorderLayout.CENTER);
272: return panel;
273: }
274:
275: private static class LogoList extends java.util.LinkedList<JPanel>
276: implements Serializable {
277: private int width = Integer.MIN_VALUE;
278: private int height = Integer.MIN_VALUE;
279:
280: private void addLogo(JPanel logo, String url) {
281: if (logo != null) {
282: Dimension d = logo.getMinimumSize();
283: width = Math.max(width, d.width);
284: height = Math.max(height, d.height);
285: add(logo);
286: if (url != null)
287: logo.putClientProperty("url", url);
288: }
289: }
290:
291: private void resizeLogos() {
292: java.util.Iterator it = iterator();
293: Dimension d = new Dimension(width, height);
294: while (it.hasNext()) {
295: JComponent i = (JComponent) it.next();
296: i.setMinimumSize(d);
297: i.setMaximumSize(d);
298: i.setPreferredSize(d);
299: }
300: }
301: }
302:
303: public static JPanel createBorderedLabel(ImageInfo info,
304: EmptyBorder pad) {
305: JLabel label = createImageLabel(info, JLabel.CENTER);
306: if (label == null)
307: return null;
308: JPanel panel = new JPanel(new GridLayout(1, 1));
309: panel.setOpaque(true);
310: panel.setBackground(info.color);
311: panel.setBorder(pad);
312: wrapBorder(panel, new EtchedBorder());
313: panel.add(label);
314: return panel;
315: }
316:
317: public static JLabel createImageLabel(ImageInfo info, int align) {
318: ImageIcon icon = MainFrame.getIcon(info.name);
319: if (icon == null)
320: return null;
321: JLabel label = new JLabel(icon, align);
322: label.setOpaque(true);
323: label.setBackground(info.color);
324: return label;
325: }
326:
327: public static JTextArea createTextArea(String text) {
328: JTextArea textArea = new JTextArea(text);
329: textArea.setEditable(false);
330: textArea.setLineWrap(true);
331: textArea.setWrapStyleWord(true);
332: textArea.setCaretPosition(0);
333: return textArea;
334: }
335:
336: public static JScrollPane createTextScroller(String text) {
337: return new BorderlessScrollPane(createTextArea(text));
338: }
339:
340: private JPanel createBottomBar() {
341: JPanel panel = new JPanel(new BorderLayout());
342: JPanel buttonPanel = new JPanel();
343: _copyButton = new JButton(new AbstractAction(
344: "Copy System Properties") {
345: public void actionPerformed(ActionEvent e) {
346: Clipboard cb = Toolkit.getDefaultToolkit()
347: .getSystemClipboard();
348: StringSelection contents = new StringSelection(
349: DrJavaErrorWindow.getSystemAndDrJavaInfo());
350: cb.setContents(contents, null);
351: }
352: });
353: _tabs.addChangeListener(new ChangeListener() {
354: // This method is called whenever the selected tab changes
355: public void stateChanged(ChangeEvent evt) {
356: _copyButton
357: .setVisible(_tabs.getSelectedIndex() == _propertiesTabIndex);
358: }
359: });
360: _copyButton
361: .setVisible(_tabs.getSelectedIndex() == _propertiesTabIndex);
362: _okButton.addActionListener(this );
363: buttonPanel.add(_copyButton);
364: buttonPanel.add(_okButton);
365: panel.add(buttonPanel, BorderLayout.EAST);
366: wrapBorder(panel, new EmptyBorder(5, 5, 5, 5));
367: return panel;
368: }
369:
370: public void actionPerformed(ActionEvent e) {
371: setVisible(false);
372: }
373:
374: public static final String COPYRIGHT = "Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)\n"
375: + "All rights reserved.\n\n"
376: + "Redistribution and use in source and binary forms, with or without"
377: + "modification, are permitted provided that the following conditions are met:\n"
378: + "* Redistributions of source code must retain the above copyright"
379: + "notice, this list of conditions and the following disclaimer.\n"
380: + "* Redistributions in binary form must reproduce the above copyright"
381: + "notice, this list of conditions and the following disclaimer in the"
382: + "documentation and/or other materials provided with the distribution.\n"
383: + "* Neither the names of DrJava, the JavaPLT group, Rice University, nor the"
384: + "names of its contributors may be used to endorse or promote products"
385: + "derived from this software without specific prior written permission.\n\n"
386: + "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"
387: + "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"
388: + "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR"
389: + "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR"
390: + "CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,"
391: + "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,"
392: + "PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR"
393: + "PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF"
394: + "LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"
395: + "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"
396: + "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n"
397: + "This software is Open Source Initiative approved Open Source Software.\n"
398: + "Open Source Initative Approved is a trademark of the Open Source Initiative.\n";
399: private static String LICENSE;
400: private static boolean initLicense = false;
401: public static final String DYADE_LICENSE = "DynamicJava - Copyright \u00a9 1999 Dyade\n\nPermission is hereby granted,"
402: + " free of charge, to any person obtaining a copy of this software and associated"
403: + " documentation files (the \"Software\"), to deal in the Software without restriction,"
404: + " including without limitation the rights to use, copy, modify, merge, publish, distribute,"
405: + " sublicense, and/or sell copies of the Software, and to permit persons to whom the Software"
406: + " is furnished to do so, subject to the following conditions:\n\n"
407: + "The above copyright notice and this permission notice shall be included in all copies or"
408: + " substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY"
409: + " OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,"
410: + " FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DYADE BE LIABLE FOR ANY CLAIM,"
411: + " DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT"
412: + " OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n"
413: + "Except as contained in this notice, the name of Dyade shall not be used in advertising or otherwise"
414: + " to promote the sale, use or other dealings in this Software without prior written authorization from Dyade.";
415: public static final String INTRODUCTION = "DrJava is a pedagogic programming environment for Java, intended to help students focus more on program"
416: + " design than on the features of a complicated development environment. It provides an Interactions"
417: + " window based on a \"read-eval-print loop\", which allows programmers to develop, test, and debug"
418: + " Java programs in an interactive, incremental fashion.\n\n"
419: + "Home Page: http://www.drjava.org\nPaper: http://drjava.sf.net/papers/drjava-paper.shtml";
420:
421: public static class ImageInfo {
422: private final String name;
423: private final Color color;
424:
425: public ImageInfo(String name, Color color) {
426: this .name = name;
427: this .color = color;
428: }
429: }
430:
431: public static String getLicense() {
432: if (initLicense)
433: return LICENSE;
434:
435: try {
436: InputStream is = AboutDialog.class
437: .getResourceAsStream("/edu/rice/cs/LICENSE");
438: if (is != null) {
439: BufferedReader r = new BufferedReader(
440: new InputStreamReader(is));
441: try {
442:
443: final StringBuilder sb = new StringBuilder();
444: for (String s = r.readLine(); s != null; s = r
445: .readLine()) {
446: int lastSig = s.length() - 1; // the last char index
447:
448: while (lastSig >= 0
449: && Character.isWhitespace(s
450: .charAt(lastSig)))
451: lastSig--;
452: if (lastSig < 0)
453: sb.append("\n"); // empty line, so insert two newlines.
454: else {
455: sb.append(s.substring(0, lastSig + 1));
456: sb.append('\n');
457: }
458: }
459: LICENSE = sb.toString();
460: LICENSE = LICENSE.trim();
461: if (LICENSE.length() == 0)
462: LICENSE = null;
463: } finally {
464: is.close();
465: r.close();
466: }
467: }
468: } catch (Exception e) {
469: throw new UnexpectedException(e, StringOps.getStackTrace(e));
470: }
471:
472: initLicense = true;
473: return LICENSE;
474: }
475:
476: private static void wrapBorder(JComponent c, Border b) {
477: c.setBorder(new CompoundBorder(b, c.getBorder()));
478: }
479: }
|