001: package org.swingml.treetablebrowser.ext;
002:
003: import java.awt.*;
004: import java.awt.event.*;
005: import java.util.*;
006: import java.util.List;
007:
008: import javax.swing.*;
009: import javax.swing.event.*;
010: import javax.swing.table.*;
011: import javax.swing.text.*;
012: import javax.swing.tree.*;
013:
014: import org.swingml.*;
015: import org.swingml.action.*;
016: import org.swingml.component.*;
017: import org.swingml.component.ext.*;
018: import org.swingml.event.*;
019: import org.swingml.model.*;
020: import org.swingml.system.*;
021:
022: public class TreeTableComponent extends JTable implements
023: MouseListener, XMLTranslatable,
024: SelectionMadeRemoteActionSubject, XMLStateTranslatable {
025:
026: /**
027: * ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel to
028: * listen for changes in the ListSelectionModel it maintains. Once a change
029: * in the ListSelectionModel happens, the paths are updated in the
030: * DefaultTreeSelectionModel.
031: */
032: class ListToTreeSelectionModelWrapper extends
033: DefaultTreeSelectionModel {
034:
035: /**
036: * Class responsible for calling updateSelectedPathsFromSelectedRows
037: * when the selection of the list changse.
038: */
039: class ListSelectionHandler implements ListSelectionListener {
040:
041: public void valueChanged(ListSelectionEvent e) {
042: updateSelectedPathsFromSelectedRows();
043: TreePath currentSelectionPath = ListToTreeSelectionModelWrapper.this
044: .getLeadSelectionPath();
045: if (currentSelectionPath != null
046: && currentSelectionPath != getActiveSelectionPath()) {
047: // notify of deselection
048: if (getActiveSelectionPath() != null) {
049: Object object = getActiveSelectionPath()
050: .getLastPathComponent();
051: EventHandler
052: .getInstance()
053: .handleEvent(
054: (SwingMLModel) object,
055: Constants.ITEM_STATE_CHANGED_DESELECTED,
056: TreeTableComponent.this );
057: }
058: setActiveSelectionPath(currentSelectionPath);
059:
060: // notify of selection
061: Object object = currentSelectionPath
062: .getLastPathComponent();
063: EventHandler.getInstance().handleEvent(
064: (SwingMLModel) object,
065: Constants.ITEM_STATE_CHANGED_SELECTED,
066: TreeTableComponent.this );
067: }
068: }
069: }
070:
071: /** Set to true when we are updating the ListSelectionModel. */
072: protected boolean updatingListSelectionModel;
073:
074: public ListToTreeSelectionModelWrapper() {
075: super ();
076: getListSelectionModel().addListSelectionListener(
077: createListSelectionListener());
078: }
079:
080: /**
081: * Creates and returns an instance of ListSelectionHandler.
082: */
083: protected ListSelectionListener createListSelectionListener() {
084: return new ListSelectionHandler();
085: }
086:
087: /**
088: * Returns the list selection model. ListToTreeSelectionModelWrapper
089: * listens for changes to this model and updates the selected paths
090: * accordingly.
091: */
092: ListSelectionModel getListSelectionModel() {
093: return listSelectionModel;
094: }
095:
096: /**
097: * This is overridden to set <code>updatingListSelectionModel</code>
098: * and message super. This is the only place DefaultTreeSelectionModel
099: * alters the ListSelectionModel.
100: */
101: public void resetRowSelection() {
102: if (!updatingListSelectionModel) {
103: updatingListSelectionModel = true;
104: try {
105: super .resetRowSelection();
106: } finally {
107: updatingListSelectionModel = false;
108: }
109: }
110: // Notice how we don't message super if
111: // updatingListSelectionModel is true. If
112: // updatingListSelectionModel is true, it implies the
113: // ListSelectionModel has already been updated and the
114: // paths are the only thing that needs to be updated.
115: }
116:
117: /**
118: * If <code>updatingListSelectionModel</code> is false, this will
119: * reset the selected paths from the selected rows in the list selection
120: * model.
121: */
122: protected void updateSelectedPathsFromSelectedRows() {
123: if (!updatingListSelectionModel) {
124: updatingListSelectionModel = true;
125: try {
126: // This is way expensive, ListSelectionModel needs an
127: // enumerator for iterating.
128: int min = listSelectionModel.getMinSelectionIndex();
129: int max = listSelectionModel.getMaxSelectionIndex();
130: clearSelection();
131: if (min != -1 && max != -1) {
132: for (int counter = min; counter <= max; counter++) {
133: if (listSelectionModel
134: .isSelectedIndex(counter)) {
135: TreePath selPath = tree
136: .getPathForRow(counter);
137: if (selPath != null) {
138: addSelectionPath(selPath);
139: }
140: }
141: }
142: }
143: } finally {
144: updatingListSelectionModel = false;
145: }
146: }
147: }
148: }
149:
150: /**
151: * TreeTableCellEditor implementation. Component returned is the JTree.
152: */
153: public class TreeTableCellEditor extends AbstractCellEditor
154: implements TableCellEditor {
155:
156: public Component getTableCellEditorComponent(JTable table,
157: Object value, boolean isSelected, int r, int c) {
158: JTextField field = new JTextField();
159: field.setText(value.toString());
160: if (value instanceof TreeTableBrowserNodeModel) {
161: return field;
162: }
163: return tree;
164: }
165:
166: /**
167: * Overridden to return false, and if the event is a mouse event it is
168: * forwarded to the tree.
169: * <p>
170: * The behavior for this is debatable, and should really be offered as a
171: * property. By returning false, all keyboard actions are implemented in
172: * terms of the table. By returning true, the tree would get a chance to
173: * do something with the keyboard events. For the most part this is ok.
174: * But for certain keys, such as left/right, the tree will
175: * expand/collapse where as the table focus should really move to a
176: * different column. Page up/down should also be implemented in terms of
177: * the table. By returning false this also has the added benefit that
178: * clicking outside of the bounds of the tree node, but still in the
179: * tree column will select the row, whereas if this returned true that
180: * wouldn't be the case.
181: * <p>
182: * By returning false we are also enforcing the policy that the tree
183: * will never be editable (at least by a key sequence).
184: */
185: public boolean isCellEditable(EventObject e) {
186: if (e instanceof MouseEvent) {
187: for (int counter = getColumnCount() - 1; counter >= 0; counter--) {
188: if (getColumnClass(counter) == TreeTableBrowserModelInterface.class) {
189: MouseEvent me = (MouseEvent) e;
190: MouseEvent newME = new MouseEvent(tree, me
191: .getID(), me.getWhen(), me
192: .getModifiers(), me.getX()
193: - getCellRect(0, counter, true).x, me
194: .getY(), me.getClickCount(), me
195: .isPopupTrigger());
196: tree.dispatchEvent(newME);
197: break;
198: }
199: }
200: }
201: return false;
202: }
203: }
204:
205: /**
206: * A TreeCellRenderer that displays a JTree.
207: */
208: public class TreeTableCellRenderer extends JTree implements
209: TableCellRenderer {
210:
211: private Icon closedFolderIcon;
212: private Icon leafIcon;
213: private Icon openFolderIcon;
214: /** Last table/tree row asked to renderer. */
215: protected int visibleRow;
216:
217: public TreeTableCellRenderer(TreeModel model) {
218: super (model);
219: }
220:
221: public Icon getClosedFolderIcon() {
222: return closedFolderIcon;
223: }
224:
225: public Icon getLeafIcon() {
226: return leafIcon;
227: }
228:
229: public Icon getOpenFolderIcon() {
230: return openFolderIcon;
231: }
232:
233: /**
234: * TreeCellRenderer method. Overridden to update the visible row.
235: */
236: public Component getTableCellRendererComponent(JTable table,
237: Object value, boolean isSelected, boolean hasFocus,
238: int row, int column) {
239: TreeTableBrowserModelAdapter model = (TreeTableBrowserModelAdapter) table
240: .getModel();
241: TreeTableBrowserDataModel cellModel = model.getDataModel(
242: row, column);
243: if (isSelected) {
244: setBackground(table.getSelectionBackground());
245: setForeground(table.getSelectionForeground());
246: } else if (cellModel != null) {
247: if (cellModel.getBackground() == null) {
248: setBackground(table.getBackground());
249: } else {
250: setBackground(cellModel.getBackground());
251: }
252: if (cellModel.getForeground() == null) {
253: setForeground(table.getForeground());
254: } else {
255: setForeground(cellModel.getForeground());
256: }
257: }
258:
259: if (cellModel != null) {
260: this .setFont(FontFactory.getFontForModel(cellModel,
261: table.getFont()));
262: }
263: visibleRow = row;
264:
265: return this ;
266: }
267:
268: /**
269: * Sublcassed to translate the graphics such that the last visible row
270: * will be drawn at 0,0.
271: */
272: public void paint(Graphics g) {
273: g.translate(0, -visibleRow * getRowHeight());
274: try {
275: super .paint(g);
276: } catch (Throwable t) {
277:
278: }
279: }
280:
281: /**
282: * This is overridden to set the height to match that of the JTable.
283: */
284: public void setBounds(int x, int y, int w, int h) {
285: super .setBounds(x, 0, w, TreeTableComponent.this
286: .getHeight());
287: }
288:
289: public void setClosedFolderIcon(Icon icon) {
290: this .closedFolderIcon = icon;
291: }
292:
293: public void setLeafIcon(Icon icon) {
294: this .leafIcon = icon;
295: }
296:
297: public void setOpenFolderIcon(Icon icon) {
298: this .openFolderIcon = icon;
299: }
300:
301: /**
302: * Sets the row height of the tree, and forwards the row height to the
303: * table.
304: */
305: public void setRowHeight(int height) {
306: if (height > 0) {
307: super .setRowHeight(height);
308: if (TreeTableComponent.this != null
309: && TreeTableComponent.this .getRowHeight() != height) {
310: TreeTableComponent.this
311: .setRowHeight(getRowHeight());
312: }
313: }
314: }
315:
316: /**
317: * updateUI is overridden to set the colors of the Tree's renderer to
318: * match that of the table.
319: */
320: public void updateUI() {
321: super .updateUI();
322: // Make the tree's cell renderer use the table's cell selection
323: // colors.
324: TreeCellRenderer tcr = getCellRenderer();
325: if (tcr instanceof DefaultTreeCellRenderer) {
326: DefaultTreeCellRenderer dtcr = ((DefaultTreeCellRenderer) tcr);
327: // For 1.1 uncomment this, 1.2 has a bug that will cause an
328: // exception to be thrown if the border selection color is
329: // null.
330: // dtcr.setBorderSelectionColor(null);
331: // Set the icons for the nodes
332: dtcr
333: .setOpenIcon(getOpenFolderIcon() != null ? getOpenFolderIcon()
334: : dtcr.getDefaultOpenIcon());
335: dtcr
336: .setClosedIcon(getClosedFolderIcon() != null ? getClosedFolderIcon()
337: : dtcr.getDefaultClosedIcon());
338: dtcr.setLeafIcon(getLeafIcon() != null ? getLeafIcon()
339: : dtcr.getDefaultLeafIcon());
340: dtcr.setTextSelectionColor(UIManager
341: .getColor("Table.selectionForeground"));
342: dtcr.setBackgroundSelectionColor(UIManager
343: .getColor("Table.selectionBackground"));
344: }
345: }
346: }
347:
348: private String actionURL;
349: private TreePath activeSelectionPath;
350: protected TreeTableBrowser browser;
351: private EventHandler eventHandler = EventHandler.getInstance();
352: /** A subclass of JTree. */
353: protected TreeTableCellRenderer tree;
354: private StringBuffer xmlValue;
355:
356: public TreeTableComponent(
357: final TreeTableBrowserModelInterface treeTableModel) {
358: super ();
359: addMouseListener(this );
360: browser = new TreeTableBrowser(this ,
361: (TreeTableBrowserModel) treeTableModel);
362: treeTableModel.setBrowser(browser);
363:
364: // Create the tree. It will be used as a renderer and editor.
365: tree = new TreeTableCellRenderer(treeTableModel);
366:
367: // Set the icons
368: tree
369: .setOpenFolderIcon(((TreeTableBrowserTreeModel) treeTableModel
370: .getRoot()).getOpenFolderIcon());
371: tree
372: .setClosedFolderIcon(((TreeTableBrowserTreeModel) treeTableModel
373: .getRoot()).getClosedFolderIcon());
374: tree.setLeafIcon(((TreeTableBrowserTreeModel) treeTableModel
375: .getRoot()).getLeafIcon());
376:
377: // Install a tableModel representing the visible rows in the tree.
378: super .setModel(new TreeTableBrowserModelAdapter(treeTableModel,
379: tree));
380:
381: // Force the JTable and JTree to share their row selection models.
382: ListToTreeSelectionModelWrapper selectionWrapper = new ListToTreeSelectionModelWrapper();
383: tree.setSelectionModel(selectionWrapper);
384: setSelectionModel(selectionWrapper.getListSelectionModel());
385:
386: // Install the tree editor renderer and editor.
387: setDefaultRenderer(TreeTableBrowserModelInterface.class, tree);
388: setDefaultEditor(TreeTableBrowserModelInterface.class,
389: new TreeTableCellEditor());
390:
391: // No grid.
392: setShowGrid(false);
393:
394: // No intercell spacing
395: setIntercellSpacing(new Dimension(0, 0));
396:
397: // Update the height of the trees row to match that of the table.
398: if (tree.getRowHeight() < 1) {
399: // Metal looks better like this.
400: setRowHeight(18);
401: }
402: applyColumnEditors((TreeTableBrowserModel) treeTableModel);
403:
404: browser.renderTable();
405: }
406:
407: public void applyColumnEditors(TreeTableBrowserModel browserModel) {
408: for (int i = 0; i < this .getColumnCount(); i++) {
409: TreeTableBrowserColumnModel m = (TreeTableBrowserColumnModel) browserModel
410: .getTreeTableColumns().get(i);
411: if (m.getCustomEditor() != null) {
412: getColumnModel().getColumn(i).setCellEditor(
413: m.getCustomEditor());
414: }
415: }
416: }
417:
418: public void applyFilters() {
419: TreeTableBrowserModelAdapter m = (TreeTableBrowserModelAdapter) getModel();
420: m.applyFilters();
421: updateUI();
422: }
423:
424: public void collapseAll() {
425: // collapse all
426: int nextRow = tree.getRowCount() - 1;
427: while (nextRow >= 0) {
428: nextRow = findNonLeafParentRowFrom(nextRow);
429: tree.collapseRow(nextRow);
430: nextRow--;
431: }
432: }
433:
434: private String dumpDatas(List datas, TreeTableBrowserModel model) {
435: String result = "";
436: Iterator itr = datas.iterator();
437: int index = 0;
438: while (itr.hasNext()) {
439: String colName = model.getColumnName(index);
440: TreeTableBrowserDataModel dm = (TreeTableBrowserDataModel) itr
441: .next();
442: result += xmlDataModel(dm, colName, isSelected(dm));
443: index++;
444: }
445:
446: return result;
447: }
448:
449: public void editingStopped(ChangeEvent e) {
450: TableCellEditor editor = getCellEditor();
451: if (editor != null) {
452: Object node = tree.getPathForRow(editingRow)
453: .getLastPathComponent();
454: if (node instanceof TreeTableBrowserNodeModel) {
455: // Mark the cell as dirty
456: TreeTableBrowserNodeModel model = (TreeTableBrowserNodeModel) node;
457: TreeTableBrowserDataModel cell = (TreeTableBrowserDataModel) model
458: .getTreeTableDatas().get(editingColumn);
459: cell.setDirty(true);
460: }
461: }
462: super .editingStopped(e);
463: }
464:
465: protected final void expand(final String s) {
466: for (int i = tree.getRowCount() - 1; i >= 0; i--) {
467: TreePath tp = tree.getPathForRow(i);
468: SwingMLModel smlm = (SwingMLModel) tp
469: .getLastPathComponent();
470: if (smlm.getName().equals(s)) {
471: tree.expandPath(tp);
472: break;
473: }
474: }
475: }
476:
477: public void expandAll() {
478: // expand all..
479: for (int i = 0; i < tree.getRowCount(); i++) {
480: browser.model.expand(getName(i));
481: tree.expandRow(i);
482: }
483: }
484:
485: public void expandTo(final String s) {
486: for (int i = tree.getRowCount() - 1; i >= 0; i--) {
487: TreePath tp = tree.getPathForRow(i);
488: SwingMLModel smlm = (SwingMLModel) tp
489: .getLastPathComponent();
490: if (smlm.getName().equals(s)) {
491: tree.expandPath(tp.getParentPath());
492: tree.setSelectionPath(tp);
493: break;
494: }
495: }
496: }
497:
498: public void filterColumn(String colname, String targetName) {
499: String filter = null;
500: // get filter from specificed component is prefized with @
501: if (targetName.indexOf("@") == 0) {
502: String cleanTarget = targetName.substring(1);
503: JTextComponent theComponent = (JTextComponent) eventHandler
504: .findActionTarget(this .getTopLevelAncestor(),
505: cleanTarget);
506: filter = theComponent.getText();
507: } else {
508: filter = targetName;
509: }
510: // clear filter if empty
511: if (filter.trim().equals("")) {
512: browser.filter.removeFilter(colname);
513: // I think this is required browser.filter.refreshFilters();
514: } else {
515: browser.filter.filterColumn(colname, filter);
516: }
517: applyFilters();
518: }
519:
520: private int findNonLeafParentRowFrom(int row) {
521: int result = row;
522: Object lastComponent = tree.getPathForRow(result)
523: .getLastPathComponent();
524: while (lastComponent instanceof TreeTableBrowserNodeModel) {
525: result--;
526: lastComponent = tree.getPathForRow(result)
527: .getLastPathComponent();
528: }
529: return result;
530: }
531:
532: /**
533: * @return Returns the actionURL.
534: */
535: public String getActionURL() {
536: return actionURL;
537: }
538:
539: /**
540: * @return Returns the activeSelectionPath.
541: */
542: public TreePath getActiveSelectionPath() {
543: return activeSelectionPath;
544: }
545:
546: /*
547: * Workaround for BasicTableUI anomaly. Make sure the UI never tries to
548: * paint the editor. The UI currently uses different techniques to paint the
549: * renderers and editors and overriding setBounds() below is not the right
550: * thing to do for an editor. Returning -1 for the editing row in this case,
551: * ensures the editor is never painted.
552: */
553: public int getEditingRow() {
554: return (getColumnClass(editingColumn) == TreeTableBrowserModelInterface.class) ? -1
555: : editingRow;
556: }
557:
558: private final String getName(final int i) {
559: SwingMLModel model = (SwingMLModel) tree.getPathForRow(i)
560: .getLastPathComponent();
561: return model.getName();
562: }
563:
564: public String getToolTipText(MouseEvent e) {
565: String aTip = null;
566: java.awt.Point p = e.getPoint();
567: int rowIndex = rowAtPoint(p);
568: int colIndex = columnAtPoint(p);
569: int realColumnIndex = convertColumnIndexToModel(colIndex);
570: TreeTableBrowserModelAdapter model = (TreeTableBrowserModelAdapter) getModel();
571: aTip = model.getToolTip(rowIndex, realColumnIndex);
572: if (aTip == null) {
573: aTip = getToolTipText();
574: }
575: return aTip;
576: }
577:
578: /**
579: * Returns the tree that is being shared between the model.
580: */
581: public JTree getTree() {
582: return tree;
583: }
584:
585: public String getXMLState() {
586: String result = xmlTableStart();
587: result += xmlColumnState();
588: result += xmlTableEnd();
589: return result;
590: }
591:
592: public String getXMLValue() {
593: TreeTableBrowserModel theTableModel = null;
594: TreeTableBrowserModelAdapter theModel = (TreeTableBrowserModelAdapter) getModel();
595: String thePostStyle = Constants.POST_ALL;
596: theTableModel = (TreeTableBrowserModel) theModel.treeTableModel;
597: thePostStyle = theTableModel.getPostStyle();
598: StringBuffer xml = new StringBuffer();
599: // post entire tree
600: if (thePostStyle.equalsIgnoreCase(Constants.POST_ALL)) {
601: xml.append(xmlTableStart());
602: List treeNodes = theTableModel.treeNodes();
603: for (int i = 0; i < treeNodes.size(); i++) {
604: xml.append(xmlTree((SwingMLModel) treeNodes.get(i),
605: theTableModel));
606: }
607: xml.append(xmlTableEnd());
608: } else {
609: // post only selected rows' data (column values)
610: xml.append(xmlTableStart());
611:
612: // Find nodes to post
613: ListToTreeSelectionModelWrapper sw = (ListToTreeSelectionModelWrapper) tree
614: .getSelectionModel();
615: TreePath[] selected = sw.getSelectionPaths();
616: List nodes = new ArrayList();
617: if (selected != null && selected.length > 0) {
618: for (int x = 0; x < selected.length; x++) {
619: TreePath path = selected[x];
620: nodes.add(path.getLastPathComponent());
621: }
622: }
623:
624: if (!nodes.isEmpty()) {
625: for (int i = 0; i < nodes.size(); i++) {
626: Object node = nodes.get(i);
627: SwingMLModel swingModel = (SwingMLModel) node;
628: xml.append(xmlNodeStart(swingModel,
629: isSelected(swingModel)));
630: List datas = null;
631: if (node instanceof TreeTableBrowserTreeModel) {
632: datas = ((TreeTableBrowserTreeModel) node)
633: .getTreeTableDatas();
634: } else {
635: datas = ((TreeTableBrowserNodeModel) node)
636: .getTreeTableDatas();
637: }
638:
639: int col = 0;
640: Iterator itr = datas.iterator();
641: while (itr.hasNext()) {
642: String colName = theTableModel
643: .getColumnName(col);
644: TreeTableBrowserDataModel dm = (TreeTableBrowserDataModel) itr
645: .next();
646: xml.append(xmlDataModel(dm, colName, true));
647: col++;
648: }
649: xml.append(xmlNodeEnd());
650: }
651: }
652: xml.append(xmlTableEnd());
653: }
654:
655: xmlValue = xml;
656: return xmlValue.toString();
657: }
658:
659: public boolean hasState() {
660: return true;
661: }
662:
663: public void invoke(SelectionMadeResult result) {
664: // process action
665: SwingMLLogger.getInstance().log(
666: "Invoking Selection Action " + result);
667: ActionModel model = new ActionModel();
668: model.setComponent(result.getComponent());
669: model.setMethod(result.getMethod());
670: model.setTypes(result.getType());
671: model.setValues(result.getValue());
672:
673: // invoke method
674: EventUtil util = new EventUtil();
675: Component comp = util.getComponent(this , model.getComponent());
676: if (comp == null) {
677: throw new RuntimeException("Select Result Component ("
678: + model.getComponent()
679: + ") not found, check spelling.. ");
680: }
681:
682: // Component target
683: EventHandler.getInstance().processAction(model, comp,
684: model.getComponent(), null);
685: }
686:
687: /**
688: * Returns true if the given model is currently selected on the screen.
689: * @param model
690: * @return
691: */
692: private boolean isSelected(SwingMLModel model) {
693: boolean result = false;
694: TreePath[] paths = tree.getSelectionModel().getSelectionPaths();
695: if (paths != null) {
696: for (int x = 0; x < paths.length; x++) {
697: TreePath path = paths[x];
698: for (int y = 0; y < path.getPathCount(); y++) {
699: Object component = path.getPathComponent(y);
700: if (component == model) {
701: result = true;
702: break;
703: }
704: }
705: }
706: }
707: return result;
708: }
709:
710: public void mouseClicked(MouseEvent e) {
711: if (getTree().getSelectionPath() != null) {
712: Object clickedOn = getTree().getSelectionPath()
713: .getLastPathComponent();
714: if (clickedOn instanceof TreeTableBrowserNodeModel) {
715: final int DOUBLE_CLICK_COUNT = 2;
716: final int SINGLE_CLICK_COUNT = 1;
717: String theEventType = null;
718: switch (e.getClickCount()) {
719: case DOUBLE_CLICK_COUNT:
720: theEventType = Constants.MOUSE_DOUBLE_CLICKED;
721: break;
722: case SINGLE_CLICK_COUNT:
723: theEventType = Constants.MOUSE_SINGLE_CLICKED;
724: break;
725: default:
726: theEventType = null;
727: break;
728: }
729: if (theEventType != null && theEventType.length() > 0) {
730: this .eventHandler.handleEvent(
731: (SwingMLModel) clickedOn, theEventType,
732: this );
733: }
734: }
735: } else if (getActiveSelectionPath() != null) {
736: this .eventHandler.handleEvent(
737: (SwingMLModel) getActiveSelectionPath()
738: .getLastPathComponent(),
739: Constants.ITEM_STATE_CHANGED_DESELECTED, this );
740: }
741: }
742:
743: public void mouseEntered(MouseEvent e) {
744: }
745:
746: public void mouseExited(MouseEvent e) {
747: }
748:
749: public void mousePressed(MouseEvent e) {
750: }
751:
752: public void mouseReleased(MouseEvent e) {
753: }
754:
755: public void removeFilter(String colname) {
756: browser.filter.removeFilter(colname);
757: }
758:
759: public void removeFilter(String colname, String value) {
760: browser.filter.removeFilter(colname, value);
761: }
762:
763: /**
764: * @param aUrl
765: * The actionURL to set.
766: */
767: public void setActionURL(String aUrl) {
768: this .actionURL = aUrl;
769: }
770:
771: /**
772: * @param aPath
773: * The activeSelectionPath to set.
774: */
775: public void setActiveSelectionPath(TreePath aPath) {
776: this .activeSelectionPath = aPath;
777: }
778:
779: /**
780: * Sets the column width for the given column. This will automatically turn
781: * off the column auto resizing feature.
782: *
783: * @param index
784: * the index of the column for which the width should be set
785: * @param width
786: * the width for the column.
787: */
788: public void setColumnWidth(int index, int width) {
789: if (width > -1) {
790: // Disable auto resizing
791: this .setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
792: // Get the column by the index
793: TableColumn c = this .getColumnModel().getColumn(index);
794: c.setPreferredWidth(width);
795: }
796: }
797:
798: /**
799: * Overridden to pass the new rowHeight to the tree.
800: */
801: public void setRowHeight(int height) {
802: super .setRowHeight(height);
803: if (tree != null && tree.getRowHeight() != height) {
804: tree.setRowHeight(getRowHeight());
805: }
806: }
807:
808: public void sort() {
809: TreeTableBrowserModelAdapter m = (TreeTableBrowserModelAdapter) getModel();
810: m.sort();
811: updateUI();
812: }
813:
814: /**
815: * Overridden to message super and forward the method to the tree. Since the
816: * tree is not actually in the component hieachy it will never receive this
817: * unless we forward it in this manner.
818: */
819: public void updateUI() {
820: super .updateUI();
821: if (tree != null) {
822: tree.updateUI();
823: }
824: // Use the tree's default foreground and background colors in the
825: // table.
826: LookAndFeel.installColorsAndFont(this , "Tree.background",
827: "Tree.foreground", "Tree.font");
828: }
829:
830: private String xmlColumnState() {
831: StringBuffer result = new StringBuffer();
832: for (int columnIndex = 0; columnIndex < getColumnCount(); columnIndex++) {
833: TableColumn theColumn = getColumnModel().getColumn(
834: columnIndex);
835: result.append("<COLUMN ");
836: result.append(Constants.TEXT);
837: result.append("=\"");
838: result.append(getColumnName(columnIndex));
839: result.append("\" ");
840: result.append(Constants.WIDTH);
841: result.append("=\"");
842: result.append(theColumn.getPreferredWidth());
843: result.append("\" ");
844: result.append(Constants.COLUMN_ORDER);
845: result.append("=\"");
846: result.append(columnIndex);
847: result.append("\" ");
848: result.append(Constants.SORT);
849: result.append("=\"");
850: String sortType = "ASC";
851: ColumnHeadingCellRenderer chcr = (ColumnHeadingCellRenderer) theColumn
852: .getHeaderRenderer();
853: if (chcr.getSortType() != null
854: && chcr.getSortType().equalsIgnoreCase("D")) {
855: sortType = "DESC";
856: }
857: result.append(sortType);
858: result.append("\" ");
859: result.append(Constants.SORTORDER);
860: result.append("=\"");
861: result.append(chcr.getSort());
862: result.append("\" />");
863:
864: }
865: return result.toString();
866: }
867:
868: private String xmlDataModel(TreeTableBrowserDataModel model,
869: String columnName, boolean selected) {
870: String result = "";
871: if (model != null) {
872: result = "<TREE_TABLE_BROWSER_DATA column=\"" + columnName
873: + "\" text=\"" + model.getDisplayValue()
874: + "\" value=\"" + model.getText() + "\" dirty=\""
875: + model.isDirty() + "\" selected=\"" + selected
876: + "\" />";
877: }
878: return result;
879: }
880:
881: private String xmlNodeEnd() {
882: return "</TREE_TABLE_BROWSER_NODE>";
883: }
884:
885: private String xmlNodeStart(SwingMLModel model, boolean selected) {
886: return "<TREE_TABLE_BROWSER_NODE NAME=\"" + model.getName()
887: + "\" selected=\"" + selected + "\" >";
888: }
889:
890: private String xmlTableEnd() {
891: return "</TREE_TABLE_BROWSER>";
892: }
893:
894: private String xmlTableStart() {
895: String text = browser.getModel().getText();
896: String name = getName();
897: return "<TREE_TABLE_BROWSER NAME=\"" + name + "\" TEXT=\""
898: + text + "\" >";
899: }
900:
901: private String xmlTree(SwingMLModel model,
902: TreeTableBrowserModel browserModel) {
903: String result = "";
904: // iterate over children and write nodes.
905: Iterator itr = model.getChildren().iterator();
906: while (itr.hasNext()) {
907: Object child = itr.next();
908: if (child instanceof TreeTableBrowserNodeModel) {
909: TreeTableBrowserNodeModel node = (TreeTableBrowserNodeModel) child;
910: result += xmlNodeStart(node, isSelected(node));
911: result += dumpDatas(node.getTreeTableDatas(),
912: browserModel);
913: result += xmlNodeEnd();
914: }
915: if (child instanceof TreeTableBrowserTreeModel) {
916: TreeTableBrowserTreeModel aTree = (TreeTableBrowserTreeModel) child;
917: result += xmlTreeStart(model.getName());
918: result += dumpDatas(aTree.getTreeTableDatas(),
919: browserModel);
920: result += xmlTree(aTree, browserModel);
921: result += xmlTableEnd();
922: }
923: }
924:
925: return result;
926: }
927:
928: private String xmlTreeStart(String name) {
929: return "<TREE_TABLE_BROWSER_TREE name=\"" + name + "\">";
930: }
931:
932: }
|