Source code: com/diaam/lgpl/ts/TerminalStandard.java
1 /*
2 * $Log: TerminalStandard.java,v $
3 * Revision 1.2 2001/02/09 16:59:59 desnoix
4 * *** empty log message ***
5 *
6 * Revision 1.1 2000/11/10 15:31:30 vonarnim
7 * - deplacement (et nouvelle version) de TerminalStandard dans ctulu
8 *
9 * Revision 1.1 1999/11/04 19:50:37 Herve_AGNOUX
10 * Initial revision
11 *
12 */
13 /*
14 -- TerminalStandard v111999
15
16 Fichier : TerminalStandard.java
17 Auteur : Hervé AGNOUX, hagnoux@mail.club-internet.fr
18 License LGPL.
19 */
20
21 package com.diaam.lgpl.ts;
22
23 import java.awt.*;
24 import java.awt.event.*;
25 import java.io.*;
26
27 import javax.swing.*;
28 import javax.swing.event.DocumentEvent;
29 import javax.swing.text.BadLocationException;
30 import javax.swing.text.Document;
31 import javax.swing.text.Style;
32 import javax.swing.text.StyleContext;
33 import javax.swing.text.StyleConstants;
34
35 /**
36 * Cette classe, à l'origine du package, n'est plus qu'une vague
37 * utilisation de la classe ShSh... Grandeur et décadence...
38 * La classe <code>TerminalStandard</code> permet de placer
39 * les flux standards (in, out, err) d'une appli dans une
40 * fenêtre swing.<br>
41 * La méthode 'main' présente un exemple basique d'utilisation.
42 * Certaine classes statiques facilitent sont intégration dans des applis.
43 * Cette classe est en diffusion LGPL, et elle est téléchargeable à
44 * <a href="http://perso.club-internet.fr/hagnoux/java/TerminalStandard">
45 * http://perso.club-internet.fr/hagnoux/java/TerminalStandard</a><br>
46 * @author <a href="h_agnoux.html">Hervé AGNOUX</a>,
47 * hagnoux@mail.club-internet.fr
48 * @version 111999
49 */
50 public class TerminalStandard extends javax.swing.JPanel
51 {
52 /**
53 * Pratique pour deboguer. Cet attribut conserve
54 * le System.out original.
55 */
56 public static final PrintStream ini = System.out;
57
58 private ShSh monPays;
59 private PrintStream oriOut;
60 private PrintStream oriErr;
61 private InputStream oriIn;
62 private FileWriter log;
63
64 /**
65 * Le constructeur créé le ShSh, le place dans un
66 * <code>JScrollPane</code>, et ajoute le tout au centre d'un
67 * BorderLayout du panneau.
68 */
69 public TerminalStandard()
70 {
71 try {
72 log=new FileWriter(System.getProperty("user.dir")+File.separator+"ts.log");
73 } catch( IOException e ) { System.err.println("TS: impossible de creer le fichier de log"); }
74 try
75 {
76 Document d;
77 JScrollPane jsp;
78
79 monPays = new ShSh(log);
80 Style fs=monPays.getStyle(StyleContext.DEFAULT_STYLE);
81 FontMetrics fm=monPays.getFontMetrics(
82 new Font(StyleConstants.getFontFamily(fs), Font.PLAIN, StyleConstants.getFontSize(fs)));
83 d = monPays.getDocument();
84 d.insertString
85 (0,
86 "TerminalStandard v111999\n"+
87 "(c)1999 Hervé AGNOUX <hagnoux@diaam.com>\n"+
88 "Distribué sous les termes de la LGPL\n"+
89 "\n", null);
90 jsp = new JScrollPane(monPays);
91 setLayout(new BorderLayout());
92 add("Center", jsp);
93 setPreferredSize(
94 new Dimension(
95 fm.stringWidth(
96 "mmmmmmmmmmmmmmmmmmmm"+
97 "mmmmmmmmmmmmmmmmmmmm"+
98 "mmmmmmmmmmmmmmmmmmmm"+
99 "mmmmmmmmmmmmmmmmmmmmm"),
100 fm.getHeight()*25));
101 }
102 catch (BadLocationException ble)
103 {
104 throw new IllegalStateException(ble.toString());
105 }
106 }
107
108 /**
109 * Cette méthode va chercher les flux de ShSh, et par
110 * l'intermédiaire de leur méthode "asStream", les assigne
111 * comme flux standard de l'appli.
112 */
113 public void activeStandards()
114 {
115 SwingTextDocumentWriter stdw1, stdw2;
116 MinReader mr;
117
118 if (oriIn == null)
119 {
120 oriIn = System.in;
121 oriOut = System.out;
122 oriErr = System.err;
123 stdw1 = monPays.rédacteur();
124 System.setOut(new PrintStream(stdw1.asStream()));
125 stdw2 = monPays.gueulard();
126 System.setErr(new PrintStream(stdw2.asStream()));
127 mr = monPays.lecteur();
128 System.setIn(mr.asStream());
129 }
130 }
131
132 /**
133 * Redirige le focus vers le ShSh interne.
134 */
135 public void requestFocus()
136 {
137 if (isRequestFocusEnabled())
138 monPays.requestFocus();
139 }
140
141 /**
142 * rétablit les flux originaux de l'appli.
143 */
144 public void removeNotify()
145 {
146 if (oriIn != null)
147 {
148 System.setIn(oriIn);
149 System.setOut(oriOut);
150 System.setErr(oriErr);
151 }
152 super.removeNotify();
153 }
154
155 /**
156 * Pour utiliser TerminalStandard comme une appli (qui sert à quoi ? :-((
157 * Je sais pas) (Mais si ! Allez voir la classe ScriptsStream !
158 * @param lui le TerminalStandard qu'on veut utiliser.
159 * @return une JFrame contenant "lui" (hum !), disposée par un
160 * BorderLayout avec "lui" en son centre, une barre d'outil au nord,
161 * le focus redirigé vers elle, l'arrêt de l'appli si on clique sur la
162 * croix...
163 */
164 public static JFrame enAppli(final TerminalStandard lui)
165 {
166 JFrame jf;
167 Container c;
168 Dimension d;
169 JToolBar jtb;
170
171 lui.activeStandards();
172 jf = new JFrame();
173 jf.addWindowListener(new WindowAdapter()
174 {
175 public void windowClosing(WindowEvent e)
176 {System.exit(0);}
177 public void windowActivated(WindowEvent e)
178 {lui.requestFocus();}
179 });
180 c = jf.getContentPane();
181 c.setLayout(new BorderLayout());
182 c.add("Center", lui);
183 jtb = new JToolBar();
184 jtb.add(new ActionSauvegarde(lui.monPays));
185 c.add("North", jtb);
186 d = Toolkit.getDefaultToolkit().getScreenSize();
187 jf.setBounds
188 ((d.width * 10)/100, (d.height * 15)/100,
189 (d.width * 60)/100, (d.height * 50)/100);
190 jf.setIconImage
191 (Toolkit.getDefaultToolkit().getImage
192 (lui.getClass().getResource("tsico.gif")));
193 return jf;
194 }
195
196 /**
197 * Pour utiliser TerminalStandard en fenêtre de log, à coté de l'appli
198 * principale. Cette fenêtre n'apparait QUE SI on écrit quelque chose
199 * dessus. Si l'utilisateur la referme, elle reste cachée, et
200 * réapparrait dés que l'on re-écrit quelque chose dessus. Son
201 * apparence et sa disposition générale sont la même qu'avec
202 * "enAppli".
203 * @param lui le TerminalStandard à utiliser.
204 * @return une JFrame de fenêtre.
205 * @see #enAppli
206 */
207 public static JFrame pourAfficherLog(TerminalStandard lui)
208 {
209 Dimension d;
210 EcritureDocumentFaitJaillir edfj;
211 JFrame jf;
212 Container c;
213 JToolBar jtb;
214
215 lui.activeStandards();
216 jf = new JFrame();
217 edfj = lui.new EcritureDocumentFaitJaillir(jf, lui);
218 lui.monPays.getDocument().addDocumentListener(edfj);
219 c = jf.getContentPane();
220 c.setLayout(new BorderLayout());
221 c.add("Center", lui);
222 jtb = new JToolBar();
223 jtb.add(new ActionSauvegarde(lui.monPays));
224 c.add("North", jtb);
225 d = Toolkit.getDefaultToolkit().getScreenSize();
226 jf.setBounds
227 ((d.width * 15)/100, (d.height * 20)/100,
228 (d.width * 80)/100, (d.height * 60)/100);
229 jf.setTitle("TerminalStandard : fenêtre de log");
230 return jf;
231 }
232
233 /**
234 * Un exemple à suivre...
235 * Voici le code modèle :<pre>
236 * TerminalStandard ts;
237 * JFrame jf;
238 *
239 * ts = new TerminalStandard();
240 * jf = TerminalStandard.enAppli(ts);
241 * jf.show();
242 * System.out.println("Hello bizou !");
243 * // Hello bizou apparaît sur l'écran swing !
244 * </pre>
245 * Amusez vous bien.
246 */
247 public static void main(String args[]) throws IOException
248 {
249 JFrame jf;
250 final TerminalStandard ts;
251
252 ts = new TerminalStandard();
253 jf = TerminalStandard.enAppli(ts);
254 jf.show();
255 System.out.println
256 ("tapez 'q', pour sortir, \nou 'x' pour montrer "+
257 "une exception sur la sortie erreur.");
258 while (true)
259 {
260 int i;
261
262 i = System.in.read();
263 if ((char)i == 'q')
264 System.exit(0);
265 else if ((char)i == 'x')
266 {
267 Exception e = new Exception("La belle !");
268 e.printStackTrace();
269 }
270 System.out.print(""+(char)i);
271 }
272 }
273
274 private class EcritureDocumentFaitJaillir
275 implements javax.swing.event.DocumentListener
276 {
277 JFrame maFenêtre;
278 TerminalStandard maConsole;
279
280 private EcritureDocumentFaitJaillir
281 (JFrame fenêtre, TerminalStandard console)
282 {
283 maFenêtre = fenêtre;
284 maConsole = console;
285 }
286
287 public void changedUpdate(DocumentEvent de)
288 {
289 }
290
291 public void insertUpdate(DocumentEvent de)
292 {
293 if (maFenêtre.isVisible())
294 return;
295 maFenêtre.setVisible(true);
296 }
297
298 public void removeUpdate(DocumentEvent de)
299 {
300 }
301 }
302 }