KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > BuildTool


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is Terminal Emulator.
16  * The Initial Developer of the Original Software is Sun Microsystems, Inc..
17  * Portions created by Sun Microsystems, Inc. are Copyright (C) 2001.
18  * All Rights Reserved.
19  *
20  * Contributor(s): Ivan Soleimanipour.
21  */

22
23 import java.io.*;
24 import java.awt.*;
25 import java.awt.event.*;
26 import javax.swing.*;
27 import javax.swing.border.*;
28
29 import org.netbeans.lib.terminalemulator.*;
30
31 /*
32  * A simple demonstration of using ActiveTerm for highlighting compiler
33  * error output. Most of the machinery in this code is concerened with
34  * starting the build and capturing the output unfortunately.
35  * - The Compiler is started in a separate thread so that we quickly
36  * return from the button action handler.
37  * - We have separate readers for stdout and stderr because alternating
38  * between them in a loop may cause deadlocks, and using Reader.ready()
39  * will cause needless CPU looping.
40  * - Note that since Java provides no facility for merging stdout
41  * and stderr at the origin that by the time the outputs make it
42  * through the OS and BufferedReaders buffers all ordering information
43  * is lost.
44  */

45
46 public class BuildTool extends JFrame implements ActionListener {
47
48     private ActiveTerm term;
49     private JButton b_javac;
50     private JTextField t_files;
51
52     private Object JavaDoc sync = new Object JavaDoc();
53
54     /**
55      * Create a simple red square glyph image
56      */

57     private Image glyph(int dim) {
58     int xpoints[] = {1, 1, dim-1, dim-1};
59     int ypoints[] = {1, dim-1, dim-1, 1};
60     Polygon square = new Polygon(xpoints, ypoints, 4);
61     Image i = term.getTopLevelAncestor().createImage(dim, dim);
62     Graphics g = i.getGraphics();
63     g.setColor(Color.white);
64     g.fillRect(0, 0, dim, dim);
65     g.setColor(Color.red);
66     g.fillPolygon(square);
67     g.setColor(Color.black);
68     g.drawPolygon(square);
69     g.dispose();
70     return i;
71     }
72
73     private void setup_gui() {
74
75     // Handle quit from WM
76
addWindowListener(new WindowAdapter() {
77         public void windowClosing(WindowEvent e) {
78         System.exit(0);
79         }
80     });
81
82     term = new ActiveTerm();
83     term.setFont(new Font("Helvetica", Font.PLAIN, 10));
84
85     term.setBackground(Color.white);
86     term.setGlyphGutterWidth(20);
87     term.setClickToType(false);
88     term.setHighlightColor(Color.orange);
89
90     term.setActionListener(new ActiveTermListener() {
91         public void action(ActiveRegion r, InputEvent e) {
92         if (r.isLink()) {
93             String JavaDoc text = term.textWithin(r.begin, r.end);
94             JOptionPane.showMessageDialog(term,
95             "Get the editor to show " + text,
96             "Syntax error",
97             JOptionPane.DEFAULT_OPTION);
98         }
99         }
100     } );
101
102     JToolBar toolbar = new JToolBar();
103     toolbar.setMargin(new Insets(5, 5, 5, 5));
104     toolbar.setFloatable(false);
105         b_javac = new JButton("Build");
106         b_javac.addActionListener(this);
107         toolbar.add(b_javac);
108
109         toolbar.addSeparator();
110
111         t_files = new JTextField();
112         t_files.setColumns(10);
113         t_files.setText("<Enter java file names and press Build>");
114         toolbar.add(t_files);
115
116     getContentPane().add(toolbar, BorderLayout.NORTH);
117     getContentPane().add(term, BorderLayout.CENTER);
118
119     pack();
120     }
121
122     public void setup() {
123     // Have to do this image creation business
124
// after we've become visible
125

126     Dimension glyph_cell_size = term.getGlyphCellSize();
127     term.setGlyphImage(48, glyph(glyph_cell_size.height));
128     }
129
130
131     public void actionPerformed(ActionEvent e) {
132
133     if (e.getSource() == b_javac) {
134         String JavaDoc what = t_files.getText();
135         Thread JavaDoc compiler = new Compiler JavaDoc("javac", what);
136         compiler.start();
137     }
138     }
139
140     class Compiler extends Thread JavaDoc {
141     String JavaDoc args;
142     String JavaDoc command;
143     Compiler(String JavaDoc command, String JavaDoc args) {
144         this.command = command;
145         this.args = args;
146     }
147     public void run() {
148         run_compile(command, args);
149     }
150     }
151
152     private void run_compile(String JavaDoc cmd, String JavaDoc files) {
153
154     term.clearHistory();
155
156     term.setAnchored(true);
157
158     // echo issued command in bold
159
String JavaDoc command = cmd + " " + files;
160     term.setAttribute(1); // bold
161
term.appendText(command + "\n", true);
162     term.setAttribute(0); // default
163

164     Process JavaDoc proc = null;
165     try {
166         proc = Runtime.getRuntime().exec(command, null, null);
167     } catch (Exception JavaDoc x) {
168         x.printStackTrace();
169         System.exit(1);
170     }
171
172
173     int nreaders = 0;
174
175     InputStream pout = proc.getInputStream();
176     Reader out_R = new Reader(pout, this);
177     nreaders++;
178     out_R.start();
179
180     InputStream perr = proc.getErrorStream();
181     if (perr != null) {
182         Reader err_R = new Reader(perr, this);
183         nreaders++;
184         err_R.start();
185     }
186
187     // wait until we've drained all output
188
while (nreaders > 0) {
189         try {
190         synchronized(sync) {
191             sync.wait();
192         }
193         } catch (InterruptedException JavaDoc x) {
194         System.out.println("Compiler wait interrupted");
195         continue;
196         }
197         nreaders--;
198     }
199
200     term.endRegion();
201
202     term.setAttribute(1); // bold
203
term.appendText("No more output\n", true);
204
205     // wait until child exits
206
try {
207         proc.waitFor();
208     } catch (Exception JavaDoc x) {}
209
210     term.appendText("Command done\n", true);
211     term.setAttribute(0); // default
212
}
213
214
215     /**
216      * Read and process compiler output.
217      * The semantics of the processing are accomplished by the 'sink', us.
218      */

219
220     class Reader extends Thread JavaDoc {
221     BufferedReader source;
222     BuildTool sink;
223
224     Reader(InputStream src, BuildTool sink) {
225         this.source = new BufferedReader(new InputStreamReader(src));
226         this.sink = sink;
227     }
228
229     public void run() {
230         while (true) {
231         String JavaDoc line = null;
232         try {
233             line = source.readLine();
234         } catch (IOException x) {
235             x.printStackTrace();
236             sink.done();
237             break;
238         }
239
240         if (line == null) {
241             sink.done();
242             break;
243         } else {
244             sink.process_line(line);
245         }
246         }
247     }
248     }
249
250     private ActiveRegion region = null;
251
252     synchronized private void process_line(String JavaDoc line) {
253     // System.out.println(line);
254

255     int jx = line.indexOf(".java:");
256
257     if (jx != -1) {
258         // new error message detected
259
term.setGlyph(48, 0);
260
261         if (region != null)
262         term.endRegion();
263         region = term.beginRegion(false);
264         region.setFeedbackEnabled(true);
265         region.setSelectable(true);
266
267         int cx1 = line.indexOf(":"); // index of first colon
268
int cx2 = line.indexOf(":", cx1+1); // index of second colon
269

270         String JavaDoc srcloc = line.substring(0, cx2);
271         ActiveRegion link = term.beginRegion(true);
272         link.setLink(true);
273         link.setFeedbackViaParent(true);
274         term.appendText(srcloc, false);
275         term.endRegion();
276
277         String JavaDoc rest = line.substring(cx2);
278         term.appendText(rest, true);
279     } else {
280         term.appendText(line, true);
281     }
282
283     term.putChar((char)10);
284     term.putChar((char)13);
285     }
286
287
288     public void done() {
289     // declare that a Reader is done
290
synchronized(sync) {
291         sync.notify();
292     }
293     }
294
295     public static void main(String JavaDoc[] args) {
296     BuildTool app = new BuildTool();
297     app.setup_gui();
298     app.setVisible(true);
299     app.setup();
300     }
301 }
302
Popular Tags