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( "F3" ) ) )
78  					findAndReplace();
79  			}
80  		} );
81  
82  		JTextComponentPopupMenu.add( this );
83  	}
84  
85  	public JUndoableTextArea( int i, int j )
86  	{
87  		super( i, j );
88  		init();
89  	}
90  
91  	public JUndoableTextArea( String text )
92  	{
93  		super( text );
94  		init();
95  	}
96  
97  	protected void findAndReplace()
98  	{
99  		if( findAndReplaceAction == null )
100 			findAndReplaceAction = new FindAndReplaceDialog( this );
101 
102 		findAndReplaceAction.show();
103 	}
104 
105 	public void setText( String text )
106 	{
107 		ensureUndoManager();
108 		super.setText( text == null ? "" : text );
109 
110 		if( discardEditsOnSet && undoManager != null )
111 			undoManager.discardAllEdits();
112 	}
113 
114 	public boolean isDiscardEditsOnSet()
115 	{
116 		return discardEditsOnSet;
117 	}
118 
119 	public void setDiscardEditsOnSet( boolean discardEditsOnSet )
120 	{
121 		this.discardEditsOnSet = discardEditsOnSet;
122 	}
123 
124 	public UndoManager getUndoManager()
125 	{
126 		return undoManager;
127 	}
128 
129 	private void ensureUndoManager()
130 	{
131 		if( isEditable() && undoManager == null )
132 		{
133 			undoManager = new UndoManager();
134 			undoManager.setLimit( UNDO_LIMIT );
135 		}
136 	}
137 
138 	public void focusGained( FocusEvent fe )
139 	{
140 		ensureUndoManager();
141 	}
142 
143 	public void focusLost( FocusEvent fe )
144 	{
145 		// removeUndoMananger();
146 	}
147 
148 	public void undoableEditHappened( UndoableEditEvent e )
149 	{
150 		if( undoManager != null )
151 			undoManager.addEdit( e.getEdit() );
152 	}
153 
154 	public void undo()
155 	{
156 		if( !isEditable() )
157 		{
158 			getToolkit().beep();
159 			return;
160 		}
161 
162 		try
163 		{
164 			if( undoManager != null )
165 				undoManager.undo();
166 		}
167 		catch( CannotUndoException cue )
168 		{
169 			Toolkit.getDefaultToolkit().beep();
170 		}
171 	}
172 
173 	public void redo()
174 	{
175 		if( !isEditable() )
176 		{
177 			getToolkit().beep();
178 			return;
179 		}
180 
181 		try
182 		{
183 			if( undoManager != null )
184 				undoManager.redo();
185 		}
186 		catch( CannotRedoException cue )
187 		{
188 			Toolkit.getDefaultToolkit().beep();
189 		}
190 	}
191 
192 	public void setSelectedText( String txt )
193 	{
194 		replaceSelection( txt );
195 	}
196 
197 	public boolean canRedo()
198 	{
199 		return undoManager != null && undoManager.canRedo();
200 	}
201 
202 	public boolean canUndo()
203 	{
204 		return undoManager != null && undoManager.canUndo();
205 	}
206 }