001/**
002 *  '$Author: barseghian $'
003 *  '$Date: 2010-12-23 00:33:45 +0000 (Thu, 23 Dec 2010) $'
004 *  '$Revision: 26597 $'
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.util.Map;
030
031import javax.swing.JLabel;
032import javax.swing.JTable;
033import javax.swing.table.TableCellRenderer;
034
035import org.kepler.util.WorkflowRun;
036import org.kepler.workflowrunmanager.WRMDefaults;
037
038import util.TableSorter;
039
040// This renderer extends a component. It is used each time a
041// cell must be displayed.
042public class DurationCellRenderer extends JLabel implements TableCellRenderer {
043        // This method is called each time a cell in a column
044        // using this renderer needs to be rendered.
045
046        public DurationCellRenderer() {
047                setOpaque(true);
048        }
049
050        static final int NUM_SECONDS_IN_HOUR = 3600;
051        static final int NUM_SECONDS_IN_MINUTE = 60;
052        // special case for sub-second, display: "<1s":
053        static final String LESS_THAN_ONE_SECOND = "<1s";
054        // -1 seconds denotes special case for still running, display "running...":
055        static final String STILL_RUNNING = "running...";
056        private TableSorter ts = null;
057        private WorkflowRunManagerTableModel wrmtm = null;
058        private int modelRowIndex;
059        private Long lseconds;
060        private Integer seconds;
061        private Integer hours;
062        private Integer minutes;
063        private String hoursString;
064        private String minutesString;
065        private String secondsString;
066
067        public Component getTableCellRendererComponent(JTable table, Object value,
068                        boolean isSelected, boolean hasFocus, int rowIndex, int vColIndex) {
069                // 'value' is value contained in the cell located at
070                // (rowIndex, vColIndex)
071
072                setFont(WRMDefaults.WRM_FONT);
073
074                if (isSelected) {
075                        // cell (and perhaps other cells) are selected
076                        setBackground(table.getSelectionBackground());
077                        setForeground(table.getSelectionForeground());
078                } else {
079                        setBackground(table.getBackground());
080                        setForeground(table.getForeground());
081                }
082                setSpecialBackgroundIfNecessary(table, rowIndex, isSelected);
083
084                // if (hasFocus) {
085                // this cell is the anchor and the table has the focus
086                // this.setBackground(table.getSelectionBackground());
087                // }
088
089                // Configure the component with the specified value
090
091                // the value is in seconds. format it to HH:mm:ss
092                lseconds = (Long) value;
093                seconds = lseconds.intValue();
094                hours = 0;
095                minutes = 0;
096                if (seconds > NUM_SECONDS_IN_HOUR) {
097                        hours = seconds / NUM_SECONDS_IN_HOUR;
098                        seconds = seconds - (hours * NUM_SECONDS_IN_HOUR);
099                }
100                if (seconds > NUM_SECONDS_IN_MINUTE) {
101                        minutes = seconds / NUM_SECONDS_IN_MINUTE;
102                        seconds = seconds - (minutes * NUM_SECONDS_IN_MINUTE);
103                }
104
105                hoursString = hours.toString();
106                minutesString = minutes.toString();
107                secondsString = seconds.toString();
108                if (hours < 10) {
109                        hoursString = "0" + hoursString;
110                }
111                if (minutes < 10) {
112                        minutesString = "0" + minutesString;
113                }
114                if (seconds < 10) {
115                        secondsString = "0" + secondsString;
116                }
117                if (seconds < 0) {
118                        setText(STILL_RUNNING);
119                } else {
120                        setText(hoursString + ":" + minutesString + ":" + secondsString);
121                }
122                if ((hours == 0) && (minutes == 0) && (seconds == 0)) {
123                        setText(LESS_THAN_ONE_SECOND);
124                }
125
126                setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
127
128                // Set tool tip if desired
129                // setToolTipText((String)value);
130
131                // Since the renderer is a component, return itself
132                return this;
133        }
134
135        private void setSpecialBackgroundIfNecessary(JTable table, int rowIndex,
136                        boolean isSelected) {
137                // paint cells in run rows with non-empty error msgs red.
138                // if not an error run, but an imported run, also paint special color
139                // TODO better way? i'm guessing this is very expensive:
140                ts = (TableSorter) table.getModel();
141                wrmtm = (WorkflowRunManagerTableModel) ts.getTableModel();
142                modelRowIndex = ts.modelIndex(rowIndex);
143                WorkflowRun wr = wrmtm.getWorkflowRunForRow(modelRowIndex);
144                Map<Integer,String> errs = wr.getErrorMessages();
145                String type = wr.getType();
146                
147                //reset foreground in case it's changed
148                setForeground(table.getForeground());
149                
150                if (!errs.isEmpty()) {
151                        if (isSelected) {
152                                setBackground(WRMDefaults.ERROR_ROW_SELECTED_COLOR);
153                        } else {
154                                setBackground(WRMDefaults.ERROR_ROW_COLOR);
155                        }
156                }
157                else if (type.equals(WorkflowRun.type.Imported.toString())) {
158                        if (isSelected) {
159                                setBackground(WRMDefaults.IMPORTED_ROW_SELECTED_COLOR);
160                        } else {
161                                setBackground(WRMDefaults.IMPORTED_ROW_COLOR);
162                        }
163                }
164                
165                if (type.equals(WorkflowRun.type.Preview.toString()) ||
166                        type.equals(WorkflowRun.type.Preview_Error.toString())) {
167                        if (!isSelected){
168                                setForeground(WRMDefaults.PREVIEW_TEXT_COLOR);
169                        }
170                }
171                
172        }
173
174        // The following methods override the defaults for performance reasons
175        public void validate() {
176        }
177
178        public void revalidate() {
179        }
180
181        protected void firePropertyChange(String propertyName, Object oldValue,
182                        Object newValue) {
183        }
184
185        public void firePropertyChange(String propertyName, boolean oldValue,
186                        boolean newValue) {
187        }
188}