1 /* 2 * aTunes 3 * Copyright (C) Alex Aranda, Sylvain Gaudard and contributors 4 * 5 * See http://www.atunes.org/wiki/index.php?title=Contributing for information about contributors 6 * 7 * http://www.atunes.org 8 * http://sourceforge.net/projects/atunes 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License 12 * as published by the Free Software Foundation; either version 2 13 * of the License, or (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 */ 20 21 package net.sourceforge.atunes.gui; 22 23 import javax.swing.ImageIcon; 24 import javax.swing.JTable; 25 import javax.swing.event.TableModelEvent; 26 import javax.swing.table.DefaultTableColumnModel; 27 import javax.swing.table.TableCellEditor; 28 import javax.swing.table.TableCellRenderer; 29 import javax.swing.table.TableColumn; 30 31 import net.sourceforge.atunes.model.AudioObjectProperty; 32 import net.sourceforge.atunes.model.IBeanFactory; 33 import net.sourceforge.atunes.model.IColorMutableImageIcon; 34 import net.sourceforge.atunes.model.IColumn; 35 import net.sourceforge.atunes.model.IColumnModel; 36 import net.sourceforge.atunes.model.IColumnSet; 37 import net.sourceforge.atunes.model.ILookAndFeel; 38 import net.sourceforge.atunes.model.ILookAndFeelManager; 39 import net.sourceforge.atunes.model.ITableCellRendererCode; 40 import net.sourceforge.atunes.model.PlaybackState; 41 import net.sourceforge.atunes.utils.StringUtils; 42 43 /** 44 * Common column model for tables 45 * 46 * @author alex 47 * 48 */ 49 public abstract class AbstractCommonColumnModel extends DefaultTableColumnModel 50 implements IColumnModel { 51 52 private static final long serialVersionUID = -8202322203076350708L; 53 /** The table. */ 54 private JTable table; 55 /** Column set */ 56 private IColumnSet columnSet; 57 /** The model. */ 58 private AbstractCommonTableModel model; 59 /** The column being moved. */ 60 private int columnBeingMoved = -1; 61 /** The column moved to. */ 62 private int columnMovedTo = -1; 63 private ColumnMoveListener columnMoveListener; 64 private ColumnModelListener columnModelListener; 65 66 private ILookAndFeelManager lookAndFeelManager; 67 68 private IBeanFactory beanFactory; 69 getBeanFactory()70 protected final IBeanFactory getBeanFactory() { 71 return this.beanFactory; 72 } 73 74 /** 75 * @param beanFactory 76 */ setBeanFactory(final IBeanFactory beanFactory)77 public void setBeanFactory(final IBeanFactory beanFactory) { 78 this.beanFactory = beanFactory; 79 } 80 81 /** 82 * @param lookAndFeelManager 83 */ setLookAndFeelManager( final ILookAndFeelManager lookAndFeelManager)84 public void setLookAndFeelManager( 85 final ILookAndFeelManager lookAndFeelManager) { 86 this.lookAndFeelManager = lookAndFeelManager; 87 } 88 89 /** 90 * @param table 91 */ setTable(final JTable table)92 public void setTable(final JTable table) { 93 this.table = table; 94 } 95 96 /** 97 * @param model 98 */ setModel(final AbstractCommonTableModel model)99 public void setModel(final AbstractCommonTableModel model) { 100 this.model = model; 101 } 102 getLookAndFeel()103 protected final ILookAndFeel getLookAndFeel() { 104 return this.lookAndFeelManager.getCurrentLookAndFeel(); 105 } 106 107 /** 108 * Return column for x position. 109 * 110 * @param x 111 * the x 112 * 113 * @return the column index at position 114 */ getColumnIndexAtPosition(final int x)115 public final int getColumnIndexAtPosition(final int x) { 116 int computedX = x; 117 if (computedX < 0) { 118 return -1; 119 } 120 121 for (int column = 0; column < getColumnCount(); column++) { 122 computedX = computedX - getColumn(column).getPreferredWidth(); 123 if (computedX < 0) { 124 return column; 125 } 126 } 127 128 return -1; 129 } 130 131 /** 132 * Updates columns width. 133 */ updateColumnWidth()134 protected final void updateColumnWidth() { 135 for (int i = 0; i < getColumnCount(); i++) { 136 Class<? extends IColumn<?>> col = getColumnId(i); 137 int width = getColumn(i).getPreferredWidth(); 138 setWidthForColumn(col, width); 139 } 140 } 141 142 /** 143 * Sets width for a column. 144 * 145 * @param c 146 * the c 147 * @param width 148 * the width 149 */ setWidthForColumn(final Class<? extends IColumn<?>> c, final int width)150 private final void setWidthForColumn(final Class<? extends IColumn<?>> c, 151 final int width) { 152 getColumn(c).setWidth(width); 153 } 154 155 /** 156 * Arrange columns. 157 * 158 * @param reapplyFilter 159 * the reapply filter 160 */ 161 @Override arrangeColumns(final boolean reapplyFilter)162 public final void arrangeColumns(final boolean reapplyFilter) { 163 setCurrentColumns(); 164 this.model.refresh(TableModelEvent.UPDATE); 165 if (reapplyFilter) { 166 reapplyFilter(); 167 } 168 } 169 170 /** 171 * Return Column object for a given column number. 172 * 173 * @param column 174 * the column 175 * 176 * @return the column 177 */ getColumnObject(final int column)178 public final IColumn<?> getColumnObject(final int column) { 179 return getColumn(getColumnId(column)); 180 } 181 182 /** 183 * Returns class of column given by index 184 * 185 * @param index 186 * @return 187 */ getColumnId(final int index)188 private final Class<? extends IColumn<?>> getColumnId(final int index) { 189 return this.columnSet.getColumnId(index); 190 } 191 192 /** 193 * Returns a column object given its class 194 * 195 * @param columnClass 196 * @return 197 */ getColumn( final Class<? extends IColumn<?>> columnClass)198 private final IColumn<?> getColumn( 199 final Class<? extends IColumn<?>> columnClass) { 200 return this.columnSet.getColumn(columnClass); 201 } 202 203 /** 204 * Returns alignment of current column 205 * 206 * @param column 207 * @return 208 */ getColumnAlignment(final int column)209 public int getColumnAlignment(final int column) { 210 return getColumn(getColumnId(column)).getAlignment(); 211 } 212 213 /** 214 * Initializes columns 215 */ setCurrentColumns()216 private void setCurrentColumns() { 217 this.columnSet.setCurrentColumns(); 218 } 219 getColumnMoveListener()220 private ColumnMoveListener getColumnMoveListener() { 221 if (this.columnMoveListener == null) { 222 this.columnMoveListener = new ColumnMoveListener(this); 223 } 224 return this.columnMoveListener; 225 } 226 getColumnModelListener()227 private ColumnModelListener getColumnModelListener() { 228 if (this.columnModelListener == null) { 229 this.columnModelListener = new ColumnModelListener(this, 230 this.beanFactory); 231 } 232 return this.columnModelListener; 233 } 234 235 /** 236 * Allows user to move columns 237 * 238 * @param enable 239 */ enableColumnChange(final boolean enable)240 public void enableColumnChange(final boolean enable) { 241 this.table.getTableHeader().setReorderingAllowed(enable); 242 if (enable) { 243 // Add listener for column size changes 244 addColumnModelListener(getColumnModelListener()); 245 this.table.getTableHeader().addMouseListener( 246 getColumnMoveListener()); 247 } else { 248 removeColumnModelListener(getColumnModelListener()); 249 this.table.getTableHeader().removeMouseListener( 250 getColumnMoveListener()); 251 } 252 } 253 254 /** 255 * Apply filter 256 */ reapplyFilter()257 protected abstract void reapplyFilter(); 258 259 /** 260 * Updates a column according to settings from column set 261 * 262 * @param aColumn 263 */ updateColumnSettings(final TableColumn aColumn)264 protected void updateColumnSettings(final TableColumn aColumn) { 265 // Get column data 266 IColumn<?> column = getColumnObject(aColumn.getModelIndex()); 267 268 // Set width 269 aColumn.setPreferredWidth(column.getWidth()); 270 aColumn.setWidth(column.getWidth()); 271 272 // Set resizable 273 aColumn.setResizable(column.isResizable()); 274 275 // If has cell editor, set cell editor 276 TableCellEditor cellEditor = column.getCellEditor(); 277 if (cellEditor != null) { 278 aColumn.setCellEditor(cellEditor); 279 } 280 281 // If has renderer, set cell renderer 282 TableCellRenderer cellRenderer = column.getCellRenderer(); 283 if (cellRenderer != null) { 284 aColumn.setCellRenderer(cellRenderer); 285 } 286 } 287 288 /** 289 * @return the columnSet 290 */ 291 @Override getColumnSet()292 public IColumnSet getColumnSet() { 293 return this.columnSet; 294 } 295 296 /** 297 * @param columnSet 298 * the columnSet to set 299 */ setColumnSet(final IColumnSet columnSet)300 public void setColumnSet(final IColumnSet columnSet) { 301 this.columnSet = columnSet; 302 } 303 304 /** 305 * Returns renderer code for given class 306 * 307 * @param clazz 308 * @return 309 */ getRendererCodeFor(final Class<?> clazz)310 public ITableCellRendererCode<?, ?> getRendererCodeFor(final Class<?> clazz) { 311 AbstractTableCellRendererCode<?, ?> renderer = null; 312 if (clazz.equals(PlaybackState.class)) { 313 renderer = this.beanFactory 314 .getBean(PlaybackStateTableCellRendererCode.class); 315 } else if (clazz.equals(Integer.class)) { 316 renderer = this.beanFactory 317 .getBean(IntegerTableCellRendererCode.class); 318 } else if (clazz.equals(ImageIcon.class)) { 319 renderer = this.beanFactory 320 .getBean(ImageIconTableCellRendererCode.class); 321 } else if (clazz.equals(String.class)) { 322 renderer = this.beanFactory.getBean("stringTableCellRendererCode", 323 StringTableCellRendererCode.class); 324 } else if (clazz.equals(TextAndIcon.class)) { 325 renderer = this.beanFactory 326 .getBean(TextAndIconTableCellRendererCode.class); 327 } else if (clazz.equals(AudioObjectProperty.class)) { 328 renderer = this.beanFactory 329 .getBean(PropertyTableCellRendererCode.class); 330 } else if (clazz.equals(IColorMutableImageIcon.class)) { 331 renderer = this.beanFactory 332 .getBean(ColorMutableTableCellRendererCode.class); 333 } else { 334 throw new IllegalArgumentException(StringUtils.getString( 335 "No renderer found for class: ", clazz.getName())); 336 } 337 return renderer; 338 } 339 340 /** 341 * @return the table 342 */ getTable()343 protected JTable getTable() { 344 return this.table; 345 } 346 347 /** 348 * @param columnBeingMoved 349 */ setColumnBeingMoved(int columnBeingMoved)350 protected void setColumnBeingMoved(int columnBeingMoved) { 351 this.columnBeingMoved = columnBeingMoved; 352 } 353 354 /** 355 * @param columnMovedTo 356 */ setColumnMovedTo(int columnMovedTo)357 protected void setColumnMovedTo(int columnMovedTo) { 358 this.columnMovedTo = columnMovedTo; 359 } 360 361 /** 362 * @return 363 */ getColumnBeingMoved()364 protected int getColumnBeingMoved() { 365 return columnBeingMoved; 366 } 367 368 /** 369 * @return 370 */ getColumnMovedTo()371 protected int getColumnMovedTo() { 372 return columnMovedTo; 373 } 374 375 } 376