001: package org.enhydra.jawe.base.panel.panels;
002:
003: import java.awt.Color;
004: import java.awt.Component;
005: import java.awt.Dimension;
006: import java.awt.event.ActionEvent;
007: import java.awt.event.KeyEvent;
008: import java.awt.event.MouseAdapter;
009: import java.awt.event.MouseEvent;
010: import java.util.ArrayList;
011: import java.util.Iterator;
012: import java.util.List;
013:
014: import javax.swing.AbstractAction;
015: import javax.swing.Action;
016: import javax.swing.Box;
017: import javax.swing.BoxLayout;
018: import javax.swing.DefaultListModel;
019: import javax.swing.JButton;
020: import javax.swing.JComponent;
021: import javax.swing.JList;
022: import javax.swing.JOptionPane;
023: import javax.swing.JPanel;
024: import javax.swing.JScrollPane;
025: import javax.swing.KeyStroke;
026: import javax.swing.ListSelectionModel;
027: import javax.swing.event.ListSelectionEvent;
028: import javax.swing.event.ListSelectionListener;
029:
030: import org.enhydra.jawe.JaWEManager;
031: import org.enhydra.jawe.ResourceManager;
032: import org.enhydra.jawe.base.controller.JaWEActions;
033: import org.enhydra.jawe.base.controller.JaWEController;
034: import org.enhydra.jawe.base.editor.StandardXPDLElementEditor;
035: import org.enhydra.jawe.base.panel.InlinePanel;
036: import org.enhydra.jawe.base.panel.PanelSettings;
037: import org.enhydra.shark.xpdl.XMLCollection;
038: import org.enhydra.shark.xpdl.XMLElement;
039: import org.enhydra.shark.xpdl.XMLElementChangeInfo;
040: import org.enhydra.shark.xpdl.XMLElementChangeListener;
041: import org.enhydra.shark.xpdl.XMLUtil;
042:
043: /**
044: * Creates a list panel.
045: *
046: * @author Sasa Bojanic
047: * @author Zoran Milakovic
048: * @author Miroslav Popov
049: *
050: */
051: public class XMLBasicListPanel extends XMLBasicPanel implements
052: XMLElementChangeListener {
053:
054: protected static Dimension minimalDimension = new Dimension(250, 60);
055:
056: protected static Dimension listDimension = new Dimension(450, 150);
057:
058: /**
059: * Object which we are replacing from one place to another within the list by dragging it.
060: */
061: protected XMLElementView movingElement;
062:
063: /**
064: * Index of the object which we are replacing from one place to another within the list by
065: * dragging it.
066: */
067: protected int movingElementPosition;
068:
069: /**
070: * The new index of the object which we are replacing from one place to another within the list
071: * by dragging it.
072: */
073: protected int newMovingElementPosition;
074:
075: /** Indicates if object is being dragged. */
076: protected boolean dragging = false;
077:
078: /**
079: * Indicates if the code for changing object position within the list is executed.
080: */
081: protected boolean changing = false;
082:
083: protected JList allParam;
084:
085: protected JPanel toolbox;
086:
087: protected InlinePanel ipc;
088:
089: public XMLBasicListPanel(InlinePanel ipc, XMLCollection myOwner,
090: List elementsToShow, String title, boolean hasBorder,
091: boolean hasEmptyBorder, final boolean enableEditing,
092: boolean minDimension) {
093:
094: super (ipc, myOwner, title, true, hasBorder, hasEmptyBorder);
095: this .ipc = ipc;
096:
097: myOwner.addListener(this );
098: myOwner.setNotifyListeners(true);
099:
100: allParam = createList();
101: setupList(enableEditing);
102: fillListContent(elementsToShow);
103:
104: JScrollPane scrollParam = new JScrollPane();
105: scrollParam.setAlignmentX(Component.LEFT_ALIGNMENT);
106: //scrollParam.setAlignmentY(Component.TOP_ALIGNMENT);
107:
108: scrollParam.setViewportView(allParam);
109: if (!minDimension) {
110: scrollParam.setPreferredSize(new Dimension(listDimension));
111: } else {
112: scrollParam
113: .setPreferredSize(new Dimension(minimalDimension));
114: }
115:
116: toolbox = createToolbar();
117: JPanel paneAndArrows = new JPanel();
118: paneAndArrows.setLayout(new BoxLayout(paneAndArrows,
119: BoxLayout.X_AXIS));
120: paneAndArrows.add(scrollParam);
121:
122: // JPanel p = createArrowPanel();
123: // paneAndArrows.add(Box.createRigidArea(new Dimension(5, 0)));
124: // paneAndArrows.add(p);
125:
126: add(toolbox);
127: add(Box.createVerticalStrut(3));
128: add(paneAndArrows);
129:
130: adjustActions();
131: }
132:
133: public boolean isItemChangingPosition() {
134: return (changing || dragging);
135: }
136:
137: public JList getList() {
138: return allParam;
139: }
140:
141: public XMLElement getSelectedElement() {
142: if (allParam.getSelectedIndex() == -1)
143: return null;
144:
145: return ((XMLElementView) allParam.getSelectedValue())
146: .getElement();
147: }
148:
149: public boolean setSelectedElement(XMLElement el) {
150: int selIndex = -1;
151: XMLElementView ev = getRow(el);
152: for (int i = 0; i < allParam.getModel().getSize(); i++) {
153: XMLElementView elat = (XMLElementView) allParam.getModel()
154: .getElementAt(i);
155: if (ev.equals(elat)) {
156: selIndex = i;
157: break;
158: }
159: }
160:
161: if (selIndex != -1) {
162: allParam.setSelectedIndex(selIndex);
163: }
164: return (selIndex != -1);
165: }
166:
167: protected void moveItem(int upOrDown) {
168: newMovingElementPosition = movingElementPosition;
169: if (newMovingElementPosition == -1) {
170: return;
171: } else if (upOrDown == 0) {
172: newMovingElementPosition--;
173: } else {
174: newMovingElementPosition++;
175: }
176:
177: moveItem();
178: }
179:
180: protected void moveItem() {
181: changing = true;
182: DefaultListModel listModel = (DefaultListModel) allParam
183: .getModel();
184: XMLCollection owncol = (XMLCollection) getOwner();
185: int rowCnt = listModel.getSize();
186: if (movingElement == null || movingElementPosition == -1
187: || newMovingElementPosition == -1
188: || newMovingElementPosition == movingElementPosition
189: || (rowCnt - 1) < movingElementPosition
190: || (rowCnt - 1) < newMovingElementPosition
191: || !owncol.contains(movingElement.getElement())) {
192: changing = false;
193: return;
194: }
195:
196: XMLCollection col = (XMLCollection) getOwner();
197: if (JaWEManager.getInstance().getJaWEController()
198: .canRepositionElement(col, movingElement.getElement())) {
199: XMLElement currentElementAtPosition = ((XMLElementView) listModel
200: .getElementAt(newMovingElementPosition))
201: .getElement();
202: int newpos = owncol.indexOf(currentElementAtPosition);
203:
204: listModel.remove(movingElementPosition);
205: listModel.add(newMovingElementPosition, movingElement);
206:
207: JaWEController jc = JaWEManager.getInstance()
208: .getJaWEController();
209: jc.startUndouableChange();
210: owncol.reposition(movingElement.getElement(), newpos);
211: List toSelect = new ArrayList();
212: toSelect.add(movingElement.getElement());
213: jc.endUndouableChange(toSelect);
214:
215: try {
216: allParam.setSelectedIndex(newMovingElementPosition);
217: } catch (Exception ex) {
218: }
219:
220: movingElementPosition = newMovingElementPosition;
221: }
222: changing = false;
223: }
224:
225: protected Action newElementAction = new AbstractAction(
226: JaWEActions.NEW_ACTION) {
227: public void actionPerformed(ActionEvent ae) {
228: JaWEController jc = JaWEManager.getInstance()
229: .getJaWEController();
230:
231: XMLCollection col = (XMLCollection) getOwner();
232: XMLElement newEl = JaWEManager.getInstance()
233: .getXPDLObjectFactory().createXPDLObject(col, null,
234: false);
235: boolean isForModal = PanelUtilities.isForModalDialog(newEl);
236: if (!isForModal && ipc.isModified()) {
237: int sw = ipc.showModifiedWarning();
238: if (sw == JOptionPane.CANCEL_OPTION
239: || (sw == JOptionPane.YES_OPTION && ipc
240: .isModified())) {
241: return;
242: }
243: }
244:
245: boolean updInProg = false;
246: if (isForModal) {
247: StandardXPDLElementEditor ed = new StandardXPDLElementEditor();
248: ed.editXPDLElement(newEl);
249: boolean statOK = (ed.getStatus() == StandardXPDLElementEditor.STATUS_OK);
250: boolean canIns = true;
251: if (statOK) {
252: canIns = jc.canInsertElement(col, newEl);
253: }
254: if (!statOK || !canIns) {
255: if (!canIns) {
256: jc
257: .getJaWEFrame()
258: .message(
259: ed
260: .getLanguageDependentString("WarningCannotInsertElement"),
261: JOptionPane.WARNING_MESSAGE);
262: }
263: return;
264: }
265: updInProg = true;
266: }
267: jc.startUndouableChange();
268: col.add(newEl);
269: List temp = new ArrayList();
270: temp.add(newEl);
271: jc.endUndouableChange(temp);
272: if (updInProg) {
273: setSelectedElement(newEl);
274: }
275:
276: adjustActions();
277: }
278: };
279:
280: protected Action editElementAction = new AbstractAction(
281: JaWEActions.EDIT_PROPERTIES_ACTION) {
282: public void actionPerformed(ActionEvent ae) {
283: XMLElement editElement = getSelectedElement();
284: if (editElement != null) {
285: if (ipc.isModified()) {
286: int sw = ipc.showModifiedWarning();
287: if (sw == JOptionPane.CANCEL_OPTION
288: || (sw == JOptionPane.YES_OPTION && ipc
289: .isModified())) {
290: return;
291: }
292: }
293: JaWEManager.getInstance().getXPDLElementEditor()
294: .editXPDLElement(editElement);
295: }
296: }
297: };
298:
299: protected Action deleteElementAction = new AbstractAction(
300: JaWEActions.DELETE_ACTION) {
301: public void actionPerformed(ActionEvent ae) {
302: XMLElement deleteElement = getSelectedElement();
303: if (deleteElement != null) {
304: JaWEController jc = JaWEManager.getInstance()
305: .getJaWEController();
306: List sel = new ArrayList();
307: sel.add(deleteElement.getParent());
308: if (jc.confirmDelete(sel, deleteElement)) {
309: XMLCollection parent = (XMLCollection) getOwner();
310: jc.startUndouableChange();
311: parent.remove(deleteElement);
312: jc.endUndouableChange(sel);
313: ipc.getPanelSettings().adjustActions();
314: adjustActions();
315: }
316: }
317: }
318: };
319:
320: protected Action moveUpAction = new AbstractAction("MoveUp") {
321: public void actionPerformed(ActionEvent ae) {
322: moveItem(0);
323: adjustActions();
324: }
325: };
326:
327: protected Action moveDownAction = new AbstractAction("MoveDown") {
328: public void actionPerformed(ActionEvent ae) {
329: moveItem(1);
330: adjustActions();
331: }
332: };
333:
334: protected JList createList() {
335: DefaultListModel listModel = new DefaultListModel();
336:
337: JList l = new JList(listModel);
338: Color bkgCol = new Color(245, 245, 245);
339: if (ipc.getSettings() instanceof PanelSettings) {
340: bkgCol = ((PanelSettings) ipc.getSettings())
341: .getBackgroundColor();
342: }
343: l.setBackground(bkgCol);
344:
345: return l;
346: }
347:
348: protected void setupList(final boolean enableEditing) {
349: allParam.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
350:
351: allParam.setAlignmentX(Component.LEFT_ALIGNMENT);
352: allParam.setAlignmentY(Component.TOP_ALIGNMENT);
353:
354: final XMLCollection col = (XMLCollection) getOwner();
355: final boolean canRepos = JaWEManager.getInstance()
356: .getJaWEController().canRepositionElement(col, null);
357:
358: // mouse listener for editing on double-click and dragging list items
359: allParam.addMouseListener(new MouseAdapter() {
360: public void mouseClicked(MouseEvent me) {
361: // implement some action only if editing is enabled
362: if (enableEditing && me.getClickCount() > 1) {
363: editElementAction.actionPerformed(null);
364: }
365: }
366:
367: /** Marks the object which place within the list will be changed. */
368: public void mousePressed(MouseEvent me) {
369: if (!getOwner().isReadOnly() && canRepos) {
370: dragging = true;
371: }
372: movingElement = null;
373: movingElementPosition = -1;
374: try {
375: movingElementPosition = allParam.getSelectedIndex();
376: if (movingElementPosition >= 0) {
377: movingElement = (XMLElementView) allParam
378: .getSelectedValue();
379: adjustActions();
380: }
381: } catch (Exception ex) {
382: }
383:
384: if (changing) {
385: changing = false;
386: return;
387: }
388: }
389:
390: /** Just indicates that dragging is over. */
391: public void mouseReleased(MouseEvent me) {
392: dragging = false;
393: }
394:
395: });
396:
397: /** Changes position of object within the list. */
398: if (!myOwner.isReadOnly() && canRepos) {
399: allParam
400: .addListSelectionListener(new ListSelectionListener() {
401: public void valueChanged(ListSelectionEvent lse) {
402: if (dragging && !changing) {
403: newMovingElementPosition = -1;
404: try {
405: newMovingElementPosition = allParam
406: .getSelectedIndex();
407: } catch (Exception ex) {
408: }
409:
410: moveItem();
411: }
412: adjustActions();
413: }
414: });
415: }
416:
417: if (enableEditing) {
418: allParam.getInputMap(JComponent.WHEN_FOCUSED)
419: .put(
420: KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
421: 0, false), "edit");
422: allParam.getActionMap().put("edit", editElementAction);
423:
424: allParam.getInputMap(JComponent.WHEN_FOCUSED)
425: .put(
426: KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,
427: 0, false), "delete");
428: allParam.getActionMap().put("delete", deleteElementAction);
429: }
430:
431: if (!getOwner().isReadOnly() && canRepos) {
432: allParam
433: .setToolTipText(ResourceManager
434: .getLanguageDependentString("MessageDragItemToChangeItsPosition"));
435: }
436: }
437:
438: protected void fillListContent(List elementsToShow) {
439: // fills list
440: DefaultListModel listModel = (DefaultListModel) allParam
441: .getModel();
442: Iterator it = elementsToShow.iterator();
443: while (it.hasNext()) {
444: XMLElement elem = (XMLElement) it.next();
445: XMLElementView ev = getRow(elem);
446: listModel.addElement(ev);
447: }
448:
449: }
450:
451: protected XMLElementView getRow(XMLElement el) {
452: // if (el instanceof XMLComplexElement) {
453: return new XMLElementView(ipc, el, XMLElementView.TONAME);
454: // } else {
455: // return new XMLElementView( el, XMLElementView.TOVALUE);
456: // }
457: }
458:
459: protected JPanel createToolbar() {
460: JPanel panel = new JPanel();
461: panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
462: JButton buttonNew = PanelUtilities.createToolbarButton(ipc
463: .getSettings(), newElementAction);
464: buttonNew.setRolloverEnabled(true);
465: JButton buttonEdit = PanelUtilities.createToolbarButton(ipc
466: .getSettings(), editElementAction);
467: buttonEdit.setRolloverEnabled(true);
468: JButton buttonDelete = PanelUtilities.createToolbarButton(ipc
469: .getSettings(), deleteElementAction);
470: buttonDelete.setRolloverEnabled(true);
471:
472: panel.add(buttonNew);
473: panel.add(Box.createRigidArea(new Dimension(3, 3)));
474: panel.add(buttonEdit);
475: panel.add(Box.createRigidArea(new Dimension(3, 3)));
476: panel.add(buttonDelete);
477: panel.add(Box.createHorizontalGlue());
478: return panel;
479: }
480:
481: protected JPanel createArrowPanel() {
482: JPanel p = new JPanel();
483: p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
484: XMLCollection col = (XMLCollection) getOwner();
485: boolean canRepos = JaWEManager.getInstance()
486: .getJaWEController().canRepositionElement(col, null);
487:
488: JButton buttonUp = new JButton();
489: buttonUp.setIcon(ipc.getPanelSettings().getArrowUpImageIcon());
490:
491: buttonUp.setPreferredSize(new Dimension(16, 16));
492: buttonUp.setEnabled(!myOwner.isReadOnly() && canRepos);
493: buttonUp.addActionListener(moveUpAction);
494: JButton buttonDown = new JButton();
495:
496: buttonDown.setIcon(ipc.getPanelSettings()
497: .getArrowDownImageIcon());
498:
499: buttonDown.setPreferredSize(new Dimension(16, 16));
500: buttonDown.setEnabled(!myOwner.isReadOnly() && canRepos);
501: buttonDown.addActionListener(moveDownAction);
502: p.add(buttonUp);
503: p.add(Box.createVerticalGlue());
504: p.add(buttonDown);
505: return p;
506: }
507:
508: protected void adjustActions() {
509: JaWEController jc = JaWEManager.getInstance()
510: .getJaWEController();
511:
512: XMLElement selEl = getSelectedElement();
513: newElementAction.setEnabled(jc
514: .canCreateElement((XMLCollection) getOwner()));
515: editElementAction.setEnabled((selEl != null && XMLUtil
516: .getPackage(selEl) != null));
517: deleteElementAction.setEnabled((selEl != null && jc
518: .canRemoveElement((XMLCollection) getOwner(), selEl)));
519:
520: boolean canRepos = JaWEManager.getInstance()
521: .getJaWEController().canRepositionElement(
522: (XMLCollection) getOwner(), null);
523: moveUpAction.setEnabled(selEl != null
524: && allParam.getSelectedIndex() > 0 && canRepos);
525: moveDownAction.setEnabled(selEl != null
526: && allParam.getSelectedIndex() < allParam.getModel()
527: .getSize() - 1 && canRepos);
528: }
529:
530: public void xmlElementChanged(XMLElementChangeInfo info) {
531: if (info.getAction() == XMLElementChangeInfo.REMOVED) {
532: Iterator it = info.getChangedSubElements().iterator();
533: while (it.hasNext()) {
534: XMLElement el = (XMLElement) it.next();
535: removeElement(el);
536: }
537: } else if (info.getAction() == XMLElementChangeInfo.INSERTED) {
538: Iterator it = info.getChangedSubElements().iterator();
539: while (it.hasNext()) {
540: XMLElement el = (XMLElement) it.next();
541: addElement(el);
542: }
543: }
544: }
545:
546: public void addElement(XMLElement el) {
547: DefaultListModel listModel = (DefaultListModel) allParam
548: .getModel();
549: XMLElementView ev = getRow(el);
550: listModel.addElement(ev);
551: }
552:
553: public void removeElement(XMLElement el) {
554: DefaultListModel listModel = (DefaultListModel) allParam
555: .getModel();
556: XMLElementView ev = getRow(el);
557: if (ev != null)
558: listModel.removeElement(ev);
559: }
560:
561: public void cleanup() {
562: myOwner.removeListener(this);
563: allParam = null;
564: }
565:
566: }
|