001/** 002 * '$Author: barseghian $' 003 * '$Date: 2010-06-24 00:25:10 +0000 (Thu, 24 Jun 2010) $' 004 * '$Revision: 24970 $' 005 * 006 * For Details: 007 * http://www.kepler-project.org 008 * 009 * Copyright (c) 2009-2010 The Regents of the 010 * University of California. All rights reserved. Permission is hereby granted, 011 * without written agreement and without license or royalty fees, to use, copy, 012 * modify, and distribute this software and its documentation for any purpose, 013 * provided that the above copyright notice and the following two paragraphs 014 * appear in all copies of this software. IN NO EVENT SHALL THE UNIVERSITY OF 015 * CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, 016 * OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS 017 * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE 018 * POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY 019 * DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 020 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 021 * SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 * ENHANCEMENTS, OR MODIFICATIONS. 024 */ 025 026package org.kepler.workflowrunmanager.gui; 027 028import java.awt.Component; 029import java.awt.Rectangle; 030import java.util.EventObject; 031import java.util.Iterator; 032 033import javax.swing.JTable; 034import javax.swing.event.CellEditorListener; 035import javax.swing.event.ChangeEvent; 036import javax.swing.table.JTableHeader; 037import javax.swing.table.TableCellEditor; 038import javax.swing.table.TableColumn; 039 040import org.kepler.workflowrunmanager.WRMDefaults; 041 042/** 043 * ColumnGroup, GroupableTableColumnModel, GroupableTableHeader, 044 * GroupableTableHeaderUI and GroupableTableCellRenderer taken from a post by 045 * Steve Webb (16/09/04). He extended code originally posted by Nobuo Tamemasa. Many thanks 046 * to both authors. I've made some changes, including making the headers 047 * editable. 048 * 049 */ 050 051/** 052 * This is the object which manages the header of the JTable and also provides 053 * functionality for groupable headers. 054 */ 055public class GroupableTableHeader extends JTableHeader implements 056 CellEditorListener { 057 058 public static final int HEADER_ROW = -10; 059 transient protected int editingColumn; 060 transient protected TableCellEditor cellEditor; 061 transient protected Component editorComp; 062 063 private WRMDefaults wrmdefaults = WRMDefaults.getInstance(); 064 065 /** 066 * Constructs a GroupableTableHeader which is initialized with cm as the 067 * column model. If cm is null this method will initialize the table header 068 * with a default TableColumnModel. 069 * 070 * @param model 071 * the column model for the table 072 */ 073 public GroupableTableHeader(GroupableTableColumnModel model) { 074 super(model); 075 setUI(new GroupableTableHeaderUI()); 076 cellEditor = null; 077 // setDefaultEditor(Date.class, new JDateChooserCellEditor()); 078 // setReorderingAllowed(false); 079 // recreateTableColumn(model); 080 } 081 082 /** 083 * Sets the margins correctly for all groups within the header. 084 */ 085 public void setColumnMargin() { 086 int columnMargin = getColumnModel().getColumnMargin(); 087 Iterator<ColumnGroup> iter = ((GroupableTableColumnModel) columnModel) 088 .columnGroupIterator(); 089 while (iter.hasNext()) { 090 ColumnGroup cGroup = iter.next(); 091 cGroup.setColumnMargin(columnMargin); 092 } 093 } 094 095 // 096 /* 097 * protected void recreateTableColumn(GroupableTableColumnModel columnModel) 098 * { int n = columnModel.getColumnCount(); EditableHeaderTableColumn[] 099 * newCols = new EditableHeaderTableColumn[n]; TableColumn[] oldCols = new 100 * TableColumn[n]; for (int i=0;i<n;i++) { oldCols[i] = 101 * columnModel.getColumn(i); newCols[i] = new EditableHeaderTableColumn(); 102 * newCols[i].copyValues(oldCols[i]); } for (int i=0;i<n;i++) { 103 * columnModel.removeColumn(oldCols[i]); } for (int i=0;i<n;i++) { 104 * columnModel.addColumn(newCols[i]); } } 105 */ 106 107 public void editingCanceled(ChangeEvent e) { 108 removeEditor(); 109 } 110 111 public void editingStopped(ChangeEvent e) { 112 113 TableCellEditor editor = getCellEditor(); 114 if (editor != null) { 115 Object value = editor.getCellEditorValue(); 116 int index = getEditingColumn(); 117 int realColumnIndex = getTable().convertColumnIndexToModel(index); 118 // TODO change instead the appropriate part of header 119 GroupableTableColumnModel columnModel = (GroupableTableColumnModel) getColumnModel(); 120 // need to use realColumnIndex here 121 columnModel.getColumnGroup(realColumnIndex).setHeaderValue(value); 122 removeEditor(); 123 } 124 125 } 126 127 public void removeEditor() { 128 129 TableCellEditor editor = getCellEditor(); 130 if (editor != null) { 131 editor.removeCellEditorListener(this); 132 133 // requestFocus(); //discouraged because platform dependent behavior 134 // boolean requestFocusInWindow = requestFocusInWindow(); //never 135 // works 136 137 remove(editorComp); 138 139 int index = getEditingColumn(); 140 Rectangle cellRect = getHeaderRect(index); 141 142 setCellEditor(null); 143 setEditingColumn(index); 144 // setEditingColumn(-1); 145 editorComp = null; 146 147 repaint(cellRect); 148 // paintComponent(editorComp); 149 } 150 } 151 152 /* 153 * public boolean editCellAt(int index) { return editCellAt(index); } 154 */ 155 156 public boolean editCellAt(int index, EventObject e) { 157 158 if (cellEditor != null && !cellEditor.stopCellEditing()) { 159 return false; 160 } 161 if (!isCellEditable(index)) { 162 return false; 163 } 164 165 // int realColumnIndex = getTable().convertColumnIndexToModel(index); 166 // int columnIndex = columnModel.getColumn(index).getModelIndex(); 167 TableCellEditor editor = getCellEditor(index); 168 169 if (editor != null && editor.isCellEditable(e)) { 170 // TODO check this is right: 171 editorComp = prepareEditor(editor, index); 172 editorComp.setBounds(getHeaderRect(index)); 173 add(editorComp); 174 editorComp.validate(); 175 setCellEditor(editor); 176 // GroupableTableColumnModel columnModel = 177 // (GroupableTableColumnModel) getColumnModel(); 178 // columnIndex = columnModel.getColumn(index).getModelIndex(); 179 // setEditingColumn(columnIndex); 180 setEditingColumn(index); // should use index 181 editor.addCellEditorListener(this); 182 return true; 183 } 184 return false; 185 } 186 187 public boolean isCellEditable(int index) { 188 189 if (getReorderingAllowed()) { 190 ///System.out.println("GroupableTableHeader isCellEditable("+index+"). getReorderingAllowed():"+getReorderingAllowed()); 191 // return false; 192 } 193 // int columnIndex = columnModel.getColumn(index).getModelIndex(); 194 // EditableHeaderTableColumn col = 195 // (EditableHeaderTableColumn)columnModel.getColumn(columnIndex); 196 197 // System.out.println("GroupableTableHeader isCellEditable("+index+") returning " 198 // + col.isHeaderEditable()); 199 200 // FIXME hardcode 201 return true; 202 203 // return col.isHeaderEditable(); 204 } 205 206 public TableCellEditor getCellEditor() { 207 return cellEditor; 208 } 209 210 public TableCellEditor getCellEditor(int index) { 211 212 GroupableTableColumnModel columnModel = (GroupableTableColumnModel) getColumnModel(); 213 TableColumn aColumn = columnModel.getColumn(index); 214 Iterator<ColumnGroup> iter = columnModel.getColumnGroups(aColumn); 215 if (iter != null) { 216 // FIXME get rid of loop, only return appropriate thing 217 while (iter.hasNext()) { 218 ColumnGroup cGroup = iter.next(); 219 TableCellEditor tce = cGroup.getHeaderEditor(); 220 // System.out.println("GroupableTableHeader getCellEditor("+index+")"+" 221 // cGroup.getHeaderValue().toString():"+ 222 return tce; 223 } 224 } 225 226 // return col.getHeaderEditor(); 227 return null; 228 } 229 230 public int getEditingColumn() { 231 return editingColumn; 232 } 233 234 public void setEditingColumn(int aColumn) { 235 editingColumn = aColumn; 236 } 237 238 public void setCellEditor(TableCellEditor newEditor) { 239 TableCellEditor oldEditor = cellEditor; 240 cellEditor = newEditor; 241 242 // firePropertyChange 243 244 if (oldEditor != null) { 245 ((TableCellEditor) oldEditor) 246 .removeCellEditorListener((CellEditorListener) this); 247 } 248 if (newEditor != null) { 249 ((TableCellEditor) newEditor) 250 .addCellEditorListener((CellEditorListener) this); 251 } 252 253 } 254 255 public Component getEditorComponent() { 256 return editorComp; 257 } 258 259 public Component prepareEditor(TableCellEditor editor, int index) { 260 261 // GroupableTableColumnModel columnModel = 262 // (GroupableTableColumnModel)getColumnModel(); 263 // Object value = columnModel.getColumn(index).getHeaderValue(); 264 // System.out.println("value.toString():" + value.toString()); 265 266 Object value = null; 267 GroupableTableColumnModel columnModel = (GroupableTableColumnModel) getColumnModel(); 268 TableColumn aColumn = columnModel.getColumn(index); 269 Iterator<ColumnGroup> iter = columnModel.getColumnGroups(aColumn); 270 if (iter != null) { 271 // FIXME get rid of loop, only return appropriate thing 272 while (iter.hasNext()) { 273 ColumnGroup cGroup = iter.next(); 274 value = cGroup.getHeaderValue(); 275 if (wrmdefaults.containsName(value.toString())) { 276 value = ""; 277 } 278 } 279 } 280 281 boolean isSelected = true; 282 int row = HEADER_ROW; 283 JTable table = getTable(); 284 285 Component comp = editor.getTableCellEditorComponent(table, value, 286 isSelected, row, index); 287 // Component comp = editor.getTableCellEditorComponent(table, value, 288 // isSelected, row, wrmdefaultsRealColumnIndex); 289 // if (comp instanceof JComponent) { 290 // ((JComponent) comp).setNextFocusableComponent(this); //deprecated as 291 // of 1.4 292 // } 293 return comp; 294 } 295 296}