View Javadoc
1   package net.logAnalyzer.gui.messages.cellrenderers;
2   
3   import java.awt.Color;
4   import java.awt.Component;
5   import java.awt.Font;
6   import java.awt.GradientPaint;
7   import java.awt.Graphics;
8   import java.awt.Graphics2D;
9   import java.text.NumberFormat;
10  
11  import javax.swing.JLabel;
12  import javax.swing.JTable;
13  import javax.swing.UIManager;
14  import javax.swing.border.Border;
15  import javax.swing.border.EmptyBorder;
16  import javax.swing.table.TableCellRenderer;
17  
18  import net.logAnalyzer.converters.LAConverter;
19  import net.logAnalyzer.gui.messages.MessagesModel;
20  
21  /***
22   * This class defines a cell renderer model displaying an horizontal percentage
23   * bar. The percentage is calculated with a formula to implement in
24   * {@link #computePercentage(Object, Object)} using the rendered cell value and
25   * a specified base converter value.
26   * 
27   * @author Karim REFEYTON
28   * @version 0.1
29   */
30  public abstract class BarRenderer extends JLabel implements TableCellRenderer {
31      private static final long serialVersionUID = 1L;
32  
33      /***
34       * Default border.
35       */
36      public static final Border NOFOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
37  
38      /***
39       * Index of converter used as percentage base value.
40       */
41      private int logconverterBaseIndex;
42  
43      /***
44       * <tt>true</tt> if the percentage is computed; <tt>false</tt> if an
45       * error occured.
46       */
47      private boolean isComputed = false;
48  
49      /***
50       * Calculating percentage to render with the progress bar.
51       */
52      private double percentage;
53  
54      /***
55       * Low color.
56       */
57      private Color colorLow;
58  
59      /***
60       * High color.
61       */
62      private Color colorHigh;
63  
64      /***
65       * Low limit.
66       */
67      private double thresholdLow;
68  
69      /***
70       * High limit.
71       */
72      private double thresholdHigh;
73  
74      /***
75       * Constructs a new renderer calculating on a percentage between the
76       * rendered converter and a base converter values. Renders a progress bar
77       * which width is based on the percentage calculated by
78       * {@link BarRenderer#computePercentage(Object, Object)}<br>
79       * The color of the process bar is deduced from the following check :
80       * <ul>
81       * <li><tt>0 &lt;= percentage &lt;= thresholdLow</tt>: the progress bar
82       * is painted with the colorLow color</li>
83       * <li><tt>thresholdLow &lt; percentage &lt;= thresholdHigh</tt>: the
84       * progess bar is painted with a gradient form colorLow to colorHigh color</li>
85       * <li><tt>thresholdHigh &lt; percentage</tt>: the progress bar is
86       * painted with the colorHigh color</li>
87       * </ul>
88       * 
89       * @param logconverterBase
90       *            Literal of the converter which value is the base of the
91       *            percentage calculation.
92       * @param logconverters
93       *            All the converters, the base converter must be one of them.
94       * @param colorLow
95       *            Low color.
96       * @param thresholdLow
97       *            If <tt>percentage <= thresholdErrorWarn</tt> the color used
98       *            is colorLow.
99       * @param thresholdHigh
100      *            If <tt>percentage > thresholdHigh</tt> the color used is
101      *            colorHigh; otherwise is colorBase.
102      * @param colorHigh
103      *            High color.
104      */
105     public BarRenderer(String logconverterBase, LAConverter[] logconverters,
106             Color colorLow, double thresholdLow, double thresholdHigh,
107             Color colorHigh) {
108         super();
109         this.logconverterBaseIndex = -1;
110         for (int i = 0; i < logconverters.length; i++) {
111             if (logconverters[i].getLiteral().equals(logconverterBase)) {
112                 this.logconverterBaseIndex = i;
113             }
114         }
115         this.colorLow = colorLow;
116         this.thresholdLow = thresholdLow;
117         this.thresholdHigh = thresholdHigh;
118         this.colorHigh = colorHigh;
119         setOpaque(true);
120         Font font = getFont();
121         setFont(font.deriveFont(Font.PLAIN));
122         setHorizontalAlignment(JLabel.RIGHT);
123     }
124 
125     /***
126      * Sets text, height, borders and colors of the cell regarding to value,
127      * selection and focus.
128      * 
129      * @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable,
130      *      java.lang.Object, boolean, boolean, int, int)
131      */
132     public Component getTableCellRendererComponent(JTable table, Object value,
133             boolean isSelected, boolean hasFocus, int row, int converter) {
134         // The percentage is not yet computed
135         isComputed = false;
136         percentage = 0;
137         // Sets the text
138         if (value != null) {
139             setText(value.toString());
140         } else {
141             setText("");
142         }
143         // Looks at the base converter in the table regarding to its data model
144         // index
145         MessagesModel model = (MessagesModel) table.getModel();
146         if (logconverterBaseIndex >= 0) {
147             // Calculates the percentage
148             try {
149                 percentage = computePercentage(value, model.getValueAt(row,
150                         logconverterBaseIndex));
151                 isComputed = true;
152                 // Sets the tooltip whith percentage
153                 setToolTipText(NumberFormat.getPercentInstance().format(
154                         percentage));
155             } catch (NumberFormatException nfe) {
156                 isComputed = true;
157                 setToolTipText(null);
158             }
159         }
160         // Shows the selection and focus
161         if (isSelected) {
162             super.setForeground(table.getSelectionForeground());
163             super.setBackground(table.getSelectionBackground());
164         } else {
165             super.setForeground(table.getForeground());
166             super.setBackground(table.getBackground());
167         }
168         if (hasFocus) {
169             setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
170             if (table.isCellEditable(row, converter)) {
171                 super.setForeground(UIManager
172                         .getColor("Table.focusCellForeground"));
173                 super.setBackground(UIManager
174                         .getColor("Table.focusCellBackground"));
175             }
176         } else {
177             setBorder(NOFOCUS_BORDER);
178         }
179 
180         return this;
181     }
182 
183     /***
184      * Calculates the percentage. Formula is specific and must be implemented by
185      * concrete class.
186      * 
187      * @param value
188      *            Rendered cell value.
189      * @param baseValue
190      *            Base converter value.
191      * @return percentage Used to render the progress bar.
192      */
193     protected abstract double computePercentage(Object value, Object baseValue);
194 
195     /***
196      * Modification to the inherited behavior.
197      * 
198      * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
199      */
200     protected void paintComponent(Graphics g) {
201         super.paintComponent(g);
202         if (isComputed) {
203             Graphics2D g2d = (Graphics2D) g.create();
204             if (isOpaque()) {
205                 // Background must be drawable
206                 g2d.setXORMode(getBackground());
207             }
208             // Creates a paint tool comparing percentage with the thresholds
209             g2d.setPaint(new GradientPaint((float) (getWidth() * thresholdLow),
210                     0F, colorLow, (float) (getWidth() * thresholdHigh), 0F,
211                     colorHigh));
212             g2d.fillRect(0, 0, (int) (getWidth() * percentage), getHeight());
213             g2d.dispose();
214         }
215     }
216 }