001    /*
002     * Copyright (c) 2005 Einar Pehrson <einar@pehrson.nu>.
003     *
004     * This file is part of
005     * CleanSheets - a spreadsheet application for the Java platform.
006     *
007     * CleanSheets is free software; you can redistribute it and/or modify
008     * it under the terms of the GNU General Public License as published by
009     * the Free Software Foundation; either version 2 of the License, or
010     * (at your option) any later version.
011     *
012     * CleanSheets is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015     * GNU General Public License for more details.
016     *
017     * You should have received a copy of the GNU General Public License
018     * along with CleanSheets; if not, write to the Free Software
019     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
020     */
021    package csheets.ui.sheet;
022    
023    import java.awt.Color;
024    import java.awt.Component;
025    import java.awt.Graphics;
026    import java.text.Format;
027    import java.util.LinkedList;
028    
029    import javax.swing.JTable;
030    import javax.swing.table.DefaultTableCellRenderer;
031    
032    import csheets.core.Cell;
033    import csheets.core.IllegalValueTypeException;
034    import csheets.core.Value;
035    import csheets.ext.style.StylableCell;
036    import csheets.ext.style.StyleExtension;
037    import csheets.ui.ctrl.UIController;
038    import csheets.ui.ext.CellDecorator;
039    import csheets.ui.ext.UIExtension;
040    
041    /**
042     * The renderer used for cells in a spreadsheet.
043     * @author Einar Pehrson
044     */
045    @SuppressWarnings("serial")
046    public class CellRenderer extends DefaultTableCellRenderer {
047    
048            /** The cell decorators invoked by the renderer */
049            private LinkedList<CellDecorator> decorators = new LinkedList<CellDecorator>();
050    
051            /** The cell currently being rendered */
052            private Cell cell;
053    
054            /** Whether the cell currently being rendered is selected */
055            private boolean selected = false;
056    
057            /** Whether the cell currently being rendered has the focus */
058            private boolean hasFocus = false;
059    
060            /**
061             * Creates a new cell renderer.
062             * @param uiController the user interface controller
063             */
064            public CellRenderer(UIController uiController) {
065                    // Fetches decorators
066                    for (UIExtension extension : uiController.getExtensions()) {
067                            CellDecorator decorator = extension.getCellDecorator();
068                            if (decorator != null)
069                                    decorators.add(decorator);
070                    }
071            }
072    
073            public Component getTableCellRendererComponent(JTable table, Object o,
074                            boolean selected, boolean hasFocus, int row, int column) {
075                    super.getTableCellRendererComponent(table, o, selected, hasFocus, row, column);
076    
077                    // Stores members
078                    this.cell = (Cell)o;
079                    this.selected = selected;
080                    this.hasFocus = hasFocus;
081    
082                    if (cell != null) {
083                            // Fetches style
084                            StylableCell stylableCell = (StylableCell)cell.getExtension(StyleExtension.NAME);
085    
086                            // Applies format and updates text
087                            Value value = cell.getValue();
088                            Format format = stylableCell.getFormat();
089                            setText(format == null ? value.toString() : value.toString(format));
090    
091                            // Applies alignment, font and border
092                            setHorizontalAlignment(stylableCell.getHorizontalAlignment());
093                            setVerticalAlignment(stylableCell.getVerticalAlignment());
094                            setFont(stylableCell.getFont());
095                            setBorder(stylableCell.getBorder());
096    
097                            // Applies color
098                            if (!selected) {
099                                    setBackground(stylableCell.getBackgroundColor());
100                                    if (value.getType() == Value.Type.ERROR)
101                                            setForeground(Color.red);
102                                    else
103                                            setForeground(stylableCell.getForegroundColor());
104                            }
105    
106                            // Applies tool tip
107                            if (value.getType() == Value.Type.ERROR)
108                                    try {
109                                            setToolTipText(value.toError().getMessage());
110                                    } catch (IllegalValueTypeException e) {}
111                            else
112                                    setToolTipText(null);
113                    }
114                    return this;
115            }
116    
117            /**
118             * Overridden to delegate painting to decorators.
119             * @param g the Graphics object to protect
120             */
121        protected void paintComponent(Graphics g) {
122                    super.paintComponent(g);
123    
124                    if (cell != null)
125                            // Invokes decorators
126                            for (CellDecorator decorator : decorators)
127                                    if (decorator.isEnabled())
128                                            decorator.decorate(this, g, cell, selected, hasFocus);
129            }
130    }