View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.support.components;
14  
15  import java.awt.Dimension;
16  import java.awt.Toolkit;
17  import java.awt.event.FocusEvent;
18  import java.awt.event.FocusListener;
19  import java.awt.event.KeyAdapter;
20  import java.awt.event.KeyEvent;
21  
22  import javax.swing.JTextArea;
23  import javax.swing.KeyStroke;
24  import javax.swing.event.UndoableEditEvent;
25  import javax.swing.event.UndoableEditListener;
26  import javax.swing.undo.CannotRedoException;
27  import javax.swing.undo.CannotUndoException;
28  import javax.swing.undo.UndoManager;
29  
30  import com.eviware.soapui.support.UISupport;
31  import com.eviware.soapui.support.actions.FindAndReplaceDialog;
32  import com.eviware.soapui.support.actions.FindAndReplaceable;
33  import com.eviware.soapui.support.components.JEditorStatusBar.JEditorStatusBarTarget;
34  import com.eviware.soapui.support.swing.JTextComponentPopupMenu;
35  
36  /***
37   * JTextArea with Undo/Redo keyboard/popup support
38   * 
39   * @author Ole.Matzura
40   */
41  
42  public class JUndoableTextArea extends JTextArea implements Undoable, UndoableEditListener, FocusListener,
43  		FindAndReplaceable, JEditorStatusBarTarget
44  {
45  	public static final int UNDO_LIMIT = 1500;
46  
47  	private UndoManager undoManager;
48  	private boolean discardEditsOnSet = false;
49  	private FindAndReplaceDialog findAndReplaceAction;
50  
51  	public JUndoableTextArea()
52  	{
53  		super();
54  		init();
55  	}
56  
57  	private void init()
58  	{
59  		// setBorder(BorderFactory.createEtchedBorder());
60  		getDocument().addUndoableEditListener( this );
61  		addFocusListener( this );
62  
63  		setMinimumSize( new Dimension( 50, 50 ) );
64  		addKeyListener( new KeyAdapter()
65  		{
66  
67  			public void keyPressed( KeyEvent e )
68  			{
69  				if( KeyStroke.getKeyStrokeForEvent( e ).equals( UISupport.getKeyStroke( "menu Z" ) ) )
70  					undo();
71  				else if( KeyStroke.getKeyStrokeForEvent( e ).equals( UISupport.getKeyStroke( "menu Y" ) ) )
72  					redo();
73  				else if( KeyStroke.getKeyStrokeForEvent( e ).equals( UISupport.getKeyStroke( "menu X" ) ) )
74  					cut();
75  				else if( KeyStroke.getKeyStrokeForEvent( e ).equals( UISupport.getKeyStroke( "menu C" ) ) )
76  					copy();
77  				else if( KeyStroke.getKeyStrokeForEvent( e ).equals( UISupport.getKeyStroke( "menu V" ) ) )
78  					paste();
79  				else if( KeyStroke.getKeyStrokeForEvent( e ).equals( UISupport.getKeyStroke( "F3" ) ) )
80  					findAndReplace();
81  				else
82  					return;
83  				
84  				e.consume();
85  			}
86  		} );
87  
88  		JTextComponentPopupMenu.add( this );
89  	}
90  
91  	public JUndoableTextArea( int i, int j )
92  	{
93  		super( i, j );
94  		init();
95  	}
96  
97  	public JUndoableTextArea( String text )
98  	{
99  		super( text );
100 		init();
101 	}
102 
103 	protected void findAndReplace()
104 	{
105 		if( findAndReplaceAction == null )
106 			findAndReplaceAction = new FindAndReplaceDialog( this );
107 
108 		findAndReplaceAction.show();
109 	}
110 
111 	public void setText( String text )
112 	{
113 		ensureUndoManager();
114 		super.setText( text == null ? "" : text );
115 
116 		if( discardEditsOnSet && undoManager != null )
117 			undoManager.discardAllEdits();
118 	}
119 
120 	public boolean isDiscardEditsOnSet()
121 	{
122 		return discardEditsOnSet;
123 	}
124 
125 	public void setDiscardEditsOnSet( boolean discardEditsOnSet )
126 	{
127 		this.discardEditsOnSet = discardEditsOnSet;
128 	}
129 
130 	public UndoManager getUndoManager()
131 	{
132 		return undoManager;
133 	}
134 
135 	private void ensureUndoManager()
136 	{
137 		if( isEditable() && undoManager == null )
138 		{
139 			undoManager = new UndoManager();
140 			undoManager.setLimit( UNDO_LIMIT );
141 		}
142 	}
143 
144 	public void focusGained( FocusEvent fe )
145 	{
146 		ensureUndoManager();
147 	}
148 
149 	public void focusLost( FocusEvent fe )
150 	{
151 		// removeUndoMananger();
152 	}
153 
154 	public void undoableEditHappened( UndoableEditEvent e )
155 	{
156 		if( undoManager != null )
157 			undoManager.addEdit( e.getEdit() );
158 	}
159 
160 	public void undo()
161 	{
162 		if( !isEditable() )
163 		{
164 			getToolkit().beep();
165 			return;
166 		}
167 
168 		try
169 		{
170 			if( undoManager != null )
171 				undoManager.undo();
172 		}
173 		catch( CannotUndoException cue )
174 		{
175 			Toolkit.getDefaultToolkit().beep();
176 		}
177 	}
178 
179 	public void redo()
180 	{
181 		if( !isEditable() )
182 		{
183 			getToolkit().beep();
184 			return;
185 		}
186 
187 		try
188 		{
189 			if( undoManager != null )
190 				undoManager.redo();
191 		}
192 		catch( CannotRedoException cue )
193 		{
194 			Toolkit.getDefaultToolkit().beep();
195 		}
196 	}
197 
198 	public void setSelectedText( String txt )
199 	{
200 		replaceSelection( txt );
201 	}
202 
203 	public boolean canRedo()
204 	{
205 		return undoManager != null && undoManager.canRedo();
206 	}
207 
208 	public boolean canUndo()
209 	{
210 		return undoManager != null && undoManager.canUndo();
211 	}
212 }