001: package com.xoetrope.carousel.visualizer;
002:
003: import com.xoetrope.data.pojo.XPojoMethodArg;
004: import com.xoetrope.data.pojo.XPojoMethodArgs;
005: import java.awt.BorderLayout;
006: import java.awt.event.ActionEvent;
007: import java.awt.event.ActionListener;
008: import javax.swing.DefaultCellEditor;
009: import javax.swing.JButton;
010: import javax.swing.JComboBox;
011: import javax.swing.JPanel;
012: import javax.swing.JScrollPane;
013: import javax.swing.JTable;
014: import javax.swing.table.AbstractTableModel;
015: import javax.swing.table.TableCellEditor;
016: import javax.swing.table.TableColumn;
017: import net.xoetrope.editor.project.XEditorProject;
018: import net.xoetrope.editor.ui.KalideoscopeToolbar;
019:
020: public class XPojoArgsModelView extends JPanel implements
021: ActionListener {
022: private JButton changeArgValueBtn, changeArgTypeBtn;
023: private ModelVisualiserPanel visualiserPanel;
024: private KalideoscopeToolbar visualiserToolbar;
025: private XPojoMethodArgs rootNode;
026: private XEditorProject editorProject;
027: private XPojoArgsTable table;
028:
029: /**
030: * Creates a new instance of POJO method arguments visualiser.
031: */
032: public XPojoArgsModelView(XPojoMethodArgs node,
033: ModelVisualiserPanel panel) {
034: rootNode = node;
035: visualiserPanel = panel;
036: setLayout(new BorderLayout());
037: visualiserToolbar = new KalideoscopeToolbar();
038: changeArgValueBtn = visualiserToolbar.addTool(this ,
039: "addAttribute.gif", "ChangeValue",
040: "Change argument value");
041: changeArgValueBtn.setEnabled(true);
042: changeArgTypeBtn = visualiserToolbar.addTool(this ,
043: "addAttribute.gif", "ChangeType",
044: "Change argument type");
045: changeArgTypeBtn.setEnabled(true);
046: table = new XPojoArgsTable(rootNode);
047: JScrollPane tableScroll = new JScrollPane(table);
048: table.getModel().setArgsChangeListener(new Runnable() {
049: public void run() {
050: refreshTree();
051: }
052: });
053:
054: add(visualiserToolbar, BorderLayout.NORTH);
055: add(tableScroll, BorderLayout.CENTER);
056: table.revalidate();
057: table.repaint();
058:
059: // Set a pojo model invocation error observer
060: /*
061: XPojoModelEx.getInvocationErrorNotifier().addObserver( new Observer() {
062: public void update( Observable o, Object arg ) {
063: if ( arg == null )
064: return;
065: JOptionPane.showMessageDialog( visualiserPanel, arg, "invocation errer", JOptionPane.ERROR_MESSAGE );
066: }
067: });
068: */
069: }
070:
071: /**
072: * Refresh the tree model view
073: */
074: protected void refreshTree() {
075: ModelVisualiserTree tree = visualiserPanel
076: .getModelVisualiserTree();
077: if (tree != null) {
078: String path = tree.getStrippedPath();
079: tree.removeTreeSelectionListener(visualiserPanel);
080: tree.removeMouseListener(visualiserPanel);
081: tree.createTreeComp(null);
082: if (path != null)
083: tree.setSelectedPath(path);
084: tree.addTreeSelectionListener(visualiserPanel);
085: tree.addMouseListener(visualiserPanel);
086: }
087: }
088:
089: public void actionPerformed(ActionEvent ae) {
090:
091: }
092:
093: }
094:
095: /**
096: * Pojo method arguments table
097: */
098: class XPojoArgsTable extends JTable {
099: private static ArgType[] allTypes = { new ArgType(String.class),
100: new ArgType(Boolean.class), new ArgType(Character.class),
101: new ArgType(Integer.class), new ArgType(Long.class),
102: new ArgType(Float.class) };
103:
104: private static String[] FREE_VALUES = { "<null>" };
105:
106: private static String[] BOOLEAN_VALUES = { "true", "false",
107: "<null>" };
108:
109: public static final int COL_NAME_WIDTH = 100;
110: public static final int COL_TYPE_WIDTH = 100;
111: public static final int COL_VALUE_WIDTH = 100;
112: public static final int COL_DECLARED_WIDTH = 100;
113:
114: private XPojoArgsTableModel model;
115: private JComboBox allTypesComboBox;
116: private JComboBox freeValueComboBox;
117: private JComboBox booleanComboBox;
118: private DefaultCellEditor allTypesCellEditor;
119: private DefaultCellEditor freeValueCellEditor;
120: private DefaultCellEditor booleanCellEditor;
121:
122: public XPojoArgsTable(XPojoMethodArgs pojoArgs) {
123: super ();
124: setAutoCreateColumnsFromModel(false);
125: model = new XPojoArgsTableModel(pojoArgs, this );
126: setModel(model);
127:
128: // Create cell editors
129: allTypesComboBox = new JComboBox(allTypes);
130: allTypesCellEditor = new DefaultCellEditor(allTypesComboBox);
131: booleanComboBox = new JComboBox(BOOLEAN_VALUES);
132: booleanCellEditor = new DefaultCellEditor(booleanComboBox);
133: freeValueComboBox = new JComboBox(FREE_VALUES);
134: freeValueCellEditor = new DefaultCellEditor(freeValueComboBox);
135: freeValueComboBox.setSelectedIndex(0);
136: freeValueComboBox.setEditable(true);
137: // Create table columns
138: TableColumn nameColumn = new TableColumn(0, COL_NAME_WIDTH);
139: TableColumn typeColumn = new TableColumn(1, COL_TYPE_WIDTH);
140: TableColumn valueColumn = new TableColumn(2, COL_VALUE_WIDTH);
141: TableColumn declaredColumn = new TableColumn(3,
142: COL_DECLARED_WIDTH);
143: addColumn(nameColumn);
144: addColumn(typeColumn);
145: addColumn(valueColumn);
146: addColumn(declaredColumn);
147: }
148:
149: public XPojoArgsTableModel getModel() {
150: return model;
151: }
152:
153: public TableCellEditor getCellEditor(int row, int column) {
154: XPojoMethodArgs argsModel = model.getPojoModel();
155: if (argsModel == null)
156: return null;
157: TableCellEditor cellEditor = null;
158: XPojoMethodArg argModel = (XPojoMethodArg) argsModel.get(row);
159:
160: switch (column) {
161: case XPojoArgsTableModel.COL_TYPE:
162: if (argModel.isGeneric())
163: cellEditor = allTypesCellEditor;
164: break;
165: case XPojoArgsTableModel.COL_VALUE:
166: Class argType = argModel.getArgumentType();
167: if ((argType == Boolean.class)
168: || (argType == boolean.class))
169: cellEditor = booleanCellEditor;
170: else
171: cellEditor = freeValueCellEditor;
172: }
173: return cellEditor;
174: }
175:
176: /**
177: * Pojo method arguments table
178: */
179: class XPojoArgsTableModel extends AbstractTableModel {
180: public static final int COL_NAME = 0;
181: public static final int COL_TYPE = 1;
182: public static final int COL_VALUE = 2;
183: public static final int COL_DECLARED = 3;
184:
185: private XPojoMethodArgs model;
186: private XPojoArgsTable table;
187: private Runnable argsChangeListener;
188:
189: public XPojoArgsTableModel(XPojoMethodArgs args,
190: XPojoArgsTable argsTable) {
191: super ();
192: model = args;
193: table = argsTable;
194: argsChangeListener = null;
195: }
196:
197: protected void setArgsChangeListener(Runnable acl) {
198: argsChangeListener = acl;
199: }
200:
201: public void setType(XPojoMethodArg arg, Class newType) {
202: Class oldType = arg.getArgumentType();
203: if (!newType.equals(oldType)) {
204: arg.removeValue();
205: arg.setArgumentType(newType);
206: // Notify arguments change listener
207: if (argsChangeListener != null)
208: argsChangeListener.run();
209: }
210: }
211:
212: private void setValue(XPojoMethodArg arg, String value) {
213: Class argType = arg.getArgumentType();
214: if (value == null) {
215: arg.setValue(value);
216: } else if (argType == String.class) {
217: arg.setValue(value);
218: } else if ((argType == Boolean.class)
219: || (argType == boolean.class)) {
220: if ("true".equals(value))
221: arg.setValue(Boolean.TRUE);
222: else if ("false".equals(value))
223: arg.setValue(Boolean.FALSE);
224: } else if ((argType == Character.class)
225: || (argType == char.class)) {
226: if (value.length() == 1)
227: arg.setValue(new Character(value.charAt(0)));
228: } else if ((argType == Integer.class)
229: || (argType == int.class)) {
230: try {
231: int val = Integer.parseInt(value);
232: arg.setValue(new Integer(val));
233: } catch (NumberFormatException ex) {
234: return;
235: }
236: } else if ((argType == Long.class)
237: || (argType == long.class)) {
238: try {
239: long val = Long.parseLong(value);
240: arg.setValue(new Long(val));
241: } catch (NumberFormatException ex) {
242: return;
243: }
244: } else if ((argType == Float.class)
245: || (argType == float.class)) {
246: try {
247: float val = Float.parseFloat(value);
248: arg.setValue(new Float(val));
249: } catch (NumberFormatException ex) {
250: return;
251: }
252: } else
253: return;
254: // Notify arguments change listener
255: if (argsChangeListener != null)
256: argsChangeListener.run();
257: }
258:
259: public void setValueAt(Object val, int row, int column) {
260: if ((column < 0) || (column > 3))
261: return;
262: if ((row < 0) || (row >= getRowCount()))
263: return;
264: XPojoMethodArg arg = (XPojoMethodArg) model.get(row);
265: switch (column) {
266: case COL_TYPE:
267: if (val instanceof ArgType) {
268: Class argType = ((ArgType) val).getType();
269: setType(arg, argType);
270: }
271: break;
272: case COL_VALUE:
273: Class argType = arg.getArgumentType();
274: String value = null;
275: if ((argType == boolean.class)
276: || (argType == Boolean.class)) {
277: int idx = booleanComboBox.getSelectedIndex();
278: if (idx == BOOLEAN_VALUES.length - 1)
279: value = null;
280: else
281: value = (String) booleanComboBox
282: .getSelectedItem();
283: } else {
284: value = (String) freeValueComboBox
285: .getSelectedItem();
286: if ("<null>".equals(value))
287: value = null;
288: }
289: setValue(arg, value);
290: break;
291: }
292: table.revalidate();
293: table.repaint();
294: }
295:
296: public XPojoMethodArgs getPojoModel() {
297: return model;
298: }
299:
300: public Object getValueAt(int row, int column) {
301: if ((column < 0) || (column > 3))
302: return null;
303: if ((row < 0) || (row >= getRowCount()))
304: return null;
305: XPojoMethodArg arg = (XPojoMethodArg) model.get(row);
306: String retValue = null;
307: switch (column) {
308: case COL_NAME:
309: retValue = arg.getName();
310: break;
311: case COL_TYPE:
312: retValue = arg.getArgumentType().getSimpleName();
313: break;
314: case COL_VALUE:
315: if (arg.hasValue()) {
316: Object value = arg.getValue();
317: retValue = (value != null ? String.valueOf(value)
318: : "<null>");
319: } else {
320: retValue = "<not set>";
321: }
322: break;
323: case COL_DECLARED:
324: retValue = arg.getGenericName();
325: if (retValue == null)
326: retValue = "none";
327: break;
328: }
329: return retValue;
330: }
331:
332: public Class getColumnClass(int column) {
333: return String.class;
334: }
335:
336: public String getColumnName(int column) {
337: switch (column) {
338: case COL_NAME:
339: return "name";
340: case COL_TYPE:
341: return "type";
342: case COL_VALUE:
343: return "value";
344: case COL_DECLARED:
345: return "generic type name";
346: }
347: return null;
348: }
349:
350: public int getColumnCount() {
351: return 4;
352: }
353:
354: public int getRowCount() {
355: return (model != null ? model.getNumChildren() : 0);
356: }
357:
358: public boolean isCellEditable(int row, int column) {
359: if (column == COL_TYPE)
360: return true;
361: else if (column == COL_VALUE)
362: return true;
363: else
364: return false;
365: }
366: }
367:
368: }
369:
370: /**
371: * A wrapper for the argument type
372: */
373: class ArgType {
374: private Class argType;
375:
376: public ArgType(Class at) {
377: argType = at;
378: }
379:
380: public Class getType() {
381: return argType;
382: }
383:
384: public void setType(Class newType) {
385: argType = newType;
386: }
387:
388: public String toString() {
389: return (argType != null ? argType.getSimpleName() : "null");
390: }
391:
392: }
|