1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.xmlhammer.gui.history;
22
23 import java.awt.Font;
24 import java.awt.Toolkit;
25 import java.awt.event.FocusEvent;
26 import java.awt.event.FocusListener;
27 import java.awt.event.KeyEvent;
28 import java.awt.event.MouseEvent;
29 import java.awt.event.MouseListener;
30
31 import javax.swing.ImageIcon;
32 import javax.swing.InputVerifier;
33 import javax.swing.JComboBox;
34 import javax.swing.JPopupMenu;
35 import javax.swing.JTextField;
36 import javax.swing.KeyStroke;
37 import javax.swing.event.UndoableEditEvent;
38 import javax.swing.event.UndoableEditListener;
39
40 import org.bounce.MenuUtilities;
41 import org.bounce.RunnableAction;
42 import org.bounce.event.PopupListener;
43 import org.xmlhammer.gui.Page;
44 import org.xmlhammer.gui.util.UndoableComboBoxEdit;
45 import org.xmlhammer.gui.util.UndoableHistoryComboBoxItemListener;
46
47 public class HistoryComboBox extends JComboBox implements FocusListener, UndoableEditListener {
48
49 private static final long serialVersionUID = -2939294390728897917L;
50 private CopyAction copyAction = null;
51 private CutAction cutAction = null;
52 private PasteAction pasteAction = null;
53 private SelectAllAction selectAllAction = null;
54 private JPopupMenu popup = null;
55
56 private String emptyValue = "";
57 private Page page = null;
58
59 public HistoryComboBox(HistoryComboBoxModel model) {
60 this(null, model, null);
61 }
62
63 public HistoryComboBox(Page page, HistoryComboBoxModel model) {
64 this(page, model, null);
65 }
66
67 public HistoryComboBox(Page page, HistoryComboBoxModel model, InputVerifier verifier) {
68 super(model);
69
70 this.page = page;
71
72 setEditable(true);
73 setEditor(new HistoryComboBoxEditor(getEditor()));
74
75 ((JTextField)getEditor().getEditorComponent()).addFocusListener(this);
76 ((JTextField)getEditor().getEditorComponent()).getDocument().addUndoableEditListener(this);
77 ((JTextField)getEditor().getEditorComponent()).addMouseListener(new PopupListener() {
78 public void popupTriggered(MouseEvent event) {
79 showPopup(event);
80 }
81 });
82 ((JTextField)getEditor().getEditorComponent()).addMouseListener(new MouseListener() {
83 public void mousePressed(MouseEvent e) {
84 getPopup().setVisible(false);
85 }
86
87 public void mouseClicked(MouseEvent e) {}
88 public void mouseReleased(MouseEvent e) {}
89 public void mouseEntered(MouseEvent e) {}
90 public void mouseExited(MouseEvent arg0) {}
91 });
92
93 if (verifier != null) {
94 ((JTextField)getEditor().getEditorComponent()).setInputVerifier(verifier);
95 } else {
96 ((JTextField)getEditor().getEditorComponent()).setInputVerifier(new HistoryInputVerifier(this));
97 }
98
99 setFont(getFont().deriveFont( Font.PLAIN));
100
101 addItemListener(new UndoableHistoryComboBoxItemListener(page, this));
102 }
103
104 public void dispose() {
105 ((HistoryComboBoxModel)getModel()).removeListener();
106 }
107
108 public void setValue(String value) {
109 String previous = getEditor().getItem().toString();
110
111 if ( value != null && value.length() > 0) {
112 setSelectedItem( value);
113
114 if ( !value.equals(previous)) {
115 getEditor().setItem( value);
116 }
117 } else {
118 setSelectedItem(null);
119
120 if (page != null) {
121 page.getProjectView().getUndoManager().addEdit(new UndoableComboBoxEdit(page, this, null, previous));
122 }
123
124 getEditor().setItem(emptyValue);
125 }
126 }
127
128 public void showPopup(MouseEvent event) {
129 String selection = ((JTextField)getEditor().getEditorComponent()).getSelectedText();
130
131 if (selection != null && selection.length() > 0) {
132 getCutAction().setEnabled(true);
133 getCopyAction().setEnabled(true);
134 } else {
135 getCutAction().setEnabled(false);
136 getCopyAction().setEnabled(false);
137 }
138
139 getPopup().show(getEditor().getEditorComponent(), event.getX(), event.getY());
140 }
141
142 private JPopupMenu getPopup() {
143 if (popup == null) {
144 popup = new JPopupMenu();
145
146 if (page != null) {
147 popup.add(page.getProjectView().getProjectsView().getRoot().getUndoAction());
148 popup.add(page.getProjectView().getProjectsView().getRoot().getRedoAction());
149 popup.addSeparator();
150 }
151
152 popup.add(getCutAction());
153 popup.add(getCopyAction());
154 popup.add(getPasteAction());
155 popup.add(getSelectAllAction());
156
157 MenuUtilities.alignMenu(popup);
158 }
159
160 return popup;
161 }
162
163 public Page getPage() {
164 return page;
165 }
166
167 public String getValue() {
168 if (!isEmpty()) {
169 return getEditor().getItem().toString();
170 }
171
172 return "";
173 }
174
175 public void setEmptyValue(String text) {
176 this.emptyValue = text;
177 }
178
179 public String getEmptyValue() {
180 return emptyValue;
181 }
182
183 public boolean isEmpty() {
184 return emptyValue.equals( getEditor().getItem().toString()) || getEditor().getItem().toString().trim().length() == 0;
185 }
186
187 public void focusGained(FocusEvent event) {
188 if (getEditor().getItem().equals(emptyValue)) {
189 getEditor().setItem("");
190 }
191 }
192
193 public void focusLost(FocusEvent event) {
194 String value = getEditor().getItem().toString();
195
196 if ( value == null || value.length() == 0) {
197 getEditor().setItem(emptyValue);
198 }
199
200 if (page != null) {
201 page.getProjectView().getUndoManager().discardDiscardableEdits();
202 }
203 }
204
205 public void undoableEditHappened(UndoableEditEvent event) {
206 if (page != null) {
207 if (((JTextField)getEditor().getEditorComponent()).hasFocus()) {
208 page.getProjectView().getUndoManager().addDiscardableEdit(event.getEdit());
209 }
210 }
211 }
212
213 private CopyAction getCopyAction() {
214 if (copyAction == null) {
215 copyAction = new CopyAction((JTextField)getEditor().getEditorComponent());
216 }
217
218 return copyAction;
219 }
220
221 private CutAction getCutAction() {
222 if (cutAction == null) {
223 cutAction = new CutAction((JTextField)getEditor().getEditorComponent());
224 }
225
226 return cutAction;
227 }
228
229 private PasteAction getPasteAction() {
230 if (pasteAction == null) {
231 pasteAction = new PasteAction((JTextField)getEditor().getEditorComponent());
232 }
233
234 return pasteAction;
235 }
236
237 private SelectAllAction getSelectAllAction() {
238 if (selectAllAction == null) {
239 selectAllAction = new SelectAllAction((JTextField)getEditor().getEditorComponent());
240 }
241
242 return selectAllAction;
243 }
244
245 public class CutAction extends RunnableAction {
246 private static final long serialVersionUID = 939638802470121637L;
247 private JTextField text = null;
248
249 public CutAction(JTextField text) {
250 super( "Cut");
251
252 this.text = text;
253
254 putValue( MNEMONIC_KEY, new Integer( 't'));
255 putValue( ACCELERATOR_KEY, KeyStroke.getKeyStroke( KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
256 putValue( SMALL_ICON, new ImageIcon( getClass().getResource( "/org/xmlhammer/gui/icons/etool16/cut_edit.gif")));
257 putValue( SHORT_DESCRIPTION, "Cut");
258 }
259
260 public void run() {
261 text.cut();
262 }
263 }
264
265 public class CopyAction extends RunnableAction {
266 private static final long serialVersionUID = 939638802470121637L;
267 private JTextField text = null;
268
269 public CopyAction(JTextField text) {
270 super( "Copy");
271
272 this.text = text;
273
274 putValue(MNEMONIC_KEY, new Integer('C'));
275 putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
276 putValue(SHORT_DESCRIPTION, "Copy");
277 putValue(SMALL_ICON, new ImageIcon(getClass().getResource("/org/xmlhammer/gui/icons/etool16/copy_edit.gif")));
278 }
279
280 public void run() {
281 text.copy();
282 }
283 }
284
285 public class PasteAction extends RunnableAction {
286 private static final long serialVersionUID = 939638802470121637L;
287 private JTextField text = null;
288
289 public PasteAction(JTextField text) {
290 super("Paste");
291
292 this.text = text;
293
294 putValue( MNEMONIC_KEY, new Integer( 'P'));
295 putValue( ACCELERATOR_KEY, KeyStroke.getKeyStroke( KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
296 putValue( SMALL_ICON, new ImageIcon( getClass().getResource( "/org/xmlhammer/gui/icons/etool16/paste_edit.gif")));
297 putValue( SHORT_DESCRIPTION, "Paste");
298 }
299
300 public void run() {
301 text.paste();
302 }
303 }
304
305 public class SelectAllAction extends RunnableAction {
306 private static final long serialVersionUID = 939638802470121637L;
307 private JTextField text = null;
308
309 public SelectAllAction(JTextField text) {
310 super("Select All");
311
312 this.text = text;
313
314 putValue( MNEMONIC_KEY, new Integer( 'A'));
315 putValue( ACCELERATOR_KEY, KeyStroke.getKeyStroke( KeyEvent.VK_A, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
316
317 }
318
319 public void run() {
320 text.selectAll();
321 }
322 }
323 }