001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.welcome.ui;
043:
044: import java.awt.Color;
045: import java.awt.Component;
046: import java.awt.Cursor;
047: import java.awt.Dimension;
048: import java.awt.FontMetrics;
049: import java.awt.Graphics;
050: import java.awt.GridBagConstraints;
051: import java.awt.GridBagLayout;
052: import java.awt.Image;
053: import java.awt.Insets;
054: import java.awt.event.ActionEvent;
055: import java.awt.event.ActionListener;
056: import java.awt.event.MouseEvent;
057: import java.awt.event.MouseListener;
058: import java.io.File;
059: import java.io.FileInputStream;
060: import java.io.FileOutputStream;
061: import java.io.IOException;
062: import java.io.ObjectInputStream;
063: import java.io.ObjectOutputStream;
064: import java.net.MalformedURLException;
065: import java.net.URL;
066: import java.util.logging.Level;
067: import java.util.logging.Logger;
068: import javax.swing.BorderFactory;
069: import javax.swing.Icon;
070: import javax.swing.ImageIcon;
071: import javax.swing.JButton;
072: import javax.swing.JComponent;
073: import javax.swing.JLabel;
074: import javax.swing.JPanel;
075: import javax.swing.JToolTip;
076: import org.netbeans.modules.welcome.content.BundleSupport;
077: import org.netbeans.modules.welcome.content.Constants;
078: import org.netbeans.modules.welcome.content.RSSFeed;
079: import org.netbeans.modules.welcome.content.RSSFeedReaderPanel;
080: import org.netbeans.modules.welcome.content.Utils;
081: import org.netbeans.modules.welcome.content.WebLink;
082: import org.openide.awt.Mnemonics;
083: import org.openide.awt.StatusDisplayer;
084: import org.openide.util.Utilities;
085:
086: /**
087: *
088: * @author S. Aubrecht
089: */
090: class DemoPanel extends RSSFeedReaderPanel {
091:
092: public DemoPanel() {
093: super (BundleSupport.getURL("Demo")); //NOI18N
094:
095: //add( buildBottomContent(), BorderLayout.SOUTH );
096: }
097:
098: @Override
099: protected JComponent buildContent(String url,
100: boolean showProxyButton) {
101: JPanel res = new JPanel(new GridBagLayout());
102: res.setOpaque(false);
103:
104: DemoRSSFeed feed = new DemoRSSFeed(url);
105: res.add(feed, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0,
106: GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
107: new Insets(0, 0, 0, 0), 0, 0));
108: res.add(buildBottomContent(), new GridBagConstraints(0, 1, 1,
109: 1, 0.0, 0.0, GridBagConstraints.NORTHWEST,
110: GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0),
111: 0, 0));
112: res.add(new JLabel(), new GridBagConstraints(0, 2, 1, 1, 0.0,
113: 1.0, GridBagConstraints.CENTER,
114: GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
115:
116: return res;
117: }
118:
119: protected JComponent buildBottomContent() {
120: WebLink allBlogs = new WebLink("AllDemos", false); // NOI18N
121: BundleSupport.setAccessibilityProperties(allBlogs, "AllDemos"); //NOI18N
122:
123: JPanel panel = new JPanel(new GridBagLayout());
124: panel.setOpaque(false);
125: panel.add(allBlogs, new GridBagConstraints(1, 0, 1, 1, 0.0,
126: 0.0, GridBagConstraints.SOUTHEAST,
127: GridBagConstraints.HORIZONTAL, new Insets(5, 5, 0, 5),
128: 0, 0));
129: panel.add(new JLabel(), new GridBagConstraints(0, 0, 1, 1, 1.0,
130: 0.0, GridBagConstraints.CENTER,
131: GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0),
132: 0, 0));
133:
134: return panel;
135: }
136:
137: class DemoRSSFeed extends RSSFeed {
138: public DemoRSSFeed(String url) {
139: super (url, false);
140: }
141:
142: @Override
143: protected Component createFeedItemComponent(FeedItem item) {
144: JPanel panel = new JPanel(new GridBagLayout());
145: panel.setOpaque(false);
146: int row = 0;
147:
148: if (item.isValid()) {
149: WebLink linkButton = new WebLink(item.title, item.link,
150: false);
151: linkButton.getAccessibleContext().setAccessibleName(
152: BundleSupport.getAccessibilityName("WebLink",
153: item.title)); //NOI18N
154: linkButton.getAccessibleContext()
155: .setAccessibleDescription(
156: BundleSupport
157: .getAccessibilityDescription(
158: "WebLink", item.link)); //NOI18N
159: linkButton.setFont(BUTTON_FONT);
160: panel.add(linkButton, new GridBagConstraints(0, row++,
161: 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
162: GridBagConstraints.NONE, new Insets(0, 5, 2,
163: TEXT_INSETS_RIGHT), 0, 0));
164:
165: if (item.enclosureUrl != null) {
166: panel.add(new ImageLabel(item.link,
167: getImage(item.enclosureUrl),
168: item.description), new GridBagConstraints(
169: 0, row++, 1, 1, 0.0, 0.0,
170: GridBagConstraints.CENTER,
171: GridBagConstraints.NONE, new Insets(10, 5,
172: 5, 5), 0, 0));
173: } else {
174: JLabel label = new JLabel(BundleSupport
175: .getLabel("NoScreenShot")); //NOI18N
176: label.setHorizontalAlignment(JLabel.CENTER);
177: label.setVerticalAlignment(JLabel.CENTER);
178: panel.add(label, new GridBagConstraints(0, row++,
179: 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
180: GridBagConstraints.NONE, new Insets(0,
181: TEXT_INSETS_LEFT + 5, 0,
182: TEXT_INSETS_RIGHT), 0, 0));
183: }
184: } else {
185: panel.add(new JLabel(BundleSupport
186: .getLabel("ErrLoadingFeed")), // NOI18N
187: new GridBagConstraints(0, row++, 1, 1, 0.0,
188: 0.0, GridBagConstraints.CENTER,
189: GridBagConstraints.NONE, new Insets(5,
190: 10, 10, 5), 0, 0));
191: JButton button = new JButton();
192: Mnemonics.setLocalizedText(button, BundleSupport
193: .getLabel("Reload")); // NOI18N
194: button.setOpaque(false);
195: button.addActionListener(new ActionListener() {
196: public void actionPerformed(ActionEvent e) {
197: lastReload = 0;
198: reload();
199: }
200: });
201: panel.add(button, new GridBagConstraints(0, row++, 1,
202: 1, 0.0, 0.0, GridBagConstraints.CENTER,
203: GridBagConstraints.NONE, new Insets(5, 10, 10,
204: 5), 0, 0));
205: }
206:
207: return panel;
208: }
209:
210: @Override
211: protected int getMaxItemCount() {
212: return 1;
213: }
214:
215: ImageIcon getImage(String urlString) {
216: URL url = null;
217: try {
218: url = new URL(urlString);
219: } catch (MalformedURLException mfuE) {
220: mfuE.printStackTrace();
221: }
222: ImageIcon image = null;
223: if (isContentCached()) {
224: ObjectInputStream input = null;
225: try {
226: input = new ObjectInputStream(new FileInputStream(
227: getCacheFilePath()));
228: image = (ImageIcon) input.readObject();
229: Logger.getLogger(DemoPanel.class.getName()).log(
230: Level.FINE,
231: "Demo image loaded from: "
232: + getCacheFilePath()); //NOI18N
233: } catch (Exception e) {
234: image = null;
235: } finally {
236: if (null != input)
237: try {
238: input.close();
239: } catch (IOException e) {
240: }
241: }
242: }
243:
244: if (null == image) {
245: image = new ImageIcon(url);
246: ObjectOutputStream output = null;
247: try {
248: output = new ObjectOutputStream(
249: new FileOutputStream(getCacheFilePath()));
250: output.writeObject(image);
251: } catch (Exception e) {
252: Logger
253: .getLogger(DemoPanel.class.getName())
254: .log(
255: Level.FINE,
256: "Error while caching Welcome Page demo image",
257: e); //NOI18N
258: image = new ImageIcon(Utilities
259: .loadImage(Constants.BROKEN_IMAGE));
260: } finally {
261: if (null != output) {
262: try {
263: output.close();
264: } catch (IOException e) {
265: }
266: }
267: }
268: }
269:
270: return image;
271: }
272:
273: private File getCacheFilePath() throws IOException {
274: File cacheStore = Utils.getCacheStore();
275: cacheStore = new File(cacheStore, "demoimage"); //NOI18N
276: cacheStore.getParentFile().mkdirs();
277: cacheStore.createNewFile();
278: return cacheStore;
279: }
280: }
281:
282: private static class ImageLabel extends JLabel implements
283: Constants, MouseListener {
284: private String url;
285: private boolean visited = false;
286:
287: public ImageLabel(String url, ImageIcon img, String description) {
288: super (new MaxSizeImageIcon(img.getImage()));
289: this .url = url;
290: if (null != description)
291: setToolTipText("<html>" + description); //NOI18N
292: setOpaque(false);
293: setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
294: addMouseListener(this );
295: setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
296: }
297:
298: public void mouseClicked(MouseEvent e) {
299: if (!e.isPopupTrigger()) {
300: visited = true;
301: Utils.showURL(url);
302: mouseEntered(null);
303: }
304: }
305:
306: public void mousePressed(MouseEvent e) {
307: }
308:
309: public void mouseReleased(MouseEvent e) {
310: }
311:
312: public void mouseEntered(MouseEvent e) {
313: Color borderColor = Utils
314: .getColor(visited ? VISITED_LINK_COLOR
315: : MOUSE_OVER_LINK_COLOR);
316: setBorder(BorderFactory.createLineBorder(borderColor, 1));
317: StatusDisplayer.getDefault().setStatusText(url);
318: }
319:
320: public void mouseExited(MouseEvent e) {
321: setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
322: StatusDisplayer.getDefault().setStatusText("");
323: }
324:
325: @Override
326: public JToolTip createToolTip() {
327: JToolTip tip = super .createToolTip();
328: JLabel lbl = new JLabel(getToolTipText());
329: Dimension preferredSize = lbl.getPreferredSize();
330:
331: FontMetrics fm = tip.getFontMetrics(tip.getFont());
332: int lines = preferredSize.width / 500;
333: if (preferredSize.width % 500 > 0)
334: lines++;
335: preferredSize.height = Math.min(
336: lines * fm.getHeight() + 10, 300);
337: preferredSize.width = 500;
338: tip.setPreferredSize(preferredSize);
339: return tip;
340: }
341: }
342:
343: private static class MaxSizeImageIcon implements Icon, Constants {
344: private static final int MAX_IMAGE_WIDTH = 202;
345: private static final int MAX_IMAGE_HEIGHT = 142;
346: private Image content;
347: private Image frame;
348:
349: public MaxSizeImageIcon(Image content) {
350: this .content = content;
351: frame = Utilities.loadImage(IMAGE_PICTURE_FRAME);
352: }
353:
354: public void paintIcon(Component c, Graphics g, int x, int y) {
355: int imgX = x;
356: int imgY = y;
357: if (content.getWidth(null) > MAX_IMAGE_WIDTH)
358: imgX += (content.getWidth(null) - MAX_IMAGE_WIDTH) / 2;
359: if (content.getHeight(null) > MAX_IMAGE_HEIGHT)
360: imgY += (content.getHeight(null) - MAX_IMAGE_HEIGHT) / 2;
361: g.drawImage(content, x, y,
362: x
363: + Math.min(MAX_IMAGE_WIDTH, content
364: .getWidth(null)), y
365: + Math.min(MAX_IMAGE_HEIGHT, content
366: .getHeight(null)), imgX, imgY, imgX
367: + Math.min(MAX_IMAGE_WIDTH, content
368: .getWidth(null)), imgY
369: + Math.min(MAX_IMAGE_HEIGHT, content
370: .getHeight(null)), null);
371: g.drawImage(frame, x, y, c);
372: }
373:
374: public int getIconWidth() {
375: return MAX_IMAGE_WIDTH;
376: }
377:
378: public int getIconHeight() {
379: return MAX_IMAGE_HEIGHT;
380: }
381: }
382: }
|