001: package hero.client.manager;
002:
003: /*
004: *
005: * JProjectList.java -
006: * Copyright (C) 2003 Ecoo Team
007: * valdes@loria.fr
008: *
009: *
010: * This program is free software; you can redistribute it and/or
011: * modify it under the terms of the GNU Lesser General Public License
012: * as published by the Free Software Foundation; either version 2
013: * of the License, or (at your option) any later version.
014: *
015: * This program is distributed in the hope that it will be useful,
016: * but WITHOUT ANY WARRANTY; without even the implied warranty of
017: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
018: * GNU Lesser General Public License for more details.
019: *
020: * You should have received a copy of the GNU Lesser General Public License
021: * along with this program; if not, write to the Free Software
022: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
023: */
024:
025: import hero.interfaces.Constants;
026: import hero.util.EventConstants;
027: import hero.util.BonitaClient;
028: import hero.net.UserSession.BnProjectLightValue;
029:
030: import java.awt.BorderLayout;
031: import java.awt.Color;
032: import java.awt.Dimension;
033: import java.awt.GridLayout;
034: import java.awt.Toolkit;
035: import java.awt.Component;
036: import java.awt.event.ActionEvent;
037: import java.awt.event.ActionListener;
038: import java.awt.event.MouseEvent;
039: import java.awt.event.MouseListener;
040: import java.util.Hashtable;
041: import java.util.Iterator;
042: import java.util.Collection;
043: import java.util.ArrayList;
044: import java.util.Enumeration;
045:
046: import javax.swing.JComboBox;
047: import javax.swing.JMenuItem;
048: import javax.swing.JOptionPane;
049: import javax.swing.JPanel;
050: import javax.swing.JLabel;
051: import javax.swing.JPopupMenu;
052: import javax.swing.JScrollPane;
053: import javax.swing.ImageIcon;
054: import javax.swing.JTextField;
055: import javax.swing.SwingConstants;
056: import javax.swing.tree.DefaultMutableTreeNode;
057: import javax.swing.tree.MutableTreeNode;
058: import javax.swing.tree.TreeCellRenderer;
059: import javax.swing.event.TreeModelListener;
060: import javax.swing.event.TreeModelEvent;
061: import javax.swing.tree.DefaultTreeCellRenderer;
062: import javax.swing.tree.DefaultTreeModel;
063: import javax.swing.tree.TreeSelectionModel;
064: import javax.swing.JTree;
065: import java.beans.PropertyChangeListener;
066: import java.beans.PropertyChangeEvent;
067:
068: public class JProjectList extends JPanel implements
069: PropertyChangeListener, Constants.Nd, EventConstants,
070: MouseListener {
071:
072: class MyTreeModelListener implements TreeModelListener {
073: // Rest of TreeModelListener is empty
074: public void treeNodesChanged(TreeModelEvent e) {
075: }
076:
077: public void treeNodesInserted(TreeModelEvent e) {
078: }
079:
080: public void treeNodesRemoved(TreeModelEvent e) {
081: }
082:
083: public void treeStructureChanged(TreeModelEvent e) {
084: }
085: }
086:
087: protected static class CustomDefaultRenderer extends
088: DefaultTreeCellRenderer {
089: public Component getTreeCellRendererComponent(JTree tree,
090: Object value, boolean selected, boolean expanded,
091: boolean leaf, int row, boolean hasFocus) {
092: // Allow the original renderer to set up the label
093: Component c = super .getTreeCellRendererComponent(tree,
094: value, selected, expanded, leaf, row, hasFocus);
095:
096: if (leaf) {
097: // Use a different foreground
098: // color for leaf nodes.
099: if (leafForeground != null) {
100: c.setForeground(leafForeground);
101: }
102: }
103:
104: return c;
105: }
106:
107: public void setLeafForeground(Color color) {
108: this .leafForeground = color;
109: }
110:
111: private Color leafForeground;
112: }
113:
114: static java.util.ResourceBundle resource = java.util.ResourceBundle
115: .getBundle("resources.Traduction")/*#BundleType=List*/;
116:
117: private JScrollPane jsppl;
118: private JTree tree;
119: private MListener ml;
120: private DefaultMutableTreeNode top;
121: private DefaultTreeModel treeModel;
122: public final static String SELECTED = "selected";
123: public final static String PROJECTCLOSE = "close";
124: public Hashtable projects = new Hashtable();
125: private hero.client.grapheditor.Frame frame;
126: private BonitaClient soapclient;
127: private String newStatus = Constants.Pj.ACTIVE;
128: private Collection actualProjects;
129: public final static String imageBase = "images/";
130: public final static ImageIcon icon = new ImageIcon(Thread
131: .currentThread().getContextClassLoader().getResource(
132: imageBase + "icon.png"));
133: private Toolkit toolkit = Toolkit.getDefaultToolkit();
134:
135: public JProjectList(BonitaClient soapclient, MListener ml,
136: Collection initialProjects) {
137: try {
138: this .actualProjects = initialProjects;
139: ml.addEventProjectListener(this );
140:
141: this .add(new JLabel(resource
142: .getString("jprojectlist.project")),
143: BorderLayout.NORTH);
144: this .soapclient = soapclient;
145:
146: top = new DefaultMutableTreeNode(resource
147: .getString("jprojectlist.project"));
148: treeModel = new DefaultTreeModel(top);
149: treeModel.addTreeModelListener(new MyTreeModelListener());
150:
151: tree = new JTree(treeModel);
152: tree.getSelectionModel().setSelectionMode(
153: TreeSelectionModel.SINGLE_TREE_SELECTION);
154:
155: TreeCellRenderer cr = tree.getCellRenderer();
156: CustomDefaultRenderer dtcr = new CustomDefaultRenderer();
157: tree.setCellRenderer(dtcr);
158: dtcr.setBackgroundNonSelectionColor(Color.white);
159: dtcr.setTextSelectionColor(Color.white);
160: dtcr.setTextNonSelectionColor(Color.black);
161: dtcr.setLeafForeground(Color.blue);
162:
163: // Retrieve the three icons
164: javax.swing.Icon leafIcon = new ImageIcon("images/ast.gif");
165: dtcr.setLeafIcon(leafIcon);
166: dtcr.setClosedIcon(leafIcon);
167: dtcr.setOpenIcon(leafIcon);
168:
169: tree.setRowHeight(0);
170:
171: //Finally, set the tree's background color
172: tree.setBackground(Color.white);
173:
174: this .createNodes(actualProjects);
175: jsppl = new JScrollPane(tree);
176:
177: this .setLayout(new BorderLayout());
178: this .setBackground(new Color(177, 177, 251));
179: this .add(jsppl, BorderLayout.CENTER);
180: tree.addMouseListener(this );
181: tree.setVisibleRowCount(10);
182: this .setVisible(true);
183:
184: } catch (Exception e) {
185: }
186: }
187:
188: public void newProject() {
189: JPanel jp = new JPanel();
190: ArrayList types = new ArrayList();
191: types.add("Model");
192: types.add("Cooperative");
193: JComboBox processTypes = new JComboBox(types.toArray());
194: processTypes.setSelectedItem("Model");
195:
196: JTextField projectName = new JTextField();
197: jp.add(new JLabel(resource
198: .getString("wfwindowsmanager.newproj"),
199: SwingConstants.LEFT));
200: jp.add(projectName);
201:
202: jp.setLayout(new GridLayout(0, 2));
203: jp.add(new JLabel(resource
204: .getString("wfwindowsmanager.choosetype"),
205: SwingConstants.LEFT));
206: jp.add(processTypes);
207:
208: int cloneOption = JOptionPane.showConfirmDialog(null, jp,
209: resource.getString("wfwindowsmanager.newproj"),
210: JOptionPane.OK_CANCEL_OPTION,
211: JOptionPane.QUESTION_MESSAGE, icon);
212: if (cloneOption != JOptionPane.CANCEL_OPTION) {
213: while ((projectName.getText()).equals("")
214: && cloneOption != JOptionPane.CANCEL_OPTION) {
215: JOptionPane.showMessageDialog(null, resource
216: .getString("wfwindowsmanager.enterproj"),
217: resource.getString("wfwindowsmanager.newproj"),
218: JOptionPane.INFORMATION_MESSAGE, icon);
219: cloneOption = JOptionPane.showConfirmDialog(null, jp,
220: resource.getString("wfwindowsmanager.newproj"),
221: JOptionPane.OK_CANCEL_OPTION,
222: JOptionPane.QUESTION_MESSAGE, icon);
223: }
224: if (cloneOption != JOptionPane.CANCEL_OPTION) {
225: try {
226: if (exists(projectName.getText())) {
227: JOptionPane
228: .showMessageDialog(
229: null,
230: resource
231: .getString("jprojectlist.exist"),
232: resource
233: .getString("jprojectlist.name"),
234: JOptionPane.INFORMATION_MESSAGE,
235: icon);
236: } else {
237: if (processTypes.getSelectedItem().equals(
238: "Model"))
239: soapclient.createModel(projectName
240: .getText());
241: else
242: soapclient.createProject(projectName
243: .getText());
244: }
245: } catch (Exception ex) {
246: ex.printStackTrace();
247: JOptionPane.showMessageDialog(null, resource
248: .getString("jprojectlist.exist"), resource
249: .getString("jprojectlist.new"),
250: JOptionPane.INFORMATION_MESSAGE, icon);
251: }
252: }
253: }
254: }
255:
256: private boolean exists(String project) {
257: try {
258: Object[] elems = this .actualProjects.toArray();
259: for (int i = 0; i < elems.length; i++) {
260: if (((String) elems[i]).equalsIgnoreCase(project))
261: return true;
262: }
263: return false;
264: } catch (Exception e) {
265: e.printStackTrace();
266: }
267: return true;
268: }
269:
270: public void mouseReleased(MouseEvent e) {
271: try {
272: if (!tree.isSelectionEmpty()) {
273: DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
274: .getLastSelectedPathComponent();
275: if ((e.getModifiers() & java.awt.event.InputEvent.BUTTON3_MASK) != 0) {
276: JPopupMenu menu = new JPopupMenu();
277: PopupMenu(menu);
278:
279: Dimension screen = Toolkit.getDefaultToolkit()
280: .getScreenSize();
281: Dimension size = menu.getPreferredSize();
282:
283: // Flip along screen
284:
285: int x = e.getX();
286: int y = e.getY();
287:
288: menu.show(this , e.getX()
289: - (int) jsppl.getViewport()
290: .getViewPosition().getX(), e.getY()
291: - (int) jsppl.getViewport()
292: .getViewPosition().getY());
293: } else if (e.getClickCount() == 1 && !node.isRoot()) {
294: String pl = node.getUserObject().toString();
295: firePropertyChange(SELECTED, "", pl);
296: } else if (e.getClickCount() == 2 && !node.isRoot()) {
297: try {
298: if (!projects.containsKey(node.getUserObject()
299: .toString())) {
300: frame = new hero.client.grapheditor.Frame(
301: node.getUserObject().toString(),
302: soapclient, false);
303: frame.setSize(new Dimension(500, 400));
304: frame.setVisible(true);
305: projects.put(node.getUserObject()
306: .toString(), frame);
307: frame.addPropertyChangeListener(
308: PROJECTCLOSE, this );
309: } else {
310: frame = (hero.client.grapheditor.Frame) projects
311: .get(node.getUserObject()
312: .toString());
313: frame.requestFocus();
314: }
315: } catch (Exception ce) {
316: //JOptionPane.showMessageDialog(null,resource.getString("jprojectlist.modify")+ node.getUserObject().toString()+ resource.getString("jprojectlist.proj"),resource.getString("jprojectlist.open"),JOptionPane.INFORMATION_MESSAGE,icon);
317: }
318: }
319: }
320: } catch (Exception e1) {
321: JOptionPane.showMessageDialog(null, resource
322: .getString("jprojectlist.error"), resource
323: .getString("jprojectlist.interror"),
324: JOptionPane.INFORMATION_MESSAGE, icon);
325: }
326: }
327:
328: public String getProjectType(String projectName) {
329: try {
330: soapclient.initProject(projectName);
331: return (soapclient.getType());
332: } catch (Exception e) {
333: return null;
334: }
335: }
336:
337: public String getProjectStatus(String projectName) {
338: try {
339: soapclient.initProject(projectName);
340: return (soapclient.getStatus());
341: } catch (Exception e) {
342: return null;
343: }
344:
345: }
346:
347: public void PopupMenu(JPopupMenu menu) {
348: JMenuItem mi;
349: ClassLoader cl = this .getClass().getClassLoader();
350:
351: if (!((DefaultMutableTreeNode) tree
352: .getLastSelectedPathComponent()).isRoot()) {
353: try {
354: DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
355: .getLastSelectedPathComponent();
356: String status = this .getProjectStatus(node
357: .getUserObject().toString());
358: if (status != null) {
359: String message = "";
360: if (status.equals(Constants.Pj.ACTIVE)) {
361: message = resource
362: .getString("jprojectlist.hideproject");
363: newStatus = Constants.Pj.HIDDEN;
364: } else {
365: message = resource
366: .getString("jprojectlist.activeproject");
367: newStatus = Constants.Pj.ACTIVE;
368: }
369:
370: mi = (JMenuItem) menu.add(new JMenuItem(message));
371: mi.addActionListener(new ActionListener() {
372: public void actionPerformed(ActionEvent e) {
373: DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
374: .getLastSelectedPathComponent();
375: setStatus(node.getUserObject().toString());
376: }
377: });
378: }
379: } catch (Exception statusEx) {
380: statusEx.printStackTrace();
381: }
382:
383: mi = (JMenuItem) menu.add(new JMenuItem(resource
384: .getString("jprojectlist.clone")));
385: mi.addActionListener(new ActionListener() {
386: public void actionPerformed(ActionEvent e) {
387: DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
388: .getLastSelectedPathComponent();
389: cloneProject(node.getUserObject().toString());
390: }
391: });
392:
393: mi = (JMenuItem) menu.add(new JMenuItem(resource
394: .getString("jprojectlist.inst")));
395: mi.addActionListener(new ActionListener() {
396: public void actionPerformed(ActionEvent e) {
397: DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
398: .getLastSelectedPathComponent();
399: instantiateProject(node.getUserObject().toString());
400: }
401: });
402:
403: mi = (JMenuItem) menu.add(new JMenuItem(resource
404: .getString("jprojectlist.details")));
405: mi.addActionListener(new ActionListener() {
406: public void actionPerformed(ActionEvent e) {
407: DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
408: .getLastSelectedPathComponent();
409: BrowserControl
410: .displayURL(java.lang.System
411: .getProperty("bonita.host")
412: + "/bonita/protected/Action.jsp?projectname="
413: + node.getUserObject().toString());
414: }
415: });
416:
417: mi = (JMenuItem) menu.add(new JMenuItem(resource
418: .getString("jprojectlist.terminate")));
419: mi.addActionListener(new ActionListener() {
420: public void actionPerformed(ActionEvent e) {
421: DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
422: .getLastSelectedPathComponent();
423: terminateProject(node.getUserObject().toString());
424: }
425: });
426:
427: mi = (JMenuItem) menu.add(new JMenuItem(resource
428: .getString("jprojectlist.delete")));
429: mi.addActionListener(new ActionListener() {
430: public void actionPerformed(ActionEvent e) {
431: DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
432: .getLastSelectedPathComponent();
433: deleteProject(node.getUserObject().toString());
434: }
435: });
436: }
437: }
438:
439: public void deleteProject(String project) {
440: try {
441: int option = JOptionPane.showConfirmDialog(null, resource
442: .getString("jprojectlist.deleteproject"), resource
443: .getString("jprojectlist.delete"),
444: JOptionPane.OK_CANCEL_OPTION,
445: JOptionPane.QUESTION_MESSAGE, icon);
446: if (option == JOptionPane.OK_OPTION) {
447: if (soapclient.deleteProject(project) == true)
448: JOptionPane
449: .showMessageDialog(
450: null,
451: resource
452: .getString("jprojectlist.proj")
453: + project
454: + " "
455: + resource
456: .getString("jprojectlist.remove"),
457: resource
458: .getString("jprojectlist.delete"),
459: JOptionPane.INFORMATION_MESSAGE,
460: icon);
461: }
462: } catch (Exception e) {
463: JOptionPane.showMessageDialog(null, e.getMessage(),
464: resource.getString("jprojectlist.delete"),
465: JOptionPane.INFORMATION_MESSAGE, icon);
466: }
467: }
468:
469: public void cloneProject(String project) {
470: try {
471: String newProject = (String) JOptionPane.showInputDialog(
472: null, resource.getString("jprojectlist.name"),
473: resource.getString("jprojectlist.clone"),
474: JOptionPane.QUESTION_MESSAGE, icon, null, null);
475:
476: while (newProject != null && newProject.equals("")) {
477: JOptionPane.showMessageDialog(null, resource
478: .getString("jprojectlist.enternew"), resource
479: .getString("jprojectlist.clone"),
480: JOptionPane.INFORMATION_MESSAGE, icon);
481: newProject = (String) JOptionPane.showInputDialog(null,
482: resource.getString("jprojectlist.name"),
483: resource.getString("jprojectlist.clone"),
484: JOptionPane.INFORMATION_MESSAGE, icon, null,
485: null);
486: }
487: if (newProject != null)
488: soapclient.cloneProject(project, newProject);
489:
490: } catch (Exception e) {
491: JOptionPane.showMessageDialog(null, resource
492: .getString("jprojectlist.exist"), resource
493: .getString("jprojectlist.clone"),
494: JOptionPane.INFORMATION_MESSAGE, icon);
495: }
496: }
497:
498: public void setStatus(String project) {
499: try {
500: String type = this .getProjectType(project);
501: if (project.matches(".*_instance.*"))
502: soapclient.initProject(project);
503: else {
504: if (type.equals(Constants.Pj.MODEL))
505: soapclient.initModel(project);
506: else
507: soapclient.initProject(project);
508: }
509: soapclient.setStatus(newStatus);
510: } catch (Exception e) {
511: JOptionPane.showMessageDialog(null, resource
512: .getString("jprojectlist.status"), resource
513: .getString("jprojectlist.clone"),
514: JOptionPane.INFORMATION_MESSAGE, icon);
515: }
516: }
517:
518: public void instantiateProject(String project) {
519: try {
520: soapclient.instantiateProject(project);
521: } catch (Exception e) {
522: JOptionPane.showMessageDialog(null, resource
523: .getString("jprojectlist.inst.error")
524: + ", " + e.getMessage(), resource
525: .getString("jprojectlist.inst"),
526: JOptionPane.INFORMATION_MESSAGE, icon);
527: }
528: }
529:
530: public void terminateProject(String project) {
531: try {
532: soapclient.terminateProject(project);
533: } catch (Exception e) {
534: JOptionPane.showMessageDialog(null, resource
535: .getString("jprojectlist.term.error")
536: + ": " + e.getMessage(), resource
537: .getString("jprojectlist.inst"),
538: JOptionPane.INFORMATION_MESSAGE, icon);
539: }
540: }
541:
542: public void changeEvent(Object[] e, String projectName) {
543: DefaultMutableTreeNode node = this .findParent(projectName);
544: if (node != null) {
545: // Remove node; if node has descendants, all descendants are removed as well
546: treeModel.removeNodeFromParent(node);
547: this .actualProjects.remove(projectName);
548: }
549: }
550:
551: public void addElement(String projectName) {
552: if (!exists(projectName)) {
553: this .addObject(projectName);
554: }
555: }
556:
557: public void addObject(String child) {
558: int startRow = 0;
559: String prefix = null;
560: // Find the parent project.
561: if (child.matches(".*_instance.*"))
562: prefix = child.substring(0, child.indexOf("_instance"));
563: else
564: prefix = resource.getString("jprojectlist.project");
565: DefaultMutableTreeNode nd = this .findParent(prefix);
566: MutableTreeNode node;
567: if (nd != null)
568: node = nd;
569: else {
570: treeModel.insertNodeInto(new DefaultMutableTreeNode(this
571: .getModel(child)), top, top.getChildCount());
572: actualProjects.add(this .getModel(child));
573: node = this .findParent(prefix);
574: }
575:
576: // Create new node
577: MutableTreeNode newNode = new DefaultMutableTreeNode(child);
578:
579: // Insert new node as last child of node
580: treeModel.insertNodeInto(newNode, node, node.getChildCount());
581: actualProjects.add(child);
582: }
583:
584: public void propertyChange(PropertyChangeEvent e) {
585: try {
586: if (e.getPropertyName().equals(PROJECTCLOSE)) {
587: projects.remove(e.getNewValue());
588: }
589: } catch (Exception e1) {
590: e1.printStackTrace();
591: }
592: }
593:
594: private void createNodes(Collection iniProj) throws Exception {
595: DefaultMutableTreeNode project = null;
596: DefaultMutableTreeNode instance = null;
597:
598: Collection instances = soapclient.getInstances();
599: Iterator inst = instances.iterator();
600: while (inst.hasNext()) {
601: String instName = (String) inst.next();
602: if (!iniProj.contains(this .getModel(instName)))
603: iniProj.add(this .getModel(instName));
604: }
605:
606: Iterator i = iniProj.iterator();
607: while (i.hasNext()) {
608: String projectName = (String) i.next();
609: project = new DefaultMutableTreeNode(projectName);
610: top.add(project);
611: }
612:
613: Iterator pInst = instances.iterator();
614: while (pInst.hasNext()) {
615: String instName = (String) pInst.next();
616: (this .findParent(this .getModel(instName)))
617: .add(new DefaultMutableTreeNode(instName));
618: }
619: this .actualProjects.addAll(instances);
620: }
621:
622: private DefaultMutableTreeNode findParent(String parent) {
623: DefaultMutableTreeNode root = (DefaultMutableTreeNode) treeModel
624: .getRoot();
625: DefaultMutableTreeNode node = null;
626: if (root != null)
627: for (Enumeration e = root.breadthFirstEnumeration(); e
628: .hasMoreElements();) {
629: DefaultMutableTreeNode current = (DefaultMutableTreeNode) e
630: .nextElement();
631: if (parent.equals(current.getUserObject())) {
632: node = current;
633: break;
634: }
635: }
636: if (node != null) {// found}
637: return node;
638: }
639: return null;
640: }
641:
642: // Get the name of the project model of this instance
643: private String getModel(String instanceName) {
644: int i = instanceName.indexOf("_instance");
645: return (instanceName.substring(0, i));
646: }
647:
648: public Collection getActualProjects() {
649: return this .actualProjects;
650: }
651:
652: // Rest of mouse listener is empty
653: public void mousePressed(MouseEvent e) {
654: }
655:
656: public void mouseEntered(MouseEvent e) {
657: }
658:
659: public void mouseExited(MouseEvent e) {
660: }
661:
662: public void mouseClicked(MouseEvent e) {
663: }
664:
665: }
|