KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > lucane > applications > rssreader > gui > ItemComponent


1 /*
2  * Lucane - a collaborative platform
3  * Copyright (C) 2004 Vincent Fiack <vfiack@mail15.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19  
20 /*
21  * Based on HotSheet ItemListCellRenderer.java by John Munsh
22  */

23 package org.lucane.applications.rssreader.gui;
24
25 import java.awt.*;
26 import java.awt.font.*;
27 import java.awt.geom.*;
28 import java.text.*;
29
30 import javax.swing.border.Border JavaDoc;
31 import javax.swing.ImageIcon JavaDoc;
32 import javax.swing.UIManager JavaDoc;
33
34 import org.jperdian.rss2.dom.RssItem;
35
36
37 class ItemComponent extends Component
38 {
39     protected RssItem item;
40     protected boolean isSelected, hasFocus, isViewed;
41     protected int score;
42     
43     private final int margin = 8;
44     private final int height = 100;
45     private final int maxIconWidth = 140;
46     private final int maxIconHeight = height - (margin * 2);
47     
48     
49     ItemComponent(RssItem item, boolean isSelected, boolean hasFocus,
50         boolean isViewed, int score) {
51
52         this.item = item;
53         this.isSelected = isSelected;
54         this.hasFocus = hasFocus;
55         this.isViewed = isViewed;
56         score = score > 100 ? 100 : score;
57         this.score = score < 0 ? 0 : score;
58         
59         if (isSelected)
60             setBackground(UIManager.getColor("List.selectionBackground"));
61         else
62             setBackground(UIManager.getColor("List.background"));
63     }
64
65     ////////////////////////////////////////////////////////////////////////////
66
// Helper Functions
67
////////////////////////////////////////////////////////////////////////////
68

69     /**
70      * Calculates any scaling and/or translations that may need to be done to a
71      * given image in order to display it centered within an area of the given
72      * size.
73      */

74     protected AffineTransform createTransforms(Image image, Dimension dimension) {
75         int imageHeight = image.getHeight(null);
76         int imageWidth = image.getWidth(null);
77         AffineTransform returnValue = new AffineTransform();
78
79         if ((imageHeight > dimension.getHeight()) || (imageWidth > dimension.getWidth()))
80         {
81
82             // Scaling will be necessary.
83
double scaleFactor = Math.min(dimension.getHeight() / imageHeight,
84                 dimension.getWidth() / imageWidth);
85             
86             // Concatenate a scaling transform on.
87
AffineTransform temp = new AffineTransform();
88             temp.setToScale(scaleFactor, scaleFactor);
89             returnValue.concatenate(temp);
90             
91             // Recalculate the image height and width based on the scale factor.
92
// We need to do this because we might need to horizontally or
93
// vertically center the image.
94
imageHeight *= scaleFactor;
95             imageWidth *= scaleFactor;
96         }
97         
98         // Note that it is possible to need both scaling and centering so we
99
// always do our scaling first and then after we know our final
100
// dimensions for the image we do our centering.
101
if ((imageHeight < dimension.getHeight()) || (imageWidth < dimension.getWidth()))
102         {
103             // Centering will be necessary.
104
AffineTransform temp = new AffineTransform();
105             temp.setToTranslation((dimension.getWidth() - imageWidth) /
106                 2, (dimension.getHeight() - imageHeight) / 2);
107             returnValue.concatenate(temp);
108         }
109         
110         return returnValue;
111     }
112
113     public void paint(Graphics g)
114     {
115         float curY;
116         int textMargin = maxIconWidth + (margin * 2);
117
118         Graphics2D g2 = (Graphics2D) g;
119
120         g2.setBackground(getBackground());
121         g2.clearRect(0, 0, getWidth(), getHeight());
122         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
123         g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
124
125         if (hasFocus)
126             paintFocusBorder(g2);
127
128         boolean hasIcon = paintChannelIcon(g2);
129         if(! hasIcon)
130             textMargin = margin;
131         
132         curY = paintTitle(g2, textMargin);
133         paintDescription(g2, textMargin, curY);
134         paintScore(g2);
135             
136         g2.setColor(Color.lightGray);
137         g2.fillRect(0, getHeight() - 3, getWidth(), getHeight());
138
139         // If the item has already been viewed, draw a film over the whole
140
// item to render it much subtler.
141
if (isViewed)
142             paintFog(g2);
143     }
144
145     private void paintFocusBorder(Graphics2D g2)
146     {
147         Border JavaDoc focusBorder = UIManager.getBorder("List.focusCellHighlightBorder");
148         focusBorder.paintBorder(this, g2, 0, 0, getWidth(), getHeight());
149     }
150
151     private void paintDescription(Graphics2D g2, int textMargin, float curY)
152     {
153          String JavaDoc description = item.getStrippedDescription();
154          if(description.length() == 0)
155              return;
156             
157          Font smallFont = g2.getFont().deriveFont(Font.PLAIN, 10.0f);
158          float wrappingWidth = getWidth() - textMargin;
159
160          description = description.replace('\n', ' ');
161          AttributedString str = new AttributedString(description);
162          str.addAttribute(TextAttribute.FONT, smallFont);
163          AttributedCharacterIterator strIterator = str.getIterator();
164          FontRenderContext fontRenderContext = new FontRenderContext(null, false, false);
165          LineBreakMeasurer measurer = new LineBreakMeasurer(strIterator, fontRenderContext);
166
167          while (measurer.getPosition() < strIterator.getEndIndex())
168          {
169              TextLayout layout = measurer.nextLayout(wrappingWidth);
170
171              // Adjust current elevation.
172
curY += Math.floor(layout.getAscent());
173
174              Point2D.Float penPosition = new Point2D.Float(textMargin, curY);
175              layout.draw(g2, penPosition.x, penPosition.y);
176
177              // Move to next line.
178
curY += layout.getDescent() + layout.getLeading();
179
180              // If we've done enough lines to fill the printable area, don't
181
// bother getting more.
182
if (curY >= getHeight()-3)
183                  break;
184          }
185     }
186
187     private float paintTitle(Graphics2D g2, int textMargin)
188     {
189         float curY = margin;
190
191         String JavaDoc title = item.getTitle().trim();
192         if(title.length() == 0)
193             return curY;
194
195         g2.setColor(Color.black);
196         Font currentFont = g2.getFont();
197         Font boldFont = currentFont.deriveFont(Font.BOLD);
198         float wrappingWidth = getWidth() - textMargin;
199
200         AttributedString str = new AttributedString(title);
201         str.addAttribute(TextAttribute.FONT, boldFont);
202         AttributedCharacterIterator strIterator = str.getIterator();
203         FontRenderContext fontRenderContext = new FontRenderContext(null, false, false);
204         LineBreakMeasurer measurer = new LineBreakMeasurer(strIterator, fontRenderContext);
205
206         while (measurer.getPosition() < strIterator.getEndIndex())
207         {
208             TextLayout layout = measurer.nextLayout(wrappingWidth);
209             curY += Math.floor(layout.getAscent());
210             Point2D.Float penPosition = new Point2D.Float(textMargin, curY);
211             layout.draw(g2, penPosition.x, penPosition.y);
212             curY += layout.getDescent() + layout.getLeading();
213             if (curY >= getHeight()-3)
214                     break;
215         }
216
217         return curY;
218     }
219
220     private boolean paintChannelIcon(Graphics2D g2)
221     {
222         // Draw the icon for the channel of the item.
223
ImageIcon JavaDoc imageIcon = null;
224         try {
225             imageIcon = new ImageIcon JavaDoc(item.getSource().getImage().getURL());
226         } catch(Exception JavaDoc e) {}
227         
228         if(imageIcon == null)
229             return false;
230
231         // Create the scaling transformation needed to ensure that the
232
// graphic associated with this channel will fit in the space
233
// set aside for it.
234
AffineTransform transform = createTransforms(imageIcon.getImage(),
235             new Dimension(maxIconWidth, maxIconHeight));
236
237         // Now that we have our scaling transformation, create another
238
// transform to perform translation (i.e. shift the position of
239
// the image) and append the two translations to each other.
240
AffineTransform temp = new AffineTransform();
241         temp.setToTranslation(margin, margin);
242         transform.concatenate(temp);
243         
244         // Draw the image, applying the transformations to scale and
245
// translate it appropriately.
246
g2.drawImage(imageIcon.getImage(), transform, null);
247         return true;
248     }
249
250     private void paintFog(Graphics2D g2)
251     {
252         AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f);
253         g2.setComposite(ac);
254
255         // The background color is what we use to ghost the item.
256
g2.setColor(getBackground());
257         g2.fillRect(0, 0, getWidth(), getHeight());
258     }
259
260     private void paintScore(Graphics2D g2)
261     {
262         int mod = 255 - ((score - 50) * 5);
263
264         if (score > 50)
265             g2.setColor(new Color(255, mod, mod));
266         else if (score < 50)
267             g2.setColor(new Color(mod, mod, 255));
268
269         g2.fillRect(0, 0, margin / 2, getHeight());
270     }
271
272     public Dimension getPreferredSize() {
273         return (new Dimension(300, height));
274     }
275 }
Popular Tags