001/** 002 * '$Author: welker $' 003 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 004 * '$Revision: 24234 $' 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.Dimension; 030import java.util.Iterator; 031import java.util.Vector; 032 033import javax.swing.DefaultCellEditor; 034import javax.swing.JLabel; 035import javax.swing.JTable; 036import javax.swing.JTextField; 037import javax.swing.UIManager; 038import javax.swing.table.DefaultTableCellRenderer; 039import javax.swing.table.JTableHeader; 040import javax.swing.table.TableCellEditor; 041import javax.swing.table.TableCellRenderer; 042import javax.swing.table.TableColumn; 043 044/** 045 * ColumnGroup, GroupableTableColumnModel, GroupableTableHeader, 046 * GroupableTableHeaderUI and GroupableTableCellRenderer taken from a post by 047 * Steve Webb (16/09/04). He extended code originally posted by Nobuo Tamemasa. 048 * Many thanks to both authors. I've made some changes, including making the 049 * headers editable. 050 * 051 */ 052 053public class ColumnGroup extends TableColumn { 054 /** 055 * Cell renderer for group header. 056 */ 057 protected TableCellRenderer renderer; 058 /** 059 * Holds the TableColumn or ColumnGroup objects contained within this 060 * ColumnGroup instance. 061 */ 062 protected Vector<Object> v; 063 /** 064 * The ColumnGroup instance name. 065 */ 066 // protected String text; 067 068 /** The ColumnGroup header object of the column. */ 069 protected Object cgHeaderObject; 070 071 /** 072 * The margin to use for rendering. 073 */ 074 protected int margin = 0; 075 076 protected TableCellEditor headerEditor; 077 protected boolean isHeaderEditable; 078 079 protected boolean isVisible = true; 080 081 /** 082 * Standard ColumnGroup constructor. 083 * 084 * @param text 085 * Name of the ColumnGroup which will be displayed when the 086 * ColumnGroup is rendered. 087 */ 088 // public ColumnGroup(String text) { 089 // this(null, text); 090 // this(null, null, text); 091 // } 092 093 /** 094 * Standard ColumnGroup constructor. 095 * 096 * @param renderer 097 * a TableCellRenderer for the group. 098 * @param text 099 * Name of the ColumnGroup which will be displayed when the 100 * ColumnGroup is rendered. 101 */ 102 public ColumnGroup(TableCellRenderer renderer, TableCellEditor tce, 103 Object cgHeaderObject) { 104 105 // editor stuff: 106 setHeaderEditor(tce); 107 // setHeaderEditor(createDefaultHeaderEditor()); 108 isHeaderEditable = true; 109 110 if (renderer == null) { 111 this.renderer = new DefaultTableCellRenderer() { 112 public Component getTableCellRendererComponent(JTable table, 113 Object value, boolean isSelected, boolean hasFocus, 114 int row, int column) { 115 JTableHeader header = table.getTableHeader(); 116 117 if (header != null) { 118 setForeground(header.getForeground()); 119 setBackground(header.getBackground()); 120 setFont(header.getFont()); 121 } 122 setHorizontalAlignment(JLabel.CENTER); 123 setText((value == null) ? "" : value.toString()); 124 setBorder(UIManager.getBorder("TableHeader.cellBorder")); 125 // System.out.println("inside ColumnGroup.java ColumnGroup(renderer, text). 126 // renderer was null, now renderer: a DefaultTableCellRender"); 127 return this; 128 } 129 }; 130 } else { 131 this.renderer = renderer; 132 // System.out.println("inside ColumnGroup.java ColumnGroup(renderer, text). 133 // renderer was NOT null, now renderer:" 134 // + this.renderer.toString()); 135 136 } 137 this.cgHeaderObject = cgHeaderObject; 138 v = new Vector<Object>(); 139 } 140 141 /** 142 * Add a TableColumn or ColumnGroup object to the ColumnGroup instance. 143 * 144 * @param obj 145 * TableColumn or ColumnGroup 146 */ 147 public void add(Object obj) { 148 if (obj == null) { 149 return; 150 } 151 v.addElement(obj); 152 } 153 154 /** 155 * Get the ColumnGroup list containing the required table column. 156 * 157 * @param g 158 * vector to populate with the ColumnGroup/s 159 * @param c 160 * TableColumn 161 * @return Vector containing the ColumnGroup/s 162 */ 163 public Vector<ColumnGroup> getColumnGroups(TableColumn c, Vector<ColumnGroup> g) { 164 g.addElement(this); 165 if (v.contains(c)) { 166 return g; 167 } 168 Iterator<Object> iter = v.iterator(); 169 while (iter.hasNext()) { 170 Object obj = iter.next(); 171 if (obj instanceof ColumnGroup) { 172 Vector<ColumnGroup> groups = (Vector<ColumnGroup>) ((ColumnGroup) obj).getColumnGroups(c, 173 (Vector<ColumnGroup>) g.clone()); 174 if (groups != null) { 175 return groups; 176 } 177 } 178 } 179 return null; 180 } 181 182 /** 183 * Returns the TableCellRenderer for the ColumnGroup. 184 * 185 * @return the TableCellRenderer 186 */ 187 public TableCellRenderer getHeaderRenderer() { 188 return renderer; 189 } 190 191 /** 192 * Set the TableCellRenderer for this ColumnGroup. 193 * 194 * @param renderer 195 * the renderer to use 196 */ 197 public void setHeaderRenderer(TableCellRenderer renderer) { 198 if (renderer != null) { 199 this.renderer = renderer; 200 } 201 } 202 203 /** 204 * Get the ColumnGroup header object. 205 * 206 * @return cgHeaderObject. 207 */ 208 public Object getHeaderValue() { 209 return cgHeaderObject; 210 } 211 212 // TODO fix to only set the right one 213 public void setHeaderValue(Object cgHeaderObject) { 214 this.cgHeaderObject = cgHeaderObject; 215 } 216 217 // public void setHeaderValue(Object cgHeaderValue) { 218 // Object old = this.cgHeaderValue; 219 // this.cgHeaderValue = cgHeaderValue; 220 // firePropertyChange("cgHeaderValue", old, cgHeaderValue); 221 // } 222 223 /** 224 * Get the dimension of this ColumnGroup. 225 * 226 * @param table 227 * the table the header is being rendered in 228 * @return the dimension of the ColumnGroup 229 */ 230 public Dimension getSize(JTable table) { 231 232 // Component comp = renderer.getTableCellRendererComponent(table, 233 // getHeaderValue(), false, false, -1, -1); 234 // int height = comp.getPreferredSize().height; 235 // FIXME TODO hardcode, temporary...trying to remove all calls to 236 // getTableCellRendererComponent with -1 for col. 237 int height = 17; 238 // System.out.println("derik debug. ColumnGroup getSize. height:" + 239 // height); 240 int width = 0; 241 Iterator<Object> iter = v.iterator(); 242 while (iter.hasNext()) { 243 Object obj = iter.next(); 244 if (obj instanceof TableColumn) { 245 TableColumn aColumn = (TableColumn) obj; 246 width += aColumn.getWidth(); 247 } else { 248 width += ((ColumnGroup) obj).getSize(table).width; 249 } 250 } 251 return new Dimension(width, height); 252 } 253 254 /** 255 * Sets the margin that ColumnGroup instance will use and all held 256 * TableColumns and/or ColumnGroups. 257 * 258 * @param margin 259 * the margin 260 */ 261 public void setColumnMargin(int margin) { 262 this.margin = margin; 263 Iterator<Object> iter = v.iterator(); 264 while (iter.hasNext()) { 265 Object obj = iter.next(); 266 if (obj instanceof ColumnGroup) { 267 ((ColumnGroup) obj).setColumnMargin(margin); 268 } 269 } 270 } 271 272 public boolean isVisible() { 273 return isVisible; 274 } 275 276 public void setVisible(boolean visible) { 277 isVisible = visible; 278 } 279 280 // methods for editable 281 // 282 public void setHeaderEditor(TableCellEditor headerEditor) { 283 284 this.headerEditor = headerEditor; 285 } 286 287 public TableCellEditor getHeaderEditor() { 288 // FIXME probably need to make a special GroupableTableHeaderCellEditor 289 return headerEditor; 290 } 291 292 public void setHeaderEditable(boolean isEditable) { 293 isHeaderEditable = isEditable; 294 } 295 296 public boolean isHeaderEditable() { 297 return isHeaderEditable; 298 } 299 300 /* 301 * public void copyValues(TableColumn base) { 302 * System.out.println("derik debug. ColumnGroup copyValues start modelIndex:" 303 * +modelIndex); modelIndex = base.getModelIndex(); identifier = 304 * base.getIdentifier(); width = base.getWidth(); minWidth = 305 * base.getMinWidth(); setPreferredWidth(base.getPreferredWidth()); maxWidth 306 * = base.getMaxWidth(); headerRenderer = base.getHeaderRenderer(); 307 * headerValue = base.getHeaderValue(); cellRenderer = 308 * base.getCellRenderer(); cellEditor = base.getCellEditor(); isResizable = 309 * base.getResizable(); 310 * System.out.println("derik debug. ColumnGroup copyValues end modelIndex:" 311 * +modelIndex); } 312 */ 313 314 protected TableCellEditor createDefaultHeaderEditor() { 315 DefaultCellEditor dce = new DefaultCellEditor(new JTextField()); 316 return dce; 317 } 318 319}