0001: package org.swingml.tablebrowser.ext;
0002:
0003: import java.awt.*;
0004: import java.awt.event.*;
0005: import java.util.*;
0006: import java.util.List;
0007:
0008: import javax.swing.*;
0009: import javax.swing.event.*;
0010: import javax.swing.table.*;
0011: import javax.swing.text.*;
0012:
0013: import org.swingml.*;
0014: import org.swingml.action.*;
0015: import org.swingml.component.*;
0016: import org.swingml.component.ext.*;
0017: import org.swingml.errors.*;
0018: import org.swingml.event.*;
0019: import org.swingml.model.*;
0020: import org.swingml.registry.*;
0021: import org.swingml.system.*;
0022: import org.swingml.tablebrowser.rowheader.*;
0023:
0024: public class TableBrowserComponent extends JTable implements
0025: XMLTranslatable, MouseListener, ListSelectionListener,
0026: SelectionMadeRemoteActionSubject, XMLStateTranslatable {
0027:
0028: private class TableBrowserCellData {
0029:
0030: private int column;
0031: private int row;
0032: private boolean selected;
0033:
0034: public TableBrowserCellData(int aRow, int aColumn) {
0035: setRow(aRow);
0036: setColumn(aColumn);
0037: }
0038:
0039: public TableBrowserCellData(int aRow, int aColumn,
0040: boolean isSelected) {
0041: this (aRow, aColumn);
0042: setSelected(isSelected);
0043: }
0044:
0045: public int getColumn() {
0046: return column;
0047: }
0048:
0049: public int getRow() {
0050: return row;
0051: }
0052:
0053: private boolean isRowDirty() {
0054: boolean result = false;
0055:
0056: // check entire row
0057: for (int x = 0; x < getColumnCount(); x++) {
0058: CellDataValue cell = (CellDataValue) getValueAt(
0059: getRow(), x);
0060: if (cell.isDirty()) {
0061: result = true;
0062: break;
0063: }
0064: }
0065:
0066: return result;
0067: }
0068:
0069: public boolean isSelected() {
0070: return selected;
0071: }
0072:
0073: public void setColumn(int aColumn) {
0074: this .column = aColumn;
0075: }
0076:
0077: public void setRow(int aRow) {
0078: this .row = aRow;
0079: }
0080:
0081: public void setSelected(boolean isSelected) {
0082: this .selected = isSelected;
0083: }
0084:
0085: /**
0086: * Check validity of row/column numbers, as well as the onlypostdirty flags/values
0087: */
0088: public boolean shouldBeExported() {
0089: boolean result = false;
0090:
0091: if (getRow() != -1 && getColumn() != -1) {
0092: // check dirty flags
0093: if (m_tableModel.isOnlyPostDirty()) {
0094: CellDataValue value = (CellDataValue) getValueAt(
0095: getRow(), getColumn());
0096:
0097: switch (m_tableModel.getSelectionStyle()) {
0098: case TableBrowserModel.SELECTION_STYLE_SINGLE_CELL:
0099: result = value.isDirty();
0100: break;
0101: case TableBrowserModel.SELECTION_STYLE_MULTI_CELL:
0102: result = value.isDirty();
0103: break;
0104: case TableBrowserModel.SELECTION_STYLE_SINGLE_ROW:
0105: // check entire row
0106: result = isRowDirty();
0107: break;
0108: case TableBrowserModel.SELECTION_STYLE_MULTI_ROW:
0109: // check entire row
0110: result = isRowDirty();
0111: break;
0112: case TableBrowserModel.SELECTION_STYLE_DEFAULT:
0113: result = true;
0114: break;
0115: }
0116: } else {
0117: // don't care about dirty flag
0118: result = true;
0119: }
0120: }
0121:
0122: return result;
0123: }
0124: }
0125:
0126: private TableBrowser browser = null;
0127: private ITableBrowserCellNavigationManager cellManager;
0128: private EventHandler eventHandler = EventHandler.getInstance();
0129: private boolean filtering;
0130: private boolean handlingEditingStopped;
0131: private int[] internalSelectedRows;
0132: private TableBrowserModel m_tableModel = null;
0133: private boolean movingRows;
0134: private boolean painting;
0135: private RowHeaderTable rowHeaderTable = null;
0136: private TableSort sort = null;
0137:
0138: public TableBrowserComponent(TableBrowserModel aModel) {
0139: // create contract, mediate data access
0140: TableBrowserContract tbc = new TableBrowserContract(aModel
0141: .data());
0142: tbc.setHeadings(aModel.extractColumnNames());
0143:
0144: // create and assign browser, browser handles sorting and filtering
0145: setBrowser(new TableBrowser(tbc, this , aModel));
0146:
0147: aModel.setTableBrowser(getBrowser());
0148: aModel.setContainer(this );
0149:
0150: this .m_tableModel = aModel;
0151:
0152: super .setName(aModel.getName());
0153: super .setToolTipText(aModel.getTooltip());
0154: super .addMouseListener(this );
0155:
0156: if (aModel.getWidth() > 0 || aModel.getHeight() > 0) {
0157: Dimension size = new Dimension(aModel.getWidth(), aModel
0158: .getHeight());
0159: super .setSize(size);
0160: }
0161:
0162: super .getSelectionModel().setSelectionMode(aModel.getMode());
0163: ToolTipManager.sharedInstance().registerComponent(this );
0164:
0165: switch (aModel.getSelectionStyle()) {
0166: case TableBrowserModel.SELECTION_STYLE_SINGLE_CELL:
0167: setColumnSelectionAllowed(true);
0168: setRowSelectionAllowed(true);
0169: setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
0170: break;
0171: case TableBrowserModel.SELECTION_STYLE_MULTI_CELL:
0172: setColumnSelectionAllowed(true);
0173: setRowSelectionAllowed(true);
0174: setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
0175: break;
0176: case TableBrowserModel.SELECTION_STYLE_MULTI_ROW:
0177: setColumnSelectionAllowed(false);
0178: setRowSelectionAllowed(true);
0179: setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
0180: break;
0181: default:
0182: // Default is single-row-selection style
0183: setColumnSelectionAllowed(false);
0184: setRowSelectionAllowed(true);
0185: setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
0186: break;
0187: }
0188:
0189: setSort(new TableSort());
0190: getSort().setModel(aModel);
0191:
0192: super .setAutoscrolls(true);
0193: }
0194:
0195: public void applylCellManager(
0196: ITableBrowserCellNavigationManager manager) {
0197: if (manager != null) {
0198: // bind keystrokes for this manager
0199: InputMap inputs = getInputMap(WHEN_FOCUSED);
0200: KeyStroke[] keyStrokes = manager.getKeyStrokes();
0201: for (int x = 0; x < keyStrokes.length; x++) {
0202: KeyStroke keyStroke = keyStrokes[x];
0203: inputs.put(keyStroke, "customKeyStrokeHandler");
0204: }
0205:
0206: // Set up the custom action to forward the keystrokes to the manager
0207: AbstractAction myAction = new AbstractAction() {
0208:
0209: public void actionPerformed(ActionEvent e) {
0210: if (e.getSource() instanceof TableBrowserComponent) {
0211: if (hasCellManager()) {
0212: getCellManager().handleCellNavigation(
0213: getSelectedRow(),
0214: getSelectedColumn());
0215: }
0216: }
0217: }
0218: };
0219: getActionMap().put("customKeyStrokeHandler", myAction);
0220:
0221: manager.setTableBrowser(this );
0222: }
0223:
0224: cellManager = manager;
0225: }
0226:
0227: public int convertRowIndexToModel(int rowIndex) {
0228: int result = ((CellDataValue) getValueAt(rowIndex, 0))
0229: .getModelRow();
0230: return result;
0231: }
0232:
0233: public boolean editCellAt(int row, int column) {
0234: boolean result = false;
0235: if (hasCellManager()
0236: && getCellManager().handleCellEditStart(row, column)) {
0237: result = super .editCellAt(row, column);
0238: } else {
0239: // no cell editor manager to worry about
0240: result = super .editCellAt(row, column);
0241: }
0242:
0243: return result;
0244: }
0245:
0246: public boolean editCellAt(int row, int column, EventObject e) {
0247: boolean result = false;
0248: if (hasCellManager()
0249: && getCellManager().handleCellEditStart(row, column)) {
0250: result = super .editCellAt(row, column, e);
0251: } else {
0252: // no cell editor manager to worry about
0253: result = super .editCellAt(row, column, e);
0254: }
0255:
0256: return result;
0257: }
0258:
0259: public void editingStopped(ChangeEvent e) {
0260: if (!handlingEditingStopped) {
0261: try {
0262: handlingEditingStopped = true;
0263: if (e.getSource() != null
0264: && e.getSource() instanceof TableCellEditor) {
0265: TableCellEditor editor = getCellEditor();
0266: Object value = editor.getCellEditorValue();
0267: setValueAt(value, editingRow, editingColumn);
0268: ((CellDataValue) getValueAt(editingRow,
0269: editingColumn)).setDirty(true);
0270:
0271: int theEditingRow = getEditingRow();
0272: int theEditingColumn = getEditingColumn();
0273:
0274: removeEditor();
0275:
0276: if (hasCellManager()) {
0277: getCellManager().handleCellEditEnd(
0278: theEditingRow, theEditingColumn);
0279: }
0280: }
0281: } finally {
0282: handlingEditingStopped = false;
0283: }
0284: }
0285: }
0286:
0287: public void filterColumn(String colname, String targetName) {
0288: filterColumn(colname, targetName, true);
0289: }
0290:
0291: public void filterColumn(String colname, String targetName,
0292: boolean partial) {
0293: while (isCurrentlyPainting() || isFiltering()) {
0294:
0295: }
0296:
0297: try {
0298: setFiltering(true);
0299:
0300: String filter = null;
0301: // get filter from specificed component is prefized with @
0302: if (targetName.indexOf("@") == 0) {
0303: String cleanTarget = targetName.substring(1);
0304: ISwingMLTextContainer theComponent = (ISwingMLTextContainer) eventHandler
0305: .findActionTarget(this .getTopLevelAncestor(),
0306: cleanTarget);
0307: filter = theComponent.getText();
0308: if (filter != null) {
0309: filter = filter.trim();
0310: }
0311:
0312: } else {
0313: filter = targetName;
0314: }
0315:
0316: // clear filter if empty
0317: if (filter.trim().equals("")) {
0318: getBrowser().removeFilter(colname);
0319: getBrowser().refreshFilters();
0320: } else {
0321: getBrowser().filterColumn(colname, filter, partial);
0322: }
0323: } catch (Throwable t) {
0324:
0325: } finally {
0326: setFiltering(false);
0327: }
0328:
0329: }
0330:
0331: public void filterColumnStartsWith(String colname, String targetName) {
0332: filterColumn(colname, targetName, false);
0333: }
0334:
0335: private void fireInvalidRowNumberError() {
0336: ISwingMLError error = new SwingMLError(
0337: "Please enter a valid row number (1-" + getRowCount()
0338: + ").", ISwingMLError.ERROR_BUSINESS_LOGIC);
0339:
0340: ISwingMLError errors[] = new ISwingMLError[1];
0341: errors[0] = error;
0342: ((SwingMLModel) getModel()).handle(errors);
0343: }
0344:
0345: public TableBrowser getBrowser() {
0346: return this .browser;
0347: }
0348:
0349: public TableCellEditor getCellEditor(int row, int column) {
0350: TableCellEditor result = null;
0351:
0352: Class clazz = getColumnClass(column);
0353: if (clazz == JButton.class) {
0354: result = new IconComponentCellEditor();
0355: } else {
0356: result = super .getCellEditor(row, column);
0357: }
0358:
0359: return result;
0360: }
0361:
0362: public ITableBrowserCellNavigationManager getCellManager() {
0363: return cellManager;
0364: }
0365:
0366: public int getColumnIndex(String columnName) {
0367: return getColumnModel().getColumnIndex(columnName);
0368: }
0369:
0370: private String getColumnStateXML(TableBrowserModel theModel) {
0371: StringBuffer result = new StringBuffer();
0372: if (theModel.isPostColumnState()) {
0373: List columns = theModel.getColumns();
0374: for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) {
0375: TableBrowserColumnModel theColumn = (TableBrowserColumnModel) columns
0376: .get(columnIndex);
0377:
0378: result.append("<COLUMN ");
0379: result.append(Constants.TEXT);
0380: result.append("=\"");
0381: result.append(theColumn.getText());
0382: result.append("\" ");
0383: result.append(Constants.WIDTH);
0384: result.append("=\"");
0385: result
0386: .append(getColumn(theColumn.getText())
0387: .getWidth());
0388: result.append("\" ");
0389: result.append(Constants.VISIBLE);
0390: result.append("=\"");
0391: result.append(theColumn.isVisible());
0392: result.append("\" ");
0393: result.append(Constants.COLUMN_ORDER);
0394: result.append("=\"");
0395: result.append(convertColumnIndexToView(columnIndex));
0396: result.append("\" ");
0397: result.append(Constants.SORT);
0398: result.append("=\"");
0399: String sortType = "ASC";
0400: ColumnHeadingCellRenderer chcr = (ColumnHeadingCellRenderer) getColumn(
0401: theColumn.getText()).getHeaderRenderer();
0402: if (chcr.getSortType() != null
0403: && chcr.getSortType().equalsIgnoreCase("D")) {
0404: sortType = "DESC";
0405: }
0406: result.append(sortType);
0407: result.append("\" ");
0408: result.append(Constants.SORTORDER);
0409: result.append("=\"");
0410: result.append(chcr.getSort());
0411: result.append("\" />");
0412:
0413: }
0414: }
0415: return result.toString();
0416: }
0417:
0418: private String getColumnXML(TableBrowserCellData cell) {
0419: String result = "";
0420: TableBrowserModel model = (TableBrowserModel) getModel();
0421: TableBrowserColumnModel tbcm = (TableBrowserColumnModel) model
0422: .getColumns().get(cell.getColumn());
0423: CellDataValue cdata = (CellDataValue) model.getValueAt(cell
0424: .getRow(), cell.getColumn());
0425:
0426: // Column Start
0427: boolean wasClicked = false;
0428: int selectedColumn = getSelectedColumn();
0429: if (selectedColumn == cell.getColumn()) {
0430: wasClicked = true;
0431: }
0432: result += xmlColStart(cdata, tbcm.getText(), wasClicked);
0433:
0434: // Value
0435: result += cdata.toString();
0436:
0437: // Column end
0438: result += xmlColEnd();
0439:
0440: return result;
0441: }
0442:
0443: protected int[] getInternalSelectedRows() {
0444: return internalSelectedRows;
0445: }
0446:
0447: private String getRowEndXML() {
0448: return "</TBR>";
0449: }
0450:
0451: public RowHeaderTable getRowHeaderTable() {
0452: return rowHeaderTable;
0453: }
0454:
0455: private String getRowStartXML(TableBrowserCellData cell) {
0456: return "<TBR index=\"" + cell.getRow() + "\" selected=\""
0457: + isRowSelected(cell.getRow()) + "\" >";
0458: }
0459:
0460: public TableSort getSort() {
0461: return sort;
0462: }
0463:
0464: private String getTableEndXML() {
0465: return "</TABLEBROWSER>";
0466: }
0467:
0468: private String getTableStartXML() {
0469: return "<TABLEBROWSER NAME=\"" + super .getName() + "\">";
0470: }
0471:
0472: public String getToolTipText(MouseEvent e) {
0473: String aTip = null;
0474: java.awt.Point p = e.getPoint();
0475: int rowIndex = rowAtPoint(p);
0476: int colIndex = columnAtPoint(p);
0477: int realColumnIndex = convertColumnIndexToModel(colIndex);
0478: TableBrowserModel model = (TableBrowserModel) getModel();
0479: try {
0480: aTip = model.getToolTip(convertRowIndexToModel(rowIndex),
0481: realColumnIndex);
0482: } catch (ArrayIndexOutOfBoundsException exception) {
0483: aTip = null;
0484: }
0485:
0486: if (aTip == null) {
0487: aTip = getToolTipText();
0488: }
0489: return aTip;
0490: }
0491:
0492: public String getXMLState() {
0493: StringBuffer result = new StringBuffer();
0494:
0495: TableBrowserModel theTableModel = (TableBrowserModel) super
0496: .getModel();
0497: boolean postState = theTableModel.isPostColumnState();
0498: theTableModel.setPostColumnState(true);
0499:
0500: result.append(getTableStartXML());
0501: result.append(getColumnStateXML(theTableModel));
0502: result.append(getTableEndXML());
0503:
0504: theTableModel.setPostColumnState(postState);
0505:
0506: return result.toString();
0507: }
0508:
0509: /**
0510: * Using the selectionStyle, find the selected rows/columns and export their
0511: * data
0512: */
0513: public String getXMLValue() {
0514: if (this .isEditing()) {
0515: this .getCellEditor().stopCellEditing();
0516: }
0517: List cellsToExport = new ArrayList();
0518: TableBrowserModel theTableModel = null;
0519: Object theModel = super .getModel();
0520: String thePostStyle = Constants.POST_ALL;
0521:
0522: if (theModel instanceof JTableModel) {
0523: theTableModel = (TableBrowserModel) theModel;
0524: thePostStyle = theTableModel.getPostStyle();
0525: }
0526:
0527: int[] columnsToPost = theTableModel.getPostColumns();
0528: if (columnsToPost == null || columnsToPost.length == 0) {
0529: // Post all columns, since they didn't specify
0530: columnsToPost = new int[getColumnCount()];
0531: for (int x = 0; x < getColumnCount(); x++) {
0532: columnsToPost[x] = x;
0533: }
0534: }
0535:
0536: StringBuffer result = new StringBuffer();
0537: if (thePostStyle.equalsIgnoreCase(Constants.POST_ALL)) {
0538: // Export all rows/columns
0539: for (int row = 0; row < getRowCount(); row++) {
0540: for (int column = 0; column < columnsToPost.length; column++) {
0541: TableBrowserCellData cell = new TableBrowserCellData(
0542: row, columnsToPost[column]);
0543: if (isCellSelected(row, columnsToPost[column])) {
0544: cell.setSelected(true);
0545: }
0546: cellsToExport.add(cell);
0547: }
0548: }
0549: } else {
0550: // Only export selected rows/columns
0551: switch (m_tableModel.getSelectionStyle()) {
0552: case TableBrowserModel.SELECTION_STYLE_SINGLE_CELL:
0553: // Single selected cell
0554: cellsToExport.add(new TableBrowserCellData(
0555: getSelectedRow(), getSelectedColumn(), true));
0556: break;
0557: case TableBrowserModel.SELECTION_STYLE_MULTI_CELL:
0558: // Multiple selected cells
0559: int[] selectedColumns = getSelectedColumns();
0560: int[] selectedRows = getSelectedRows();
0561: for (int x = 0; x < selectedRows.length; x++) {
0562: for (int y = 0; y < selectedColumns.length; y++) {
0563: if (isCellSelected(selectedRows[x],
0564: selectedColumns[y])) {
0565: cellsToExport.add(new TableBrowserCellData(
0566: selectedRows[x],
0567: selectedColumns[y], true));
0568: }
0569: }
0570: }
0571: break;
0572: case TableBrowserModel.SELECTION_STYLE_MULTI_ROW:
0573: // Mutliple selected rows - use Post columns for all
0574: // selected rows
0575: selectedRows = getSelectedRows();
0576: for (int x = 0; x < selectedRows.length; x++) {
0577: for (int y = 0; y < columnsToPost.length; y++) {
0578: boolean columnWasSelected = getSelectedColumn() == columnsToPost[y];
0579: cellsToExport.add(new TableBrowserCellData(
0580: selectedRows[x], columnsToPost[y],
0581: columnWasSelected));
0582: }
0583: }
0584: break;
0585: default:
0586: // Single selected row - use Post column for the one row
0587: int selectedRow = getSelectedRow();
0588: if (selectedRow != -1) {
0589: for (int x = 0; x < columnsToPost.length; x++) {
0590: boolean columnWasSelected = getSelectedColumn() == columnsToPost[x];
0591: cellsToExport.add(new TableBrowserCellData(
0592: selectedRow, columnsToPost[x],
0593: columnWasSelected));
0594: }
0595: }
0596: break;
0597: }
0598: }
0599:
0600: // Export the data now
0601: result.append(getTableStartXML());
0602: if (cellsToExport != null && cellsToExport.size() > 0) {
0603: TableBrowserCellData cell;
0604: int currentRow = -1;
0605: boolean exportedACell = false;
0606: Iterator schmiterator = cellsToExport.iterator();
0607: while (schmiterator.hasNext()) {
0608: cell = (TableBrowserCellData) schmiterator.next();
0609: if (cell.shouldBeExported()) {
0610: exportedACell = true;
0611: if (cell.getRow() != currentRow) {
0612: // is this the first row ever?
0613: if (currentRow != -1) {
0614: result.append(getRowEndXML());
0615: }
0616: // start a new row
0617: result.append(getRowStartXML(cell));
0618: currentRow = cell.getRow();
0619: }
0620:
0621: result.append(getColumnXML(cell));
0622: }
0623: }
0624:
0625: if (exportedACell) {
0626: result.append(getRowEndXML());
0627: }
0628:
0629: result.append(getColumnStateXML(theTableModel));
0630: }
0631: result.append(getTableEndXML());
0632: return result.toString();
0633: }
0634:
0635: private boolean hasCellManager() {
0636: return getCellManager() != null;
0637: }
0638:
0639: public boolean hasState() {
0640: return true;
0641: }
0642:
0643: private List incrementIntegerNumbers(List integerList, int increment) {
0644: List result = null;
0645: if (integerList != null) {
0646: result = new ArrayList();
0647: Iterator schmiterator = integerList.iterator();
0648: while (schmiterator.hasNext()) {
0649: int newValue = ((Integer) schmiterator.next())
0650: .intValue()
0651: + increment;
0652: result.add(new Integer(newValue));
0653: }
0654: }
0655:
0656: return result;
0657: }
0658:
0659: /*
0660: * (non-Javadoc)
0661: *
0662: * @see org.swingml.action.SelectionMadeRemoteActionSubject#invoke(org.swingml.action.SelectionMadeResult)
0663: */
0664: public void invoke(SelectionMadeResult result) {
0665:
0666: SwingMLLogger.getInstance().log(
0667: "Inovking Selection Action " + result);
0668: ActionModel model = new ActionModel();
0669:
0670: model.setComponent(result.getComponent());
0671: model.setMethod(result.getMethod());
0672: model.setTypes(result.getType());
0673: model.setValues(result.getValue());
0674:
0675: // invoke method
0676: EventUtil util = new EventUtil();
0677: Component comp = util.getComponent(this , model.getComponent());
0678:
0679: if (comp == null) {
0680:
0681: throw new RuntimeException("Select Result Component ("
0682: + model.getComponent()
0683: + ") not found, check spelling.. ");
0684:
0685: }
0686:
0687: EventHandler.getInstance().processAction(model, comp,
0688: model.getComponent(), null);
0689:
0690: }
0691:
0692: protected boolean isCurrentlyPainting() {
0693: return painting;
0694: }
0695:
0696: public boolean isFiltering() {
0697: return filtering;
0698: }
0699:
0700: public boolean isMovingRows() {
0701: return movingRows;
0702: }
0703:
0704: /**
0705: * @see java.awt.event.MouseListener#mouseClicked(MouseEvent)
0706: */
0707: public void mouseClicked(MouseEvent aEvt) {
0708: final int DOUBLE_CLICK_COUNT = 2;
0709: final int SINGLE_CLICK_COUNT = 1;
0710: String theEventType = null;
0711: switch (aEvt.getClickCount()) {
0712: case DOUBLE_CLICK_COUNT:
0713: theEventType = Constants.MOUSE_DOUBLE_CLICKED;
0714: break;
0715: case SINGLE_CLICK_COUNT:
0716: theEventType = Constants.MOUSE_SINGLE_CLICKED;
0717: break;
0718: default:
0719: theEventType = null;
0720: break;
0721: }
0722:
0723: if (theEventType != null && theEventType.length() > 0) {
0724: SwingMLModel modelToNotify = (SwingMLModel) super
0725: .getModel(); // default to notifying the table
0726:
0727: // look for cell or row listeners first
0728: TableBrowserModel model = (TableBrowserModel) getModel();
0729: if (getSelectedRow() >= 0) {
0730: TableRowModel rowModel = (TableRowModel) model
0731: .getRows().get(getSelectedRow());
0732: if (rowModel != null) {
0733: TableDataModel aDataModel = (TableDataModel) rowModel
0734: .getChildren().get(getSelectedColumn());
0735: if (aDataModel != null
0736: && aDataModel.hasListenersFor(theEventType)) {
0737: // notify cell listener
0738: modelToNotify = aDataModel;
0739: } else if (rowModel.hasListenersFor(theEventType)) {
0740: // notify row listener
0741: modelToNotify = rowModel;
0742: }
0743: }
0744: }
0745:
0746: this .eventHandler.handleEvent(modelToNotify, theEventType,
0747: this );
0748: }
0749: }
0750:
0751: public void mouseEntered(MouseEvent aEvt) {
0752: }
0753:
0754: public void mouseExited(MouseEvent aEvt) {
0755: }
0756:
0757: public void mousePressed(MouseEvent aEvt) {
0758: }
0759:
0760: public void mouseReleased(MouseEvent aEvt) {
0761: }
0762:
0763: public void moveRowsDown() {
0764: int[] selectedRows = getSelectedRows();
0765: if (selectedRows != null && selectedRows.length > 0) {
0766: setMovingRows(true);
0767: try {
0768: List rowsToSelect = new Vector();
0769: boolean moveLastRowToTop = false;
0770:
0771: for (int x = selectedRows.length - 1; x >= 0; x--) {
0772: int rowToMove = selectedRows[x];
0773: if (rowToMove != getRowCount() - 1) {
0774: int newRowNumber = getBrowser().moveRowDown(
0775: rowToMove);
0776: rowsToSelect.add(new Integer(newRowNumber));
0777: } else {
0778: // trying to move the last row
0779: // skip consecutive rows, then flag to move last row to top
0780: moveLastRowToTop = true;
0781: int nextRowToProcess = x - 1;
0782: int nextConsecutiveRowNumber = rowToMove;
0783: while (nextRowToProcess >= 0
0784: && selectedRows[nextRowToProcess] == nextConsecutiveRowNumber - 1) {
0785: rowsToSelect.add(new Integer(
0786: selectedRows[nextRowToProcess]));
0787: if (nextRowToProcess == 0) {
0788: break;
0789: } else {
0790: nextConsecutiveRowNumber = selectedRows[nextRowToProcess];
0791: nextRowToProcess--;
0792: }
0793: }
0794: x = nextRowToProcess + 1; // add 1 so for-loop doesn't stop
0795: }
0796: }
0797:
0798: if (moveLastRowToTop) {
0799: // move last row to top
0800: getBrowser().moveRow(getRowCount() - 1, 0);
0801:
0802: // increment all the numbers by one, since the last row gets moved to top and all rows move down one
0803: rowsToSelect = incrementIntegerNumbers(
0804: rowsToSelect, 1);
0805:
0806: // add first row to be selected
0807: rowsToSelect.add(new Integer(0));
0808: }
0809:
0810: refresh();
0811: reselectRows(rowsToSelect);
0812: } finally {
0813: setMovingRows(false);
0814: }
0815: }
0816: }
0817:
0818: /**
0819: * Move the selected rows to the given index
0820: */
0821: public void moveRowsTo(int index) {
0822: int[] selectedRows = getSelectedRows();
0823: if (selectedRows != null && selectedRows.length > 0) {
0824: if (index > 0 && index <= getRowCount()) {
0825: setMovingRows(true);
0826: try {
0827: getBrowser().moveRowsTo(selectedRows, index - 1);
0828:
0829: // which rows to select now?
0830: List movedRows = new ArrayList();
0831: int start = index - 1;
0832: int end = start + selectedRows.length - 1;
0833:
0834: if (index + selectedRows.length > getRowCount()) {
0835: // just select the last rows
0836: end = getRowCount() - 1;
0837: start = end - selectedRows.length + 1;
0838: }
0839:
0840: for (int x = start; x <= end; x++) {
0841: movedRows.add(new Integer(x));
0842: }
0843:
0844: refresh();
0845: reselectRows(movedRows);
0846: } finally {
0847: setMovingRows(false);
0848: }
0849: } else {
0850: fireInvalidRowNumberError();
0851: }
0852: }
0853: }
0854:
0855: public void moveRowsTo(String containerName) {
0856: String newContainerName = containerName;
0857: if (newContainerName.startsWith("@")) {
0858: newContainerName = newContainerName.substring(1);
0859: }
0860:
0861: Container container = SwingMLModelToContainerRegistry
0862: .getContainer(newContainerName);
0863: if (container != null) {
0864: String value = null;
0865:
0866: // add more container types here
0867: if (container instanceof JTextComponent) {
0868: value = ((JTextComponent) container).getText();
0869: }
0870:
0871: if (value != null) {
0872: try {
0873: int newRow = Integer.parseInt(value.trim());
0874: moveRowsTo(newRow);
0875: } catch (Exception e) {
0876: fireInvalidRowNumberError();
0877: }
0878: }
0879: }
0880: }
0881:
0882: public void moveRowsUp() {
0883: int[] selectedRows = getSelectedRows();
0884: if (selectedRows != null && selectedRows.length > 0) {
0885: setMovingRows(true);
0886: try {
0887: List rowsToSelect = new Vector();
0888: boolean moveFirstRowToBottom = false;
0889:
0890: for (int x = 0; x < selectedRows.length; x++) {
0891: int rowToMove = selectedRows[x];
0892: if (rowToMove != 0) {
0893: int newRowNumber = getBrowser().moveRowUp(
0894: rowToMove);
0895: rowsToSelect.add(new Integer(newRowNumber));
0896: } else {
0897: // trying to move the first row
0898: // skip consecutive rows, then flag to move first row to bottom
0899: moveFirstRowToBottom = true;
0900: int nextRowToProcess = x + 1;
0901: int nextConsecutiveRowNumber = rowToMove;
0902: while ((nextRowToProcess <= selectedRows.length - 1)
0903: && (selectedRows[nextRowToProcess] == nextConsecutiveRowNumber + 1)) {
0904: rowsToSelect.add(new Integer(
0905: selectedRows[nextRowToProcess]));
0906: if (nextRowToProcess == selectedRows.length - 1) {
0907: nextRowToProcess++;
0908: break;
0909: } else {
0910: nextConsecutiveRowNumber = selectedRows[nextRowToProcess];
0911: nextRowToProcess++;
0912: }
0913: }
0914: x = nextRowToProcess - 1;
0915: }
0916: }
0917:
0918: if (moveFirstRowToBottom) {
0919: // move first row to bottom
0920: getBrowser().moveRow(0, getRowCount() - 1);
0921:
0922: // decrement all the numbers by one, since the first row gets moved to bottom and all rows move up one
0923: rowsToSelect = incrementIntegerNumbers(
0924: rowsToSelect, -1);
0925:
0926: // add last row to be selected
0927: rowsToSelect.add(new Integer(getRowCount() - 1));
0928: }
0929:
0930: refresh();
0931: reselectRows(rowsToSelect);
0932: } finally {
0933: setMovingRows(false);
0934: }
0935: }
0936: }
0937:
0938: public void paint(Graphics g) {
0939: while (isCurrentlyPainting()) {
0940: // wait
0941: }
0942: try {
0943: setPainting(true);
0944: super .paint(g);
0945: } catch (Throwable t) {
0946:
0947: } finally {
0948: setPainting(false);
0949: }
0950: }
0951:
0952: public void refresh() {
0953: getBrowser().refresh();
0954: if (getRowHeaderTable() != null) {
0955: getRowHeaderTable().refresh();
0956: }
0957: }
0958:
0959: public void removeFilter(String colname, String value) {
0960: try {
0961: while (isCurrentlyPainting() || isFiltering()) {
0962:
0963: }
0964: setFiltering(true);
0965: getBrowser().removeFilter(colname, value);
0966: getBrowser().refreshFilters();
0967: } catch (Throwable t) {
0968: t.printStackTrace();
0969: } finally {
0970: setFiltering(false);
0971: }
0972: }
0973:
0974: private void reselectRows(List rowsToSelect) {
0975: if (rowsToSelect != null) {
0976: ListSelectionModel theSelectionModel = getSelectionModel();
0977: theSelectionModel.removeIndexInterval(0, getRowCount());
0978: Iterator schmiterator = rowsToSelect.iterator();
0979: while (schmiterator.hasNext()) {
0980: int rowToSelect = ((Integer) schmiterator.next())
0981: .intValue();
0982: theSelectionModel.addSelectionInterval(rowToSelect,
0983: rowToSelect);
0984: }
0985:
0986: showSelectedRows();
0987: }
0988: }
0989:
0990: public void setBrowser(TableBrowser aBrowser) {
0991: this .browser = aBrowser;
0992: }
0993:
0994: public void setColumnEditor(int columnIndex, TableCellEditor editor) {
0995: TableColumn tc = getColumnModel().getColumn(columnIndex);
0996: tc.setCellEditor(editor);
0997: }
0998:
0999: public void setColumnSelectionInterval(int index0, int index1) {
1000: super .setColumnSelectionInterval(index0, index1);
1001: }
1002:
1003: /**
1004: * Sets the column width for the given column. This will automatically turn
1005: * off the column auto resizing feature.
1006: *
1007: * @param index
1008: * the index of the column for which the width should be set
1009: * @param width
1010: * the width for the column.
1011: */
1012: public void setColumnWidth(int index, int width) {
1013: if (width > -1) {
1014: // Disable auto resizing
1015: this .setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
1016: // Get the column by the index
1017: TableColumn c = this .getColumnModel().getColumn(index);
1018: if (width == 0) {
1019: c.setMinWidth(width);
1020: c.setMaxWidth(width);
1021: c.setResizable(false);
1022: }
1023: c.setPreferredWidth(width);
1024: }
1025: }
1026:
1027: public void setFiltering(boolean isFiltering) {
1028: this .filtering = isFiltering;
1029: }
1030:
1031: protected void setInternalSelectedRows(int[] selectedRows) {
1032: this .internalSelectedRows = selectedRows;
1033: }
1034:
1035: public void setMovingRows(boolean moving) {
1036: if (moving) {
1037: while (isMovingRows()) {
1038: // wait
1039: }
1040: }
1041:
1042: this .movingRows = moving;
1043: }
1044:
1045: public void setPainting(boolean isPainting) {
1046: this .painting = isPainting;
1047: }
1048:
1049: public void setRowHeaderTable(RowHeaderTable table) {
1050: this .rowHeaderTable = table;
1051: }
1052:
1053: public void setSort(TableSort aSort) {
1054: this .sort = aSort;
1055: }
1056:
1057: public void setValueAt(Object aValue, int row, int column) {
1058: super .setValueAt(aValue, row, column);
1059: }
1060:
1061: public void showSelectedRows() {
1062: scrollRectToVisible(getCellRect(getSelectedRow(), 0, false));
1063: }
1064:
1065: public void valueChanged(ListSelectionEvent aEvt) {
1066: super .valueChanged(aEvt);
1067:
1068: if (!isMovingRows()) {
1069: // notify of deselection first
1070: int deselectedRows[] = getInternalSelectedRows();
1071: if (deselectedRows != null && deselectedRows.length > 0) {
1072: // notify each row's listeners
1073: for (int index = 0; index < deselectedRows.length; index++) {
1074: TableRowModel rowModel = (TableRowModel) ((TableBrowserModel) getModel())
1075: .getRows().get(deselectedRows[index]);
1076: eventHandler.handleEvent(rowModel,
1077: Constants.ITEM_STATE_CHANGED_DESELECTED,
1078: this );
1079: }
1080:
1081: // notify table's listeners
1082: eventHandler.handleEvent(this .m_tableModel,
1083: Constants.ITEM_STATE_CHANGED_DESELECTED, this );
1084: }
1085:
1086: // notify of selection, now
1087: int selectedRows[] = getSelectedRows();
1088: if (selectedRows != null && selectedRows.length > 0) {
1089: // notify each row's listeners
1090: for (int index = 0; index < selectedRows.length; index++) {
1091: TableRowModel rowModel = (TableRowModel) ((TableBrowserModel) getModel())
1092: .getRows().get(selectedRows[index]);
1093: eventHandler
1094: .handleEvent(
1095: rowModel,
1096: Constants.ITEM_STATE_CHANGED_SELECTED,
1097: this );
1098: }
1099:
1100: // notify table's listeners
1101: eventHandler.handleEvent(this .m_tableModel,
1102: Constants.ITEM_STATE_CHANGED_SELECTED, this );
1103: } else {
1104: // nothing selected
1105: if (this .m_tableModel != null) {
1106: eventHandler.handleEvent(this .m_tableModel,
1107: Constants.ITEM_STATE_CHANGED_NONE_SELECTED,
1108: this );
1109: }
1110: }
1111:
1112: setInternalSelectedRows(selectedRows);
1113: }
1114: }
1115:
1116: private String xmlColEnd() {
1117: return "</TBD>";
1118: }
1119:
1120: private String xmlColStart(CellDataValue cell, String columnName,
1121: boolean selected) {
1122: return "<TBD id=\"" + cell.getKey() + "\" index=\""
1123: + columnName + "\" dirty=\"" + cell.isDirty()
1124: + "\" value=\"" + cell.getValue() + "\" selected=\""
1125: + selected + "\">";
1126: }
1127: }
|