KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > MyTextPane


1 /*
2  * MyTextPane !:)==($)
3  * <P>
4  * @authors: Stefanovic Nenad, Puskas Vladimir, Bojanic Sasa
5  * @Date: July-November 2001.
6  */

7
8 import javax.swing.*;
9 import java.util.*;
10 import java.beans.*;
11 import java.net.URL JavaDoc;
12 import javax.swing.text.*;
13 import javax.swing.event.*;
14 import java.awt.datatransfer.*;
15 import javax.swing.text.html.*;
16 import java.awt.Color JavaDoc;
17
18 /**
19  * Since JTextPane does not redefines cut, copy, and paste methods inherited from JTextComponent
20  * there is a inconsistency in implementation. Although styled text can be drawn and typed in,
21  * clipboard operations aren't working as they suppose to. Hence this class.<p>
22  *
23  * Applets are tipically run in sandboxed environments, so if one wants to use system clipboard
24  * it is essential to configure one's machine properly.<br> Locate your JRE folder, and bellow it,
25  * there is <code>lib\security\java.security</code> file. There are lines similar to the next two:<p>
26  * <code>policy.url.1=file:${java.home}/lib/security/java.policy<br>
27  * <code>policy.url.2=file:${user.home}/.java.policy<p>
28  * Edit eighter file and insert into appropriate <b>grant</b> section line as follows<p>
29  * <code>permission java.awt.AWTPermission "accessClipboard", "access";<p>
30  * <b>Hint</b><br><code>.security</code> files you can edit using your favorite text editor or with
31  * <code>${java.home}\bin\policytool.exe</code>
32  */

33 public class MyTextPane extends JTextPane{
34
35    static final private String JavaDoc signature = "!:)==($)";
36 /**
37  * Constructs a new instance.
38  *
39  * There is not much to do. Let the superclass' constructor does the hard work.
40  */

41    public MyTextPane(){
42       super();
43       try {
44          jbInit();
45       }catch( Exception JavaDoc e ) {
46          e.printStackTrace();
47       }
48       pasteDeletesSelection = true;
49    }
50 /**
51  * Transfers the currently selected range to the system clipboard, <b>removing</b>
52  * the selection from the text. The current selection is reset. Does nothing for null selections.
53  */

54    public void cut(){
55       copy( true );
56    }
57
58    public void copyExt(){
59       super.copy();
60    }
61 /**
62  * Transfers the currently selected range to the system clipboard, <b>leaving</b>
63  * the selected text intact. The current selection is reset. Does nothing for null selections.
64  */

65    public void copy(){
66       copy( false );
67       setSelectionStart( getSelectionEnd());
68    }
69 /**
70  * Transfers the contents of the system clipboard into the associated text model.
71  * If there is no selection, the clipboard contents are inserted in front of the current insert
72  * position in the associated view. If the clipboard is empty, does nothing.
73  * If there is a selection in the associated view, behavior is described in the following note.
74  * <p><b>NOTE:</b><br> Paste operation depends on state which is set by setPasteDeletesSelection
75  * method. When true selection is deleted prior to actual pasting, otherwise text is inserted in
76  * front of selection. Default is true.
77  * @see #setPasteDeletesSelection
78  * @see #getPasteDeletesSelection
79  */

80    public void paste(){
81       if( myClipboard == null )
82          return;
83       if( pasteDeletesSelection ){
84          int selectionStart = getSelectionStart();
85          int selectionEnd = getSelectionEnd();
86          if( selectionStart < selectionEnd ){
87             try{
88                getStyledDocument().remove( selectionStart, selectionEnd - selectionStart );
89             }catch( BadLocationException e ){
90                e.printStackTrace();
91             }
92          }
93       }
94       try{
95          String JavaDoc clip = ( String JavaDoc )( myClipboard.getContents( DataFlavor.stringFlavor ).getTransferData( DataFlavor.stringFlavor ));
96 // test on length is crucial because substring method will throw an exception for strigs shorter than signature
97
if(( clip.length()> signature.length())&&( clip.substring( 0, signature.length()).equals( signature )))
98             takeIn( clip );
99          else
100             super.paste();
101       }catch( Exception JavaDoc e ){
102          e.printStackTrace();
103       }
104    }
105 /**
106  * Long and unforgettable name of this method is chosen to explain itself.
107  * @see #paste
108  * @see #setPasteDeletesSelection
109  * @return wether paste method would deleted selection.
110  */

111    public boolean getPasteDeletesSelection(){
112       return this.pasteDeletesSelection;
113    }
114 /**
115  * Long and unforgettable name of this method is chosen to explain itself.
116  * @see #paste
117  * @see #getPasteDeletesSelection
118  * @param value specifying wether paste method would deleted selection
119  */

120    public void setPasteDeletesSelection( boolean pasteDeletesSelection ){
121       this.pasteDeletesSelection = pasteDeletesSelection;
122    }
123 /* NOTE: Javadoc won't make this appear in generated documentation,
124  * still there are some private stuff, that need to be explained.
125  *
126  * One cannot know if system security settings will allow to use system clipboard, hence this
127  * field. Working methods wouldn't know what clipboard they are accessing, they don't need to
128  * know, while myClipboard is working properly.
129  */

130    private java.awt.datatransfer.Clipboard JavaDoc myClipboard;
131 /*
132  * Because paste can act two ways this field bares what way it should act.
133  */

134    private boolean pasteDeletesSelection;
135 /*
136  * Initializes the state of this instance.
137  * This won't appear in javadoc generated files. Method itself is included,...
138  * well I don't know why it is here.
139  */

140    private void jbInit() throws Exception JavaDoc{
141       pickClipboardToUse();
142    }
143 /*
144  * CUT and COPY operations are the same except CUT deletes text it copied to clipboard. This
145  * private method provides for both.
146  */

147    private void copy( boolean deleteToo ){
148       int selectionStart = getSelectionStart();
149       int selectionEnd = getSelectionEnd();
150       if( selectionStart >= selectionEnd )
151          return;
152       StringSelection stringCopied = new StringSelection( returnCopy( selectionStart, selectionEnd ));
153       myClipboard.setContents( stringCopied, stringCopied );
154       if( deleteToo ){
155          try{
156             getStyledDocument().remove( selectionStart, selectionEnd - selectionStart );
157          }catch( BadLocationException e ){
158             e.printStackTrace();
159          }
160       }
161    }
162 /*
163  * Here it is. Method pickClipboardToUse tries to connect JTextPane to system clipboard.
164  * If connection fails local clipboard is made, so cut, copy, paste functionality could
165  * work as expected.
166  */

167    //private void pickClipboardToUse(){
168
public void pickClipboardToUse(){
169       if( myClipboard != null )
170          return;
171       try{
172          System.getSecurityManager().checkSystemClipboardAccess();
173          myClipboard = getToolkit().getSystemClipboard();
174          System.out.println("Using system clipboard.");
175       }catch( SecurityException JavaDoc se ){
176          myClipboard = new Clipboard("TextEditor");
177          System.out.println("Using local clipboard, because system isn't available.");
178       }
179    }
180 /*
181  * Escape sequences used to store character and paragraph attributes in String are
182  * (all are preceded with backslash sign '\'):
183  *
184  * family = whatever font family is set its name is concatenated after this tag
185  * size = size of font in decimal representation
186  * style = (Bold, Italic, or Underlined)
187  * align = number which return and accept static methods of StyleConstants class
188  * color = rgb value
189  *
190  * private method takeIn does dirty work for paste method, parsing in content of myOwnClipboard
191  * and adding text into document together with attributes
192  */

193    private void takeIn( String JavaDoc myOwnClipboard ){
194       StyledDocument theDocument = getStyledDocument();
195       SimpleAttributeSet characterAttributes = new SimpleAttributeSet( theDocument.getCharacterElement( getSelectionStart()).getAttributes());
196       for( int i = signature.length(); i < myOwnClipboard.length(); ++i ){
197          String JavaDoc currentChar = myOwnClipboard.substring( i, 1 + i );
198          int insertHere = getSelectionStart();
199          if( currentChar.equals("\\")){
200             int nextBackSlash = myOwnClipboard.indexOf('\\', 1 + i );
201             if(( myOwnClipboard.charAt( i + 1 )=='\\')){
202                try{
203                   theDocument.insertString( insertHere, currentChar, characterAttributes );
204                   i++;
205                   continue;
206                }catch( BadLocationException e ){
207                   e.printStackTrace();
208                }
209             }
210             currentChar = myOwnClipboard.substring( i, myOwnClipboard.indexOf("\\", 1 + i ));
211             switch( currentChar.charAt( 2 )){
212                case 'l':
213                   StyleConstants.setAlignment( characterAttributes,( new Integer JavaDoc( currentChar.substring( 6 ))).intValue());
214                   try{
215                      theDocument.insertString( insertHere,"\n", characterAttributes );
216                      insertHere = getSelectionStart();
217                      theDocument.setParagraphAttributes( insertHere, 1, characterAttributes, true );
218                   }catch( BadLocationException e ){
219                      e.printStackTrace();
220                   }
221                   break;
222                case 't':
223                   if( currentChar.substring( 6 ).equals("Bold"))
224                      StyleConstants.setBold( characterAttributes, true );
225                   else if( currentChar.substring( 6 ).equals("Italic"))
226                      StyleConstants.setItalic( characterAttributes, true );
227                   else
228                      StyleConstants.setUnderline( characterAttributes, true );
229                   break;
230                case 'a':
231                   StyleConstants.setFontFamily( characterAttributes, currentChar.substring( 7 ));
232                   StyleConstants.setBold( characterAttributes, false );
233                   StyleConstants.setItalic( characterAttributes, false );
234                   StyleConstants.setUnderline( characterAttributes, false );
235                   break;
236                case 'o':
237                   StyleConstants.setForeground( characterAttributes, new Color JavaDoc( new Integer JavaDoc( currentChar.substring( 6 )).intValue()));
238                   break;
239                case 'i':
240                   StyleConstants.setFontSize( characterAttributes,( new Integer JavaDoc( currentChar.substring( 5 ))).intValue());
241                   break;
242             }
243             i += currentChar.length();
244          }else{
245             try{
246                theDocument.insertString( insertHere, currentChar, characterAttributes );
247             }catch( BadLocationException e ){
248                e.printStackTrace();
249             }
250          }
251       }
252    }
253 /*
254  * private method returnCopy is heart'n'soul of both cut and copy methods.
255  * Running through selection character by character it makes String representation of styled
256  * text which would be stored in clipboard.
257  */

258    private String JavaDoc returnCopy( int selectionStart, int selectionEnd ) {
259       StyledDocument theDocument = getStyledDocument( );
260       AttributeSet characterAttributes = theDocument.getCharacterElement( selectionStart ).getAttributes( );
261       String JavaDoc result = signature + shotOut( characterAttributes );
262       while(selectionStart < selectionEnd) {
263          AttributeSet currentAttributes = theDocument.getCharacterElement( selectionStart ).getAttributes( );
264          if(! characterAttributes.isEqual( currentAttributes )) {
265             result += shotOut( currentAttributes );
266             characterAttributes = currentAttributes.copyAttributes( );
267          }
268          try{
269             String JavaDoc theChar = theDocument.getText( selectionStart++, 1 );
270             if(theChar.equals( "\n" )) {
271                result += "\\align"+ StyleConstants.getAlignment( theDocument.getParagraphElement( selectionStart ).getAttributes())+"\\";
272             }else{
273                result += theChar;
274                if(theChar.equals("\\"))
275                   result += theChar;
276             }
277          }catch( BadLocationException e ) {
278             e.printStackTrace();
279          }
280       }
281       return( result );
282    }
283 /*
284  * private method shotOut returns String representation of current character attributes
285  * (font family, size, and style)
286  */

287    private String JavaDoc shotOut( AttributeSet attributes ){
288       String JavaDoc result = "\\family" + StyleConstants.getFontFamily( attributes )+"\\";
289       result += "\\color" + StyleConstants.getForeground( attributes ).getRGB()+"\\";
290       if( StyleConstants.isBold( attributes )){
291          result += "\\styleBold\\";
292       }
293       if( StyleConstants.isItalic( attributes )){
294          result += "\\styleItalic\\";
295       }
296       if( StyleConstants.isUnderline( attributes )){
297          result += "\\styleUnderline\\";
298       }
299       return( result +"\\size"+ StyleConstants.getFontSize( attributes )+"\\" );
300    }
301 }
302
Popular Tags