1 /* 2 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.tools.jconsole; 27 28 import java.awt.Font; 29 import java.awt.event.WindowAdapter; 30 import java.awt.event.WindowEvent; 31 import java.io.*; 32 33 import javax.swing.*; 34 35 /** 36 * A simple console window to display messages sent to System.out and 37 * System.err. 38 * 39 * A stop-gap solution until an error dialog is implemented. 40 */ 41 public class OutputViewer { 42 private static JFrame frame; 43 private static JTextArea ta; 44 45 static { 46 System.setOut(PipeListener.create("System.out")); 47 System.setErr(PipeListener.create("System.err")); 48 } 49 50 // Dummy to cause class to be loaded init()51 public static void init() { } 52 append(String s)53 private static void append(String s) { 54 if (frame == null) { 55 // FIXME: The frame title should be a localized string. 56 frame = new JFrame("JConsole: Output"); 57 ta = new JTextArea(); 58 ta.setEditable(false); 59 frame.getContentPane().add(new JScrollPane(ta)); 60 ta.setFont(new Font("Monospaced", Font.BOLD, 14)); 61 frame.setSize(500, 600); 62 frame.setLocation(1024-500, 768-600); 63 // Exit JConsole if no window remains. 64 // e.g. jconsole -version only creates the OutputViewer 65 // but no other window. 66 frame.addWindowListener(new WindowAdapter() { 67 public void windowClosing(WindowEvent e) { 68 if (JFrame.getFrames().length == 1) { 69 System.exit(0); 70 } 71 } 72 }); 73 } 74 ta.append(s); 75 ta.setCaretPosition(ta.getText().length()); 76 frame.setVisible(true); 77 } 78 appendln(String s)79 private static void appendln(String s) { 80 append(s+"\n"); 81 } 82 83 private static class PipeListener extends Thread { 84 public PrintStream ps; 85 private String name; 86 private PipedInputStream inPipe; 87 private BufferedReader br; 88 create(String name)89 public static PrintStream create(String name) { 90 return new PipeListener(name).ps; 91 } 92 PipeListener(String name)93 private PipeListener(String name) { 94 this.name = name; 95 96 try { 97 inPipe = new PipedInputStream(); 98 ps = new PrintStream(new PipedOutputStream(inPipe)); 99 br = new BufferedReader(new InputStreamReader(inPipe)); 100 } catch (IOException e) { 101 appendln("PipeListener<init>("+name+"): " + e); 102 } 103 start(); 104 } 105 run()106 public void run() { 107 try { 108 String str; 109 while ((str = br.readLine()) != null) { 110 appendln(str); 111 112 // Hack: Turn off thread check in PipedInputStream. 113 // Any thread should be allowed to write except this one 114 // but we just use this one to keep the pipe alive. 115 try { 116 java.lang.reflect.Field f = 117 PipedInputStream.class.getDeclaredField("writeSide"); 118 f.setAccessible(true); 119 f.set(inPipe, this); 120 } catch (Exception e) { 121 appendln("PipeListener("+name+").run: "+e); 122 } 123 } 124 appendln("-- "+name+" closed --"); 125 br.close(); 126 } catch (IOException e) { 127 appendln("PipeListener("+name+").run: "+e); 128 } 129 } 130 } 131 } 132