001: package org.acm.seguin.pmd.swingui;
002:
003: import org.acm.seguin.pmd.swingui.event.ListenerList;
004: import org.acm.seguin.pmd.swingui.event.RulesEditingEvent;
005: import org.acm.seguin.pmd.swingui.event.RulesEditingEventListener;
006:
007: import javax.swing.JComboBox;
008: import javax.swing.JLabel;
009: import javax.swing.JPanel;
010: import javax.swing.JTextField;
011: import javax.swing.UIManager;
012: import javax.swing.border.EmptyBorder;
013: import javax.swing.border.TitledBorder;
014: import java.awt.BorderLayout;
015: import java.awt.Color;
016: import java.awt.Component;
017: import java.awt.GridBagConstraints;
018: import java.awt.GridBagLayout;
019: import java.awt.Insets;
020: import java.awt.Window;
021: import java.awt.event.FocusEvent;
022: import java.awt.event.FocusListener;
023: import java.text.MessageFormat;
024:
025: /**
026: *
027: * @author Donald A. Leckie
028: * @since August 29, 2002
029: * @version $Revision: 1.1 $, $Date: 2003/07/29 20:51:59 $
030: */
031: class RulePropertyEditingPanel extends JPanel implements Constants {
032:
033: private JLabel m_nameLabel;
034: private JTextField m_name;
035: private JLabel m_valueLabel;
036: private JTextField m_value;
037: private JLabel m_valueTypeLabel;
038: private JComboBox m_valueType;
039: private boolean m_enabled;
040: private RulesTreeNode m_currentDataNode;
041: private boolean m_isEditing;
042: private String m_originalName;
043: private String m_originalValue;
044: private FocusListener m_focusListener = new PropertyNameFocusListener();
045:
046: /**
047: *******************************************************************************
048: *
049: * @return
050: */
051: protected RulePropertyEditingPanel() {
052: super (new BorderLayout());
053:
054: EmptyBorder emptyBorder = new EmptyBorder(5, 5, 5, 5);
055:
056: setBorder(emptyBorder);
057:
058: JPanel panel;
059: TitledBorder titledBorder;
060: GridBagLayout layout;
061: GridBagConstraints constraints;
062:
063: int[] columnWidths = { 50, 100, 100 };
064: layout = new GridBagLayout();
065: layout.columnWidths = columnWidths;
066: panel = new JPanel(layout);
067: titledBorder = ComponentFactory
068: .createTitledBorder(" Property ");
069:
070: panel.setBorder(titledBorder);
071: add(panel, BorderLayout.CENTER);
072:
073: // Property Name Label
074: m_nameLabel = new JLabel("Name");
075: m_nameLabel.setFont(UIManager.getFont("labelFont"));
076: m_nameLabel.setHorizontalAlignment(JLabel.RIGHT);
077: constraints = layout.getConstraints(m_nameLabel);
078: constraints.gridx = 0;
079: constraints.gridy = 0;
080: constraints.gridwidth = 1;
081: constraints.gridheight = 1;
082: constraints.anchor = GridBagConstraints.NORTHEAST;
083: constraints.fill = GridBagConstraints.NONE;
084: constraints.insets = new Insets(4, 2, 4, 2);
085: panel.add(m_nameLabel, constraints);
086:
087: // Property Name Text
088: m_name = new JTextField();
089: m_name.setFont(UIManager.getFont("dataFont"));
090: m_name.addFocusListener(m_focusListener);
091: m_name.setRequestFocusEnabled(true);
092: constraints = layout.getConstraints(m_name);
093: constraints.gridx = 1;
094: constraints.gridy = 0;
095: constraints.gridwidth = GridBagConstraints.REMAINDER;
096: constraints.gridheight = 1;
097: constraints.anchor = GridBagConstraints.NORTHWEST;
098: constraints.fill = GridBagConstraints.BOTH;
099: constraints.insets = new Insets(4, 2, 4, 2);
100: panel.add(m_name, constraints);
101:
102: // Property Value Label
103: m_valueLabel = new JLabel("Value");
104: m_valueLabel.setFont(UIManager.getFont("labelFont"));
105: m_valueLabel.setHorizontalAlignment(JLabel.RIGHT);
106: constraints = layout.getConstraints(m_nameLabel);
107: constraints.gridx = 0;
108: constraints.gridy = 1;
109: constraints.gridwidth = 1;
110: constraints.gridheight = 1;
111: constraints.anchor = GridBagConstraints.NORTHEAST;
112: constraints.fill = GridBagConstraints.NONE;
113: constraints.insets = new Insets(4, 2, 4, 2);
114: panel.add(m_valueLabel, constraints);
115:
116: // Property Value Text
117: m_value = new JTextField();
118: m_value.setFont(UIManager.getFont("dataFont"));
119: m_value.setOpaque(true);
120: constraints = layout.getConstraints(m_name);
121: constraints.gridx = 1;
122: constraints.gridy = 1;
123: constraints.gridwidth = GridBagConstraints.REMAINDER;
124: constraints.gridheight = 1;
125: constraints.anchor = GridBagConstraints.NORTHWEST;
126: constraints.fill = GridBagConstraints.BOTH;
127: constraints.insets = new Insets(4, 2, 4, 2);
128: panel.add(m_value, constraints);
129:
130: // Property Value Type Label
131: m_valueTypeLabel = new JLabel("Type");
132: m_valueTypeLabel.setFont(UIManager.getFont("labelFont"));
133: m_valueTypeLabel.setHorizontalAlignment(JLabel.RIGHT);
134: constraints.gridx = 0;
135: constraints.gridy = 2;
136: constraints.gridwidth = 1;
137: constraints.gridheight = 1;
138: constraints.anchor = GridBagConstraints.NORTHEAST;
139: constraints.fill = GridBagConstraints.NONE;
140: constraints.insets = new Insets(4, 2, 4, 2);
141: panel.add(m_valueTypeLabel, constraints);
142:
143: // Property Value Type
144: String[] items = { STRING, BOOLEAN, DECIMAL_NUMBER, INTEGER };
145: m_valueType = new JComboBox(items);
146: m_valueType.setEditable(false);
147: m_valueType.setOpaque(true);
148: constraints = layout.getConstraints(m_name);
149: constraints.gridx = 1;
150: constraints.gridy = 2;
151: constraints.gridwidth = 1;
152: constraints.gridheight = 1;
153: constraints.anchor = GridBagConstraints.NORTHWEST;
154: constraints.fill = GridBagConstraints.BOTH;
155: constraints.insets = new Insets(4, 2, 4, 2);
156: panel.add(m_valueType, constraints);
157:
158: enableData(false);
159:
160: ListenerList.addListener(new RulesEditingEventHandler());
161: }
162:
163: /**
164: *******************************************************************************
165: *
166: * @param dataNode
167: */
168: private void saveData(RulesTreeNode dataNode) {
169: if ((dataNode != null) && m_isEditing) {
170: if (dataNode.isProperty()) {
171: // Test for valid property name.
172: String propertyName = m_name.getText();
173:
174: if (propertyName.equalsIgnoreCase(m_originalName) == false) {
175: if (dataNode.getSibling(propertyName) != null) {
176: String template = "Another property already has the name \"{0}\". The change will not be applied.";
177: String[] args = { propertyName };
178: String message = MessageFormat.format(template,
179: args);
180: boolean hasFocus = m_name.hasFocus();
181:
182: m_name.removeFocusListener(m_focusListener);
183: MessageDialog.show(getParentWindow(), message);
184: m_name.addFocusListener(m_focusListener);
185:
186: if (hasFocus) {
187: m_name.requestFocus();
188: }
189:
190: propertyName = m_originalName;
191: }
192: }
193:
194: // Test for valid value.
195: String valueText = m_value.getText();
196: String selectedItem = (String) m_valueType
197: .getSelectedItem();
198:
199: if (selectedItem.equalsIgnoreCase(BOOLEAN)) {
200: valueText = saveBoolean(valueText);
201: } else if (selectedItem
202: .equalsIgnoreCase(DECIMAL_NUMBER)) {
203: valueText = saveDecimalNumber(valueText);
204: } else if (selectedItem.equalsIgnoreCase(INTEGER)) {
205: valueText = saveInteger(valueText);
206: }
207:
208: dataNode.setName(propertyName);
209: dataNode.setPropertyValue(valueText);
210: dataNode.setPropertyValueType(selectedItem);
211: }
212: }
213: }
214:
215: /**
216: *******************************************************************************
217: *
218: * @param valueText
219: */
220: private String saveBoolean(String valueText) {
221: boolean originalValue;
222: boolean newValue;
223:
224: try {
225: originalValue = Boolean.getBoolean(m_originalValue);
226: } catch (NumberFormatException exception) {
227: originalValue = true;
228: }
229:
230: try {
231: newValue = Boolean.getBoolean(valueText);
232: valueText = String.valueOf(newValue);
233: } catch (NumberFormatException exception) {
234: String template = "New property of \"{0}\" is not a boolean. The change will not be applied.";
235: String[] args = { valueText };
236: String message = MessageFormat.format(template, args);
237:
238: m_name.removeFocusListener(m_focusListener);
239: MessageDialog.show(getParentWindow(), message);
240: m_name.addFocusListener(m_focusListener);
241:
242: newValue = originalValue;
243: valueText = m_originalValue;
244: }
245:
246: return valueText;
247: }
248:
249: /**
250: *******************************************************************************
251: *
252: * @param valueText
253: */
254: private String saveDecimalNumber(String valueText) {
255: double originalValue;
256: double newValue;
257:
258: try {
259: originalValue = Double.parseDouble(m_originalValue);
260: } catch (NumberFormatException exception) {
261: originalValue = 0.0;
262: }
263:
264: try {
265: newValue = Double.parseDouble(valueText);
266: valueText = String.valueOf(newValue);
267: } catch (NumberFormatException exception) {
268: String template = "New property of \"{0}\" is not a decimal number. The change will not be applied.";
269: String[] args = { valueText };
270: String message = MessageFormat.format(template, args);
271:
272: m_name.removeFocusListener(m_focusListener);
273: MessageDialog.show(getParentWindow(), message);
274: m_name.addFocusListener(m_focusListener);
275:
276: newValue = originalValue;
277: valueText = m_originalValue;
278: }
279:
280: return valueText;
281: }
282:
283: /**
284: *******************************************************************************
285: *
286: * @param valueText
287: */
288: private String saveInteger(String valueText) {
289: int originalValue;
290: int newValue;
291:
292: try {
293: originalValue = Integer.parseInt(m_originalValue);
294: } catch (NumberFormatException exception) {
295: originalValue = 0;
296: }
297:
298: try {
299: newValue = Integer.parseInt(valueText);
300: valueText = String.valueOf(newValue);
301: } catch (NumberFormatException exception) {
302: String template = "New property of \"{0}\" is not an integer. The change will not be applied.";
303: String[] args = { valueText };
304: String message = MessageFormat.format(template, args);
305:
306: m_name.removeFocusListener(m_focusListener);
307: MessageDialog.show(getParentWindow(), message);
308: m_name.addFocusListener(m_focusListener);
309:
310: newValue = originalValue;
311: valueText = m_originalValue;
312: }
313:
314: return valueText;
315: }
316:
317: /**
318: *******************************************************************************
319: *
320: * @param isEditing
321: */
322: protected void setIsEditing(boolean isEditing) {
323: m_isEditing = isEditing;
324: }
325:
326: /**
327: *******************************************************************************
328: *
329: * @param dataNode
330: */
331: private void loadData(RulesTreeNode dataNode) {
332: if (dataNode == null) {
333: enableData(false);
334: } else if (dataNode.isRuleSet()) {
335: enableData(false);
336: } else if (dataNode.isRule()) {
337: enableData(false);
338: } else if (dataNode.isProperty()) {
339: loadData_(dataNode);
340: } else {
341: enableData(false);
342: }
343: }
344:
345: /**
346: *******************************************************************************
347: *
348: * @param data
349: */
350: private void loadData_(RulesTreeNode dataNode) {
351: if (m_enabled == false) {
352: enableData(true);
353: }
354:
355: String name = dataNode.getName();
356: String valueType = dataNode.getPropertyValueType();
357:
358: m_name.setText(name);
359: m_value.setText(dataNode.getPropertyValue());
360: m_valueType.setSelectedItem(valueType);
361:
362: m_originalName = name;
363: m_originalValue = valueType;
364: m_currentDataNode = dataNode;
365: }
366:
367: /**
368: *******************************************************************************
369: *
370: */
371: private void enableData(boolean enable) {
372: if (enable) {
373: // Just to be sure the focus listener isn't set.
374: m_name.removeFocusListener(m_focusListener);
375: m_name.addFocusListener(m_focusListener);
376:
377: m_nameLabel.setEnabled(true);
378:
379: m_name.setEnabled(true);
380: m_name.setBackground(Color.white);
381:
382: m_valueLabel.setEnabled(true);
383:
384: m_value.setEnabled(true);
385: m_value.setBackground(Color.white);
386:
387: m_valueTypeLabel.setEnabled(true);
388:
389: m_valueType.setEnabled(true);
390: m_valueType.setBackground(Color.white);
391: } else {
392: m_name.removeFocusListener(m_focusListener);
393:
394: Color background = UIManager
395: .getColor("disabledTextBackground");
396:
397: m_nameLabel.setEnabled(false);
398:
399: m_name.setText("");
400: m_name.setEnabled(false);
401: m_name.setBackground(background);
402:
403: m_valueLabel.setEnabled(false);
404:
405: m_value.setText("");
406: m_value.setEnabled(false);
407: m_value.setBackground(background);
408:
409: m_valueTypeLabel.setEnabled(false);
410:
411: m_valueType.setSelectedIndex(0);
412: m_valueType.setEnabled(false);
413: m_valueType.setBackground(background);
414:
415: m_currentDataNode = null;
416: }
417:
418: m_enabled = enable;
419: }
420:
421: /**
422: *******************************************************************************
423: *
424: * @return
425: */
426: private Window getParentWindow() {
427: Component component = getParent();
428:
429: while ((component != null)
430: && ((component instanceof Window) == false)) {
431: component = component.getParent();
432: }
433:
434: return (Window) component;
435: }
436:
437: /**
438: ************************************************************************************
439: ************************************************************************************
440: ************************************************************************************
441: */
442: private class PropertyNameFocusListener implements FocusListener {
443:
444: /**
445: **************************************************************************
446: *
447: * @param event
448: */
449: public void focusGained(FocusEvent event) {
450: }
451:
452: /**
453: **************************************************************************
454: *
455: * @param event
456: */
457: public void focusLost(FocusEvent event) {
458: String propertyName = m_name.getText().trim();
459:
460: if (propertyName.length() == 0) {
461: String message = "The property name is missing.";
462: m_name.removeFocusListener(this );
463: MessageDialog.show(getParentWindow(), message);
464: m_name.addFocusListener(this );
465: m_name.requestFocus();
466: } else if (propertyName.equalsIgnoreCase(m_originalName) == false) {
467: if (m_currentDataNode.getSibling(propertyName) != null) {
468: String template = "Another property already has the name \"{0}\".";
469: String[] args = { propertyName };
470: String message = MessageFormat.format(template,
471: args);
472: m_name.removeFocusListener(this );
473: MessageDialog.show(getParentWindow(), message);
474: m_name.addFocusListener(this );
475: m_name.requestFocus();
476: }
477: }
478: }
479: }
480:
481: /**
482: ************************************************************************************
483: ************************************************************************************
484: ************************************************************************************
485: */
486: private class RulesEditingEventHandler implements
487: RulesEditingEventListener {
488:
489: /**
490: *************************************************************************
491: *
492: * @param event
493: */
494: public void loadData(RulesEditingEvent event) {
495: RulePropertyEditingPanel.this .loadData(event.getDataNode());
496: }
497:
498: /**
499: *************************************************************************
500: *
501: * @param event
502: */
503: public void saveData(RulesEditingEvent event) {
504: RulePropertyEditingPanel.this.saveData(event.getDataNode());
505: }
506: }
507: }
|