KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > viewers > DialogCellEditor


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jface.viewers;
12
13 import java.text.MessageFormat JavaDoc; // Not using ICU to support standalone JFace scenario
14

15 import org.eclipse.jface.resource.ImageDescriptor;
16 import org.eclipse.jface.resource.ImageRegistry;
17 import org.eclipse.jface.resource.JFaceResources;
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.events.FocusEvent;
20 import org.eclipse.swt.events.FocusListener;
21 import org.eclipse.swt.events.KeyAdapter;
22 import org.eclipse.swt.events.KeyEvent;
23 import org.eclipse.swt.events.SelectionAdapter;
24 import org.eclipse.swt.events.SelectionEvent;
25 import org.eclipse.swt.graphics.Color;
26 import org.eclipse.swt.graphics.Font;
27 import org.eclipse.swt.graphics.Point;
28 import org.eclipse.swt.graphics.Rectangle;
29 import org.eclipse.swt.widgets.Button;
30 import org.eclipse.swt.widgets.Composite;
31 import org.eclipse.swt.widgets.Control;
32 import org.eclipse.swt.widgets.Label;
33 import org.eclipse.swt.widgets.Layout;
34
35 /**
36  * An abstract cell editor that uses a dialog.
37  * Dialog cell editors usually have a label control on the left and a button on
38  * the right. Pressing the button opens a dialog window (for example, a color dialog
39  * or a file dialog) to change the cell editor's value.
40  * The cell editor's value is the value of the dialog.
41  * <p>
42  * Subclasses may override the following methods:
43  * <ul>
44  * <li><code>createButton</code>: creates the cell editor's button control</li>
45  * <li><code>createContents</code>: creates the cell editor's 'display value' control</li>
46  * <li><code>updateContents</code>: updates the cell editor's 'display value' control
47  * after its value has changed</li>
48  * <li><code>openDialogBox</code>: opens the dialog box when the end user presses
49  * the button</li>
50  * </ul>
51  * </p>
52  */

53 public abstract class DialogCellEditor extends CellEditor {
54
55     /**
56      * Image registry key for three dot image (value <code>"cell_editor_dots_button_image"</code>).
57      */

58     public static final String JavaDoc CELL_EDITOR_IMG_DOTS_BUTTON = "cell_editor_dots_button_image";//$NON-NLS-1$
59

60     /**
61      * The editor control.
62      */

63     private Composite editor;
64
65     /**
66      * The current contents.
67      */

68     private Control contents;
69
70     /**
71      * The label that gets reused by <code>updateLabel</code>.
72      */

73     private Label defaultLabel;
74
75     /**
76      * The button.
77      */

78     private Button button;
79
80     /**
81      * Listens for 'focusLost' events and fires the 'apply' event as long
82      * as the focus wasn't lost because the dialog was opened.
83      */

84     private FocusListener buttonFocusListener;
85
86     /**
87      * The value of this cell editor; initially <code>null</code>.
88      */

89     private Object JavaDoc value = null;
90
91     static {
92         ImageRegistry reg = JFaceResources.getImageRegistry();
93         reg.put(CELL_EDITOR_IMG_DOTS_BUTTON, ImageDescriptor.createFromFile(
94                 DialogCellEditor.class, "images/dots_button.gif"));//$NON-NLS-1$
95
}
96
97     /**
98      * Internal class for laying out the dialog.
99      */

100     private class DialogCellLayout extends Layout {
101         public void layout(Composite editor, boolean force) {
102             Rectangle bounds = editor.getClientArea();
103             Point size = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, force);
104             if (contents != null) {
105                 contents.setBounds(0, 0, bounds.width - size.x, bounds.height);
106             }
107             button.setBounds(bounds.width - size.x, 0, size.x, bounds.height);
108         }
109
110         public Point computeSize(Composite editor, int wHint, int hHint,
111                 boolean force) {
112             if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) {
113                 return new Point(wHint, hHint);
114             }
115             Point contentsSize = contents.computeSize(SWT.DEFAULT, SWT.DEFAULT,
116                     force);
117             Point buttonSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT,
118                     force);
119             // Just return the button width to ensure the button is not clipped
120
// if the label is long.
121
// The label will just use whatever extra width there is
122
Point result = new Point(buttonSize.x, Math.max(contentsSize.y,
123                     buttonSize.y));
124             return result;
125         }
126     }
127
128     /**
129      * Default DialogCellEditor style
130      */

131     private static final int defaultStyle = SWT.NONE;
132
133     /**
134      * Creates a new dialog cell editor with no control
135      * @since 2.1
136      */

137     public DialogCellEditor() {
138         setStyle(defaultStyle);
139     }
140
141     /**
142      * Creates a new dialog cell editor parented under the given control.
143      * The cell editor value is <code>null</code> initially, and has no
144      * validator.
145      *
146      * @param parent the parent control
147      */

148     protected DialogCellEditor(Composite parent) {
149         this(parent, defaultStyle);
150     }
151
152     /**
153      * Creates a new dialog cell editor parented under the given control.
154      * The cell editor value is <code>null</code> initially, and has no
155      * validator.
156      *
157      * @param parent the parent control
158      * @param style the style bits
159      * @since 2.1
160      */

161     protected DialogCellEditor(Composite parent, int style) {
162         super(parent, style);
163     }
164
165     /**
166      * Creates the button for this cell editor under the given parent control.
167      * <p>
168      * The default implementation of this framework method creates the button
169      * display on the right hand side of the dialog cell editor. Subclasses
170      * may extend or reimplement.
171      * </p>
172      *
173      * @param parent the parent control
174      * @return the new button control
175      */

176     protected Button createButton(Composite parent) {
177         Button result = new Button(parent, SWT.DOWN);
178         result.setText("..."); //$NON-NLS-1$
179
return result;
180     }
181
182     /**
183      * Creates the controls used to show the value of this cell editor.
184      * <p>
185      * The default implementation of this framework method creates
186      * a label widget, using the same font and background color as the parent control.
187      * </p>
188      * <p>
189      * Subclasses may reimplement. If you reimplement this method, you
190      * should also reimplement <code>updateContents</code>.
191      * </p>
192      *
193      * @param cell the control for this cell editor
194      * @return the underlying control
195      */

196     protected Control createContents(Composite cell) {
197         defaultLabel = new Label(cell, SWT.LEFT);
198         defaultLabel.setFont(cell.getFont());
199         defaultLabel.setBackground(cell.getBackground());
200         return defaultLabel;
201     }
202
203     /* (non-Javadoc)
204      * Method declared on CellEditor.
205      */

206     protected Control createControl(Composite parent) {
207
208         Font font = parent.getFont();
209         Color bg = parent.getBackground();
210
211         editor = new Composite(parent, getStyle());
212         editor.setFont(font);
213         editor.setBackground(bg);
214         editor.setLayout(new DialogCellLayout());
215
216         contents = createContents(editor);
217         updateContents(value);
218
219         button = createButton(editor);
220         button.setFont(font);
221
222         button.addKeyListener(new KeyAdapter() {
223             /* (non-Javadoc)
224              * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
225              */

226             public void keyReleased(KeyEvent e) {
227                 if (e.character == '\u001b') { // Escape
228
fireCancelEditor();
229                 }
230             }
231         });
232         
233         button.addFocusListener(getButtonFocusListener());
234         
235         button.addSelectionListener(new SelectionAdapter() {
236             /* (non-Javadoc)
237              * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
238              */

239             public void widgetSelected(SelectionEvent event) {
240                 // Remove the button's focus listener since it's guaranteed
241
// to lose focus when the dialog opens
242
button.removeFocusListener(getButtonFocusListener());
243                 
244                 Object JavaDoc newValue = openDialogBox(editor);
245                 
246                 // Re-add the listener once the dialog closes
247
button.addFocusListener(getButtonFocusListener());
248
249                 if (newValue != null) {
250                     boolean newValidState = isCorrect(newValue);
251                     if (newValidState) {
252                         markDirty();
253                         doSetValue(newValue);
254                     } else {
255                         // try to insert the current value into the error message.
256
setErrorMessage(MessageFormat.format(getErrorMessage(),
257                                 new Object JavaDoc[] { newValue.toString() }));
258                     }
259                     fireApplyEditorValue();
260                 }
261             }
262         });
263
264         setValueValid(true);
265
266         return editor;
267     }
268
269     /* (non-Javadoc)
270      *
271      * Override in order to remove the button's focus listener if the celleditor
272      * is deactivating.
273      *
274      * @see org.eclipse.jface.viewers.CellEditor#deactivate()
275      */

276     public void deactivate() {
277         if (button != null && !button.isDisposed()) {
278             button.removeFocusListener(getButtonFocusListener());
279         }
280         
281         super.deactivate();
282     }
283
284     /* (non-Javadoc)
285      * Method declared on CellEditor.
286      */

287     protected Object JavaDoc doGetValue() {
288         return value;
289     }
290
291     /* (non-Javadoc)
292      * Method declared on CellEditor.
293      * The focus is set to the cell editor's button.
294      */

295     protected void doSetFocus() {
296         button.setFocus();
297         
298         // add a FocusListener to the button
299
button.addFocusListener(getButtonFocusListener());
300     }
301
302     /**
303      * Return a listener for button focus.
304      * @return FocusListener
305      */

306     private FocusListener getButtonFocusListener() {
307         if (buttonFocusListener == null) {
308             buttonFocusListener = new FocusListener() {
309
310                 /* (non-Javadoc)
311                  * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
312                  */

313                 public void focusGained(FocusEvent e) {
314                     // Do nothing
315
}
316
317                 /* (non-Javadoc)
318                  * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
319                  */

320                 public void focusLost(FocusEvent e) {
321                     DialogCellEditor.this.focusLost();
322                 }
323             };
324         }
325         
326         return buttonFocusListener;
327     }
328
329     /* (non-Javadoc)
330      * Method declared on CellEditor.
331      */

332     protected void doSetValue(Object JavaDoc value) {
333         this.value = value;
334         updateContents(value);
335     }
336
337     /**
338      * Returns the default label widget created by <code>createContents</code>.
339      *
340      * @return the default label widget
341      */

342     protected Label getDefaultLabel() {
343         return defaultLabel;
344     }
345
346     /**
347      * Opens a dialog box under the given parent control and returns the
348      * dialog's value when it closes, or <code>null</code> if the dialog
349      * was canceled or no selection was made in the dialog.
350      * <p>
351      * This framework method must be implemented by concrete subclasses.
352      * It is called when the user has pressed the button and the dialog
353      * box must pop up.
354      * </p>
355      *
356      * @param cellEditorWindow the parent control cell editor's window
357      * so that a subclass can adjust the dialog box accordingly
358      * @return the selected value, or <code>null</code> if the dialog was
359      * canceled or no selection was made in the dialog
360      */

361     protected abstract Object JavaDoc openDialogBox(Control cellEditorWindow);
362
363     /**
364      * Updates the controls showing the value of this cell editor.
365      * <p>
366      * The default implementation of this framework method just converts
367      * the passed object to a string using <code>toString</code> and
368      * sets this as the text of the label widget.
369      * </p>
370      * <p>
371      * Subclasses may reimplement. If you reimplement this method, you
372      * should also reimplement <code>createContents</code>.
373      * </p>
374      *
375      * @param value the new value of this cell editor
376      */

377     protected void updateContents(Object JavaDoc value) {
378         if (defaultLabel == null) {
379             return;
380         }
381
382         String JavaDoc text = "";//$NON-NLS-1$
383
if (value != null) {
384             text = value.toString();
385         }
386         defaultLabel.setText(text);
387     }
388 }
389
Popular Tags