001: package org.swingml.component;
002:
003: import java.awt.*;
004: import java.awt.datatransfer.*;
005: import java.awt.event.*;
006: import java.text.*;
007: import java.util.List;
008:
009: import javax.swing.*;
010: import javax.swing.event.*;
011: import javax.swing.text.*;
012:
013: import org.swingml.*;
014: import org.swingml.event.*;
015: import org.swingml.model.*;
016: import org.swingml.system.*;
017:
018: /**
019: * @author ybxdde
020: *
021: */
022: public class JFormattedTextFieldComponent extends JFormattedTextField
023: implements XMLTranslatable, DocumentListener, FocusListener,
024: MouseListener, KeyListener, ISwingMLTextContainer {
025:
026: private class ContextMenu extends JPopupMenu implements
027: ActionListener {
028:
029: private JFormattedTextFieldComponent m_textField = null;
030: private final String MENU_COPY = "Copy";
031: private final String MENU_CUT = "Cut";
032: private final String MENU_DELETE = "Delete";
033: private final String MENU_PASTE = "Paste";
034: private final String MENU_SELECT_ALL = "Select All";
035: private final String MENU_SEPARATOR = "-";
036:
037: public ContextMenu(JFormattedTextFieldComponent textField) {
038: this .m_textField = textField;
039:
040: String items[] = { MENU_CUT, MENU_COPY, MENU_PASTE,
041: MENU_DELETE, MENU_SEPARATOR, MENU_SELECT_ALL };
042:
043: for (int i = 0; i < items.length; i++) {
044: if (items[i].equalsIgnoreCase(MENU_SEPARATOR)) {
045: javax.swing.JSeparator separator = new JSeparator();
046: this .add(separator);
047: } else {
048: JMenuItem menuItem = new JMenuItem(items[i]);
049: menuItem.addActionListener(this );
050:
051: boolean isEnabled = ((items[i]
052: .equalsIgnoreCase(MENU_CUT)
053: || items[i].equalsIgnoreCase(MENU_COPY) || items[i]
054: .equalsIgnoreCase(MENU_DELETE))
055: && (this .m_textField.getSelectedText() == null || this .m_textField
056: .getSelectedText().length() == 0) ? false
057: : true);
058:
059: // This entire block is used just to determine whether or
060: // not the
061: // data in the clipboard is available for pasting into a
062: // text field.
063: if (items[i].equalsIgnoreCase(MENU_PASTE)) {
064: try {
065: Clipboard clipBoard = this .m_textField
066: .getToolkit().getSystemClipboard();
067:
068: if (clipBoard != null) {
069: Transferable clipObject = clipBoard
070: .getContents(null);
071: Object realData = clipObject
072: .getTransferData(DataFlavor.stringFlavor);
073: isEnabled = (realData != null);
074: }
075: } catch (UnsupportedFlavorException e) {
076: isEnabled = false;
077: } catch (Exception e) {
078: // Swallow the exception.
079: }
080: }
081: // Finally set the enabled status of the menu item.
082: menuItem.setEnabled(isEnabled);
083: this .add(menuItem);
084: }
085: }
086: }
087:
088: public void actionPerformed(ActionEvent event) {
089: if (event.getActionCommand().equalsIgnoreCase(MENU_CUT)) {
090: this .m_textField.cut();
091: } else if (event.getActionCommand().equalsIgnoreCase(
092: MENU_COPY)) {
093: this .m_textField.copy();
094: } else if (event.getActionCommand().equalsIgnoreCase(
095: MENU_PASTE)) {
096: this .m_textField.paste();
097:
098: } else if (event.getActionCommand().equalsIgnoreCase(
099: MENU_DELETE)) {
100: if (this .m_textField.getSelectedText() != null
101: && this .m_textField.getSelectedText().length() > 0) {
102: StringBuffer text = new StringBuffer(
103: this .m_textField.getText());
104:
105: text.replace(this .m_textField.getSelectionStart(),
106: this .m_textField.getSelectionEnd(), "");
107: this .m_textField.setText(text.toString());
108: }
109: } else if (event.getActionCommand().equalsIgnoreCase(
110: MENU_SELECT_ALL)) {
111: this .m_textField.requestFocus();
112: this .m_textField.selectAll();
113: }
114: }
115: }
116:
117: private Color editableColor = new Color(UIManager.getColor(
118: "TextField.background").getRGB());
119:
120: private EventHandler eventHandler = EventHandler.getInstance();
121:
122: private JFormattedTextFieldModel model = null;
123:
124: private Color readonlyColor = new Color(UIManager.getColor(
125: "TextField.inactiveBackground").getRGB());
126:
127: public JFormattedTextFieldComponent(JFormattedTextFieldModel aModel) {
128: super (aModel.getFormatter());
129: this .model = aModel;
130: setName(aModel.getName());
131: if (aModel.getFormatter() instanceof NumberFormatter) {
132: try {
133: setValue(getFormatter().stringToValue(aModel.getText()));
134: } catch (ParseException e) {
135: e.printStackTrace();
136: }
137: } else {
138: setValue(aModel.getText());
139: }
140:
141: setColumns(Integer.parseInt(aModel.getCols()));
142: setEditable(model.isEditable());
143: getDocument().addDocumentListener(this );
144: addFocusListener(this );
145: setToolTipText(aModel.getTooltip());
146: addMouseListener(this );
147: if (aModel.getForeground() != null) {
148: setForeground(aModel.getForeground());
149: }
150: if (aModel.getBackground() != null) {
151: setBackground(aModel.getBackground());
152: }
153:
154: setEnabled(aModel.isEnabled());
155:
156: if (aModel.getFormatter() != null) {
157: super .setFormatter(aModel.getFormatter());
158: if (aModel.getFormatter() instanceof MaskFormatter) {
159: try {
160: MaskFormatter maskFormatter = (MaskFormatter) aModel
161: .getFormatter();
162: maskFormatter.setMask(aModel.getPattern());
163: if (aModel.getPlaceholder() != null) {
164: maskFormatter.setPlaceholder(aModel
165: .getPlaceholder());
166: }
167: if (aModel.getPlaceholdChar() != ' ') {
168: maskFormatter.setPlaceholderCharacter(aModel
169: .getPlaceholdChar());
170: }
171: if (aModel.isOverwrite()) {
172: maskFormatter.setOverwriteMode(aModel
173: .isOverwrite());
174: }
175:
176: maskFormatter.install(this );
177: } catch (ParseException e) {
178: SwingMLLogger.getInstance().log(e);
179: }
180: } else if (aModel.getFormatter() instanceof NumberFormatter) {
181: NumberFormatter numberFormatter = (NumberFormatter) aModel
182: .getFormatter();
183: numberFormatter.setFormat(new DecimalFormat(aModel
184: .getPattern()));
185: if (aModel.isOverwrite()) {
186: numberFormatter.setOverwriteMode(aModel
187: .isOverwrite());
188: }
189: numberFormatter.install(this );
190: } else if (aModel.getFormatter() instanceof DateFormatter) {
191: DateFormatter dateFormatter = (DateFormatter) aModel
192: .getFormatter();
193: dateFormatter.setFormat(new SimpleDateFormat(aModel
194: .getPattern()));
195: if (aModel.isOverwrite()) {
196: dateFormatter
197: .setOverwriteMode(aModel.isOverwrite());
198: }
199: dateFormatter.install(this );
200: }
201: }
202:
203: if (null != aModel.getReturnButton()) {
204: addKeyListener(new ReturnKeyAdapter(aModel
205: .getReturnButton()));
206: }
207:
208: List listeners = aModel.getListeners();
209: for (int i = 0; i < listeners.size(); i++) {
210: ListenerModel listenerModel = (ListenerModel) listeners
211: .get(i);
212: if (listenerModel.getEvent().indexOf("KeyListener") != -1) {
213: addKeyListener(this );
214: break;
215: }
216: }
217: }
218:
219: public void changedUpdate(DocumentEvent aEvt) {
220: System.err.print(getName() + " changed update start....");
221: this .eventHandler.handleEvent(this .getModel(),
222: Constants.CHANGED_UPDATE, this );
223: System.err.println(getName() + " end.");
224: }
225:
226: public void focusGained(FocusEvent aEvt) {
227: this .eventHandler.handleEvent(this .getModel(),
228: Constants.FOCUS_GAINED, this );
229: if (!aEvt.isTemporary()
230: && aEvt.getID() == FocusEvent.FOCUS_GAINED) {
231: internalFocusGained();
232: }
233: }
234:
235: public void focusLost(FocusEvent aEvt) {
236: this .eventHandler.handleEvent(this .getModel(),
237: Constants.FOCUS_LOST, this );
238: }
239:
240: public JFormattedTextFieldModel getModel() {
241: return this .model;
242: }
243:
244: public String getXMLValue() {
245: return super .getText();
246: }
247:
248: public void insertUpdate(DocumentEvent aEvt) {
249: this .eventHandler.handleEvent(this .getModel(),
250: Constants.INSERT_UPDATE, this );
251: }
252:
253: private void internalFocusGained() {
254: if (getModel().shouldAutoSelectOnFocus()) {
255: selectAll();
256: }
257: }
258:
259: /**
260: * Don't allow focus if the field is not editable
261: */
262: public boolean isFocusable() {
263: return isEditable();
264: }
265:
266: public void keyPressed(KeyEvent e) {
267: }
268:
269: public void keyReleased(KeyEvent e) {
270: this .eventHandler.handleEvent(this .getModel(),
271: Constants.KEY_RELEASED, this );
272: }
273:
274: public void keyTyped(KeyEvent e) {
275: }
276:
277: public void mouseClicked(MouseEvent aEvt) {
278: possiblePopup(aEvt);
279: if (!hasFocus()) {
280: internalFocusGained();
281: }
282: }
283:
284: public void mouseEntered(MouseEvent aEvt) {
285: }
286:
287: public void mouseExited(MouseEvent aEvt) {
288: }
289:
290: public void mousePressed(MouseEvent aEvt) {
291: possiblePopup(aEvt);
292: }
293:
294: public void mouseReleased(MouseEvent aEvt) {
295: possiblePopup(aEvt);
296: }
297:
298: public void possiblePopup(MouseEvent aEvt) {
299: if (aEvt.isPopupTrigger()) {
300: ContextMenu thePopup = new ContextMenu(this );
301: thePopup
302: .show(aEvt.getComponent(), aEvt.getX(), aEvt.getY());
303: }
304: }
305:
306: protected void processFocusEvent(FocusEvent e) {
307: super .processFocusEvent(e);
308:
309: // ignore temporary focus event and process only focus gained events
310: if (!e.isTemporary() && e.getID() == FocusEvent.FOCUS_GAINED) {
311: internalFocusGained();
312: }
313: }
314:
315: public void removeUpdate(DocumentEvent aEvt) {
316: this .eventHandler.handleEvent(this .getModel(),
317: Constants.REMOVE_UPDATE, this );
318: }
319:
320: /**
321: * This is a fix for: http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=1eb5c9e2832612ff3f128da0418f:YfiG?bug_id=4883120
322: */
323: public void setEditable(boolean isEditable) {
324: super .setEditable(isEditable);
325: setBackground(isEditable ? editableColor : readonlyColor);
326: }
327:
328: /**
329: * This is a fix for: http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=1eb5c9e2832612ff3f128da0418f:YfiG?bug_id=4883120
330: */
331: public void setEnabled(boolean enabled) {
332: super .setEnabled(enabled);
333: setBackground(enabled ? editableColor : readonlyColor);
334: }
335:
336: public void setValue(Object value) {
337: super.setValue(value);
338: }
339: }
|