Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/diaam/lgpl/ts/ShSh.java


1   /*
2    * $Log: ShSh.java,v $
3    * Revision 1.1  2000/11/10 15:31:30  vonarnim
4    * - deplacement (et nouvelle version) de TerminalStandard dans ctulu
5    *
6    * Revision 1.1  1999/11/04 20:02:41  Herve_AGNOUX
7    * Initial revision
8    * License LGPL.
9    * hgnoux@diaam.com
10   */
11  /*
12  -- TerminalStandard v111999
13  
14  Fichier : ShSh.java
15  Auteur : Hervé AGNOUX, hagnoux@mail.club-internet.fr
16  License LGPL.
17  */
18  
19  package com.diaam.lgpl.ts;
20  
21  
22  import java.awt.AWTError;
23  import java.awt.AWTEvent;
24  import java.awt.BorderLayout;
25  import java.awt.Dimension;
26  import java.awt.event.*;
27  import java.io.*;
28  import java.util.Enumeration;
29  
30  import javax.swing.*;
31  import javax.swing.text.*;
32  import javax.swing.event.CaretListener;
33  import javax.swing.event.CaretEvent;
34  import javax.swing.event.DocumentEvent;
35  
36  /**
37   * <code>ShSh</code> est une classe qui a l'ambition de mettre n'importe
38   * quel shell dans swing. <em>L'ambition</em> seulement... Ne me faites
39   * pas dire ce que je n'ai pas dit... A cet effet, une interface générale
40   * est à l'étude, visible dans les packages "script", "realscripts", et
41   * "applications".<br>
42   * ShSh constitue, avec les classes <code>MinReader</code> et
43   * <code>SwingTextDocumentWriter</code>, le pivot du package.<br>
44   * ShSh permet à l'utilisateur de faire... un copier/coller sur 
45   * les commandes ! N'est ce pas merveilleux !? Merci, SWING !
46   * Pour la gestion interne, elle utilise la notion d'attribut. Cette
47   * gestion est trés mal faite, mais elle fonctionne.<p>
48   * Quelles sont les évolutions depuis la précédente version ? Pas grand
49   * chose, vu de l'extérieur.
50   * <ul>
51   * <li> les méthodes d'accés aux flux renvoient maintenant des MinReader et
52   * autres SwingTextDocumentWriter, ceci pour accéder à leur méthode
53   * "asStream" pour quand on est obliger les flux d'octets. Avant, elles
54   * renvoyaient simplement des Reader et des Writer.
55   * <li> une grosse modif : au lieu de descendre d'un JTextArea, elle
56   * descend maintenant d'un JTextPane. Cela permet d'utiliser la gestion
57   * des attributs pour la cuisine interne, et d'espérer que dans de futures
58   * versions cette cuisine soit mieux faite.
59   * </ul>
60   * Comment travaille cette classe ? Ce qu'elle reçoit du clavier, elle
61   * le renvoit sur un MinReader ; et lorsque le document associé se modifie,
62   * normalement par l'intermédiaire d'un SwingTextDocumentWriter, ça
63   * s'affiche automatiquement. Ce qui est moins automatique, c'est la gestion
64   * du curseur dans ce cas. Voyez les sources pour constater les jongleries.
65   * <p>Cette classe est en diffusion LGPL, et elle est téléchargeable à
66   * <a href="http://perso.club-internet.fr/hagnoux/java/TerminalStandard">
67   * http://perso.club-internet.fr/hagnoux/java/TerminalStandard</a>.<br>
68   * ... au fait ! Qu'est ce que <big>
69   * <a href="http://www.diaam.com">diaam</a></big> ?
70   * @author <a href="h_agnoux.html">Hervé AGNOUX</a>, 
71   * hagnoux@mail.club-internet.fr
72   * @version 111999
73   * @see MinReader
74   * @see SwingTextDocumentWriter
75   */
76  public class ShSh extends javax.swing.JTextPane
77  {
78    private MinReader tubeClavier;
79    private SwingTextDocumentWriter tubeSortieFenêtre;
80    private SimpleAttributeSet attrs;
81  
82    /**
83     * Initialise les flux d'entrée/sortie, et un listener pour le caret,
84     * et un listener pour le clavier. Ecoute ce qui se passe sur le document,
85     * et prépare les attributs caractères de façon à pister ceux qui viennent
86     * du clavier.
87     */
88    public ShSh()
89      {
90        this(null);
91      }
92    public ShSh(FileWriter _log)
93      {
94          tubeSortieFenêtre = new SwingTextDocumentWriter(getDocument(), _log);
95          tubeClavier = new MinReader();
96     addCaretListener(new DuCurseur());
97    addKeyListener(new DuClavier());
98      getDocument().addDocumentListener(new DuDocument());
99    attrs = new SimpleAttributeSet();
100   attrs.addAttribute(this, "pas mal !");
101   super.replaceSelection("\n");
102     }
103     
104   /**
105    * @return l'équivalent de l'entrée standard.
106    */
107   public MinReader lecteur()
108     {
109         return tubeClavier;
110     }
111     
112   /**
113    * @return l'équivalent de la sortie standard.
114    */
115     public SwingTextDocumentWriter rédacteur()
116     {
117         return tubeSortieFenêtre;
118     }
119     
120   /**
121    * @return l'équivalent de la sortie erreur standard.
122    */
123     public SwingTextDocumentWriter gueulard()
124     {
125         return tubeSortieFenêtre;
126     }
127     
128   /**
129    * En plus du comportement normal, elle envoit la chaîne tapée au 
130    * clavier vers le lecteur (entrée standard) à chaque retour chariot.
131    * Normalement, encore une fois, tout ce qui vient du clavier passe par
132    * ici.
133    * @param content le contenu (-> le caractère tapé au clavier, ou le
134    * "collé" si on a fait un "copié/collé").
135    */
136     public void replaceSelection(String content)
137     {
138         try
139         {
140     setCharacterAttributes(attrs, true);
141           super.replaceSelection(content);
142     // on suppose abusivement que 'content' ne contient
143     // qu'un caractère...
144     if (content.charAt(0) == '\n')
145     {
146       int s;
147       int f;
148       String str;
149       int l;
150       
151       s = tubeSortieFenêtre.offsetAtteint();
152       f = getDocument().getLength();
153       str = getDocument().getText(s, f - s);
154       l = str.length();
155       for (int i = 0; i < l;i++)
156         tubeClavier.aj(str.charAt(i));
157     }
158   }
159   catch (BadLocationException ble)
160   {
161     throw new AWTError(ble.toString());
162   }
163     }
164 
165   class DuCurseur implements CaretListener
166   {
167     public void caretUpdate(CaretEvent e)
168     {
169       if (tubeSortieFenêtre.offsetAtteint() <= e.getDot())
170   {
171     if (!isEditable())
172       setEditable(true);
173   }
174       else
175   {
176     if (isEditable())
177       setEditable(false);
178   }
179     }
180   }
181 
182   class DuClavier extends KeyAdapter
183   {
184     public void keyPressed(KeyEvent e)
185     {
186       if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE)
187   {
188     if (tubeSortieFenêtre.offsetAtteint() == getCaret().getDot())
189       {
190     e.consume();
191       }
192   }
193     }
194   }
195 
196     private class DuDocument implements javax.swing.event.DocumentListener
197     {
198   public void changedUpdate(DocumentEvent de)
199   {
200   }
201 
202   public void insertUpdate(final DocumentEvent de)
203   {
204       final Document d;
205       Runnable r;
206 
207       d = de.getDocument();
208       final int i1, i2;
209       final int l;
210       i1 = de.getOffset();
211       i2 = de.getLength();
212       l = d.getLength();
213       if (l == i1 + i2)
214     {
215         Element e1 = d.getDefaultRootElement();
216         Element e2 = e1.getElement(e1.getElementIndex(i1));
217         while (!e2.isLeaf())
218       e2 = e2.getElement(e2.getElementIndex(i1));
219         final Element e3 = e2;
220         AttributeSet as = e3.getAttributes();
221         if (as.isDefined(tubeSortieFenêtre))
222       if (getCaretPosition() != l)
223         {
224             setCaretPosition(l);
225         }
226     }
227   }
228 
229   public void removeUpdate(DocumentEvent de)
230   {
231   }
232     }
233 
234   /**
235    * Juste pour le test...
236    * @exception Exception R.A.S.
237    */
238     public static void main(String args[]) throws Exception
239     {
240     JFrame jf;
241     JPanel jp;
242     JScrollPane jsp;
243     ShSh ss;
244     Writer stdw;
245         BufferedReader br;
246     
247     jf = new JFrame("ShSh");
248     jp = new JPanel();
249     jp.setLayout(new BorderLayout());
250     jp.setPreferredSize(new Dimension(400, 250));
251     ss = new ShSh();
252     jsp = new JScrollPane(ss);
253     jp.add("Center", jsp);
254     jf.setContentPane(jp);
255     jf.pack();
256     jf.addWindowListener(new WindowAdapter() 
257         {
258         public void windowClosing(WindowEvent e)
259         {System.exit(0);}
260         });
261     stdw = ss.rédacteur();
262     jf.show();
263     ss.requestFocus();
264           br = new BufferedReader(ss.lecteur());
265           stdw.write("GO !");
266     while (true)
267     {
268               String lu;
269 
270               lu = br.readLine();
271               stdw.write(lu);
272     }
273   }
274 }