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 */
021package csheets.ui.sheet;
022
023import java.awt.Color;
024import java.awt.Component;
025import java.awt.Graphics;
026import java.text.Format;
027import java.util.LinkedList;
028
029import javax.swing.JTable;
030import javax.swing.table.DefaultTableCellRenderer;
031
032import csheets.core.Cell;
033import csheets.core.IllegalValueTypeException;
034import csheets.core.Value;
035import csheets.ext.style.StylableCell;
036import csheets.ext.style.StyleExtension;
037import csheets.ui.ctrl.UIController;
038import csheets.ui.ext.CellDecorator;
039import csheets.ui.ext.UIExtension;
040
041/**
042 * The renderer used for cells in a spreadsheet.
043 * @author Einar Pehrson
044 */
045@SuppressWarnings("serial")
046public 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}