package com.bitwaffle.launcher; import java.awt.BorderLayout; import java.awt.Color; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import javax.swing.BoxLayout; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.LineBorder; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** * This class takes an RSS feed and returns a nice looking JPanel containing a number of items in the feed. * Java's native XML parsing libraries are used to deal with the RSS feed. * @author TranquilMarmot * */ public class RSS2AWT { /** * Gets a JPanel with the RSS feed in it * @param rssUrl URL for RSS feed * @param numItems Number of items to grab from RSS feed * @return JPanel with every element from the RSS feed */ public static JPanel getRSSFeed(String rssUrl, int numItems){ JPanel p = new JPanel(); p.setBackground(Color.black); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db; Document doc; NodeList nodes = null; try{ db = dbf.newDocumentBuilder(); URL url = new URL(rssUrl); URLConnection con = url.openConnection(); InputStream stream = con.getInputStream(); doc = db.parse(stream); stream.close(); Element docEle = doc.getDocumentElement(); nodes = docEle.getChildNodes(); } catch(Exception e){ e.printStackTrace(); } if(nodes != null && nodes.getLength() > 0){ for(int i = 0; i < nodes.getLength(); i++){ if(!nodes.item(i).getNodeName().equals("#text")){ Element ele = (Element) nodes.item(i); if(ele.getNodeName().equals("channel")) p.add(parseChannel(ele, numItems)); } } } return p; } /** * Parses a 'channel' from an RSS feed * @param channel Channel to parse * @param numItems Number of items to grab from RSS feed * @return JPanel with all the elements from the channel */ private static JPanel parseChannel(Element channel, int numItems){ JPanel p = new JPanel(); p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); NodeList items = channel.getChildNodes(); int itemsParsed = 0; if(items != null && items.getLength() > 0){ for(int i = 0; i < items.getLength(); i++){ if(!items.item(i).getNodeName().equals("#text")){ Element ele = (Element) items.item(i); if(ele.getNodeName().equals("item")){ p.add(parseItem(ele)); JPanel emptyPanel = new JPanel(); emptyPanel.setSize(100, 25); emptyPanel.setBackground(Color.black); p.add(emptyPanel); itemsParsed++; } } if(itemsParsed >= numItems) break; } } return p; } /** * Parses an item from an RSS feed * @param item Item to parse * @return JPanel containing the title, description and date of the post */ private static JPanel parseItem(Element item){ JPanel p = new JPanel(); String title = getString(item, "title"); String description = getString(item, "description"); // FIXME couldn't find a clean looking way to include this (ideally it would open up the default browser) //String link = getString(item, "link"); String pubDate = getString(item, "pubDate"); p.setLayout(new BorderLayout()); if(!title.equals("Photo")){ JLabel titleLabel = new JLabel(title); titleLabel.setForeground(Color.green); p.add(titleLabel, BorderLayout.NORTH); } /* * TODO * Since links don't work (yet) it might be a good idea to parse the description * string either get rid of every <a></a> and change the text color to just be blue */ JLabel descLabel = new JLabel("<html>" + description + "</html>"); descLabel.setForeground(Color.white); JLabel dateLabel = new JLabel(pubDate); dateLabel.setForeground(Color.green); p.add(descLabel, BorderLayout.CENTER); p.add(dateLabel, BorderLayout.SOUTH); p.setBorder(new LineBorder(Color.green, 2)); p.setBackground(Color.black); return p; } /** * Gets a string from an element * * @param ele * The element to get the string from * @param tagName * The tag to get the string from * @return The string from the element */ private static String getString(Element ele, String tagName) { String textVal = null; NodeList nl = ele.getElementsByTagName(tagName); if (nl != null && nl.getLength() > 0) { Element el = (Element) nl.item(0); textVal = el.getFirstChild().getNodeValue(); } return textVal; } }