001: /*
002: * Copyright 2001-2006 C:1 Financial Services GmbH
003: *
004: * This software is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License Version 2.1, as published by the Free Software Foundation.
007: *
008: * This software is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
011: * Lesser General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public
014: * License along with this library; if not, write to the Free Software
015: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
016: */
017:
018: package de.finix.contelligent.client.gui.directory;
019:
020: import java.awt.Color;
021: import java.awt.Frame;
022: import java.awt.event.ActionEvent;
023: import java.awt.event.ActionListener;
024: import java.awt.event.FocusAdapter;
025: import java.awt.event.FocusEvent;
026: import java.awt.event.ItemEvent;
027: import java.awt.event.ItemListener;
028: import java.awt.event.KeyAdapter;
029: import java.awt.event.KeyEvent;
030: import java.awt.event.WindowAdapter;
031: import java.awt.event.WindowEvent;
032: import java.beans.PropertyChangeEvent;
033: import java.beans.PropertyChangeListener;
034: import java.util.Collections;
035: import java.util.Comparator;
036: import java.util.Iterator;
037: import java.util.Vector;
038: import java.util.logging.Level;
039: import java.util.logging.Logger;
040:
041: import javax.swing.JComboBox;
042: import javax.swing.JLabel;
043: import javax.swing.JList;
044: import javax.swing.JOptionPane;
045: import javax.swing.JTextField;
046: import javax.swing.ListCellRenderer;
047:
048: import de.finix.contelligent.client.base.ContelligentConstants;
049: import de.finix.contelligent.client.base.PackageManager;
050: import de.finix.contelligent.client.base.PackageNotFoundException;
051: import de.finix.contelligent.client.base.Type;
052: import de.finix.contelligent.client.base.TypeFactory;
053: import de.finix.contelligent.client.i18n.Resources;
054: import de.finix.contelligent.client.util.EscapeDialog;
055:
056: public class RenameTypeDialog extends EscapeDialog {
057:
058: private static Logger logger = Logger
059: .getLogger(RenameTypeDialog.class.getName());
060:
061: private String name = null;
062:
063: private String type = null;
064:
065: private JLabel nameLabel;
066:
067: private JTextField fullNameField;
068:
069: private JTextField nameField;
070:
071: private JComboBox typeBox;
072:
073: private JOptionPane optionPane;
074:
075: private String incrementalSearchString = "";
076:
077: private Vector typeList;
078:
079: private String packageIdentifier = "";
080:
081: public RenameTypeDialog(Frame frame, String preselectedTypeName) {
082: super (frame, true);
083:
084: addFocusListener(new FocusAdapter() {
085: public void focusGained(FocusEvent e) {
086: toFront();
087: }
088: });
089:
090: setTitle(Resources.getLocalString("rename_type_title"));
091: JLabel warningLabel = new JLabel(Resources
092: .getLocalString("refactor_warning"));
093: warningLabel.setForeground(Color.red);
094: nameLabel = new JLabel(Resources
095: .getLocalString("new_type_name"));
096: fullNameField = new JTextField();
097: fullNameField.setEditable(false);
098: nameField = new JTextField();
099:
100: typeList = new Vector(TypeFactory.getInstance()
101: .getRenameableTypes().values());
102: Collections.sort(typeList, new Comparator() {
103: public int compare(Object o1, Object o2) {
104: String s1 = ((Type) o1).getName();
105: String s2 = ((Type) o2).getName();
106: return (s1.compareToIgnoreCase(s2));
107: }
108:
109: public boolean equals(Object obj) {
110: if (obj == this )
111: return true;
112: return false;
113: }
114:
115: public int hashCode() {
116: return -1;
117: }
118: });
119:
120: typeBox = new JComboBox(typeList);
121:
122: // for correct pre-selection of a type:
123: Type initialSelectedType = (Type) typeBox.getItemAt(0);
124: try {
125: PackageManager.Package initialTypePackage;
126:
127: initialTypePackage = PackageManager.getInstance()
128: .getPackage(initialSelectedType);
129:
130: fullNameField.setText(initialSelectedType.getName());
131: packageIdentifier = initialTypePackage.getIdentifier()
132: + ".";
133: String relativeType = initialSelectedType.getName()
134: .substring(packageIdentifier.length());
135: nameField.setText(relativeType);
136:
137: } catch (PackageNotFoundException e1) {
138: logger.log(Level.WARNING, "Could not find package for "
139: + initialSelectedType.getName());
140: }
141:
142: typeBox.addItemListener(new ItemListener() {
143: public void itemStateChanged(ItemEvent e) {
144: Type selectedType = (Type) e.getItem();
145: try {
146: PackageManager.Package typePackage = PackageManager
147: .getInstance().getPackage(selectedType);
148: fullNameField.setText(selectedType.getName());
149: packageIdentifier = typePackage.getIdentifier()
150: + ".";
151: String relativeType = selectedType.getName()
152: .substring(packageIdentifier.length());
153: nameField.setText(relativeType);
154: } catch (PackageNotFoundException pnfe) {
155: logger.log(Level.WARNING,
156: "Could not find package for "
157: + selectedType.getName());
158: }
159: }
160: });
161: typeBox.setBackground(Color.white);
162: typeBox.setRenderer(new ComboBoxRenderer());
163: typeBox.addFocusListener(new FocusAdapter() {
164: public void focusLost(FocusEvent e) {
165: incrementalSearchString = "";
166: }
167: });
168:
169: typeBox.addKeyListener(new KeyAdapter() {
170: public void keyReleased(KeyEvent e) {
171: if (e.getKeyCode() == KeyEvent.VK_DELETE
172: || e.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
173: if (incrementalSearchString.length() == 1) {
174: incrementalSearchString = "";
175: } else if (incrementalSearchString.length() > 1) {
176: incrementalSearchString = incrementalSearchString
177: .substring(0, incrementalSearchString
178: .length() - 1);
179: }
180: searchIncremental();
181: e.consume();
182: } else if (!e.isActionKey() && !e.isControlDown()) {
183: char c = e.getKeyChar();
184: if (Character.isLetterOrDigit(c)
185: || Character.isSpaceChar(c)) {
186: incrementalSearchString = incrementalSearchString
187: + c;
188: searchIncremental();
189: e.consume();
190: }
191: }
192: }
193: });
194: if (preselectedTypeName != null) {
195: typeBox
196: .setSelectedIndex(findIndexForTypeStartingWith(preselectedTypeName));
197: }
198:
199: Object[] array = { warningLabel, typeBox, nameLabel,
200: fullNameField, nameField };
201:
202: optionPane = new JOptionPane(array,
203: JOptionPane.WARNING_MESSAGE,
204: JOptionPane.OK_CANCEL_OPTION);
205:
206: setContentPane(optionPane);
207: setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
208:
209: addWindowListener(new WindowAdapter() {
210: public void windowClosing(WindowEvent we) {
211: /*
212: * Instead of directly closing the window, we're going to change the JOptionPane's value property.
213: */
214: optionPane.setValue(new Integer(
215: JOptionPane.CLOSED_OPTION));
216: }
217: });
218:
219: nameField.addActionListener(new ActionListener() {
220: public void actionPerformed(ActionEvent e) {
221: optionPane.setValue(new Integer(JOptionPane.OK_OPTION));
222: }
223: });
224:
225: nameField
226: .addCaretListener(new javax.swing.event.CaretListener() {
227: public void caretUpdate(
228: javax.swing.event.CaretEvent e) {
229: fullNameField.setText(packageIdentifier
230: + nameField.getText());
231: }
232: });
233:
234: optionPane
235: .addPropertyChangeListener(new PropertyChangeListener() {
236: public void propertyChange(PropertyChangeEvent e) {
237: String prop = e.getPropertyName();
238:
239: if (isVisible()
240: && (e.getSource() == optionPane)
241: && (prop
242: .equals(JOptionPane.VALUE_PROPERTY) || prop
243: .equals(JOptionPane.INPUT_VALUE_PROPERTY))) {
244: Object value = optionPane.getValue();
245:
246: if (value == JOptionPane.UNINITIALIZED_VALUE) {
247: // ignore reset
248: return;
249: }
250:
251: int option = JOptionPane.CANCEL_OPTION;
252: if (value instanceof Integer) {
253: option = ((Integer) value).intValue();
254: }
255: if (option == JOptionPane.OK_OPTION) {
256: // Check input
257: boolean validName = true;
258: name = fullNameField.getText();
259: String shortName = nameField.getText();
260: if (name.startsWith("__")) {
261: JOptionPane
262: .showMessageDialog(
263: null,
264: Resources
265: .getLocalString("illegal_component_name"),
266: Resources
267: .getLocalString("illegal_component_name_title"),
268: JOptionPane.ERROR_MESSAGE);
269: validName = false;
270: } else {
271: for (int i = 0; i < name.length(); i++) {
272: if (!Character
273: .isLetterOrDigit(name
274: .charAt(i))) {
275: validName = false;
276: for (int j = 0; j < ContelligentConstants.allowedCharacters.length; j++) {
277: if (name.charAt(i) == ContelligentConstants.allowedCharacters[j]) {
278: validName = true;
279: break;
280: }
281: }
282: if (!validName) {
283: JOptionPane
284: .showMessageDialog(
285: null,
286: Resources
287: .getLocalString("illegal_component_name_char")
288: + " '"
289: + name
290: .charAt(i)
291: + "'",
292: Resources
293: .getLocalString("illegal_component_name_title"),
294: JOptionPane.ERROR_MESSAGE);
295: break;
296: }
297: }
298: }
299: }
300: // Do not allow empty type names; while this is OK for
301: // the
302: // server it breaks the client.
303: if (shortName.length() == 0) {
304: validName = false;
305: }
306: if (validName) {
307: type = ((Type) typeBox
308: .getSelectedItem())
309: .getName();
310: setVisible(false);
311: } else {
312: // Reset the JOptionPane's value.
313: // If you don't do this, then if the user
314: // presses the same button next time, no
315: // property change event will be fired.
316: optionPane
317: .setValue(JOptionPane.UNINITIALIZED_VALUE);
318: }
319: } else { // user closed dialog or clicked cancel
320: name = null;
321: type = null;
322: setVisible(false);
323: }
324: }
325: }
326: });
327: }
328:
329: public int getOption() {
330: if (optionPane.getValue() instanceof Integer
331: && ((Integer) optionPane.getValue()).intValue() == JOptionPane.OK_OPTION) {
332: return JOptionPane.OK_OPTION;
333: } else {
334: return JOptionPane.CANCEL_OPTION;
335: }
336: }
337:
338: public String getName() {
339: return name;
340: }
341:
342: public String getType() {
343: return type;
344: }
345:
346: private void searchIncremental() {
347: if (typeList != null) {
348: if (incrementalSearchString.length() == 0) {
349: typeBox.setSelectedIndex(0);
350: } else {
351: incrementalSearchString = incrementalSearchString
352: .toLowerCase();
353: typeBox
354: .setSelectedIndex(findIndexForTypeStartingWith(incrementalSearchString));
355: }
356: }
357: }
358:
359: private int findIndexForTypeStartingWith(String searchString) {
360: int i = 0;
361: for (Iterator it = typeList.iterator(); it.hasNext(); i++) {
362: Type type = (Type) it.next();
363: String name = type.getName();
364: if (name.toLowerCase().startsWith(searchString)) {
365: typeBox.setSelectedIndex(i);
366: return i;
367: }
368: }
369: return 0;
370: }
371:
372: class ComboBoxRenderer extends JLabel implements ListCellRenderer {
373:
374: public ComboBoxRenderer() {
375: setOpaque(true);
376: setHorizontalAlignment(LEFT);
377: setVerticalAlignment(CENTER);
378: }
379:
380: public java.awt.Component getListCellRendererComponent(
381: JList list, Object value, int index,
382: boolean isSelected, boolean cellHasFocus) {
383:
384: if (isSelected) {
385: setBackground(list.getSelectionBackground());
386: setForeground(list.getSelectionForeground());
387: } else {
388: setBackground(Color.white);
389: setForeground(list.getForeground());
390: }
391:
392: Type type = (Type) value;
393: setIcon(type.getIcon());
394: setText(type.getName());
395:
396: return this;
397: }
398: }
399: }
|