最近「Javaって古臭いだけだと思ってたけど結構悪くないんじゃねーか?」なんて思ってきたが、今のところNetBeansとかJavaを使う予定はない。でもまぁいいじゃんって事で、NetBeansを使ってサンプルを動かして遊んでみた。
RSSを取り込んで表示してみよう。表示するのはヘッドラインだけで、クリックすると該当記事に飛んでいく。
かっこよくリストボックスにするのもいいが、まずはHTMLの使えるコンポーネントにでも貼り付ける事にしよう。
まず機能を分解すると、以下のようになると思う。
GUIならリストボックスがいいかなと思ったが面倒くさいので、まずはHTMLの使えるコンポーネントに貼り付ける事にする。
RSSはXMLなのでXML解釈となる。Javaはこのへんが本格的すぎてちょろっと簡単に記述とはいかないんだが、とりあえずDOMってやつを使う事にする。指定URLかファイルストリームから直接もってくるようだ。a)とb)が一緒になってしまうがまぁいい、簡単なのでURLでいこう。URLを入れるとハッシュで返すようにしてみたぞ。
static Map<String,String> xmlAnl2(String fn){ Map<String,String> map = new LinkedHashMap<String,String>(); try { DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); DocumentBuilder bulder=factory.newDocumentBuilder(); InputStream input=new URL(fn).openStream(); Document dc=bulder.parse(input); NodeList list=dc.getElementsByTagName("item"); for(int i=0;i<list.getLength();i++){ Node n=list.item(i); NodeList nlist=n.getChildNodes(); String title=null; String url=null; String date=null; for(int j=0;j<nlist.getLength();j++){ Node child=nlist.item(j); if(child.getNodeName().equals("title")){ title=child.getTextContent().trim(); }else if(child.getNodeName().equals("link")){ url=child.getTextContent().trim(); }else if(child.getNodeName().equals("pubDate")){ date=child.getTextContent().trim(); } if(title!=null && url!=null && date!=null){ title = dateFormat(date)+"\t"+title; map.put(title, url); break; } } } }catch(ParserConfigurationException e){ e.printStackTrace(); }catch(SAXException e){ e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); } return(map); }
「ちょっとまて、dateFormatってなんだよ」ああすみません。ASCII形式だと何なのでちょろっと小細工してます。以下ね。とっても間に合わせ。
static String dateFormat(String date){ String r = date; String rr = ""; String[] m = "Dummy,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(",",0); Pattern pattern = Pattern.compile("(Mon|Tue|Wed|Thu|Fri|Sat|Sun),"); Matcher matcher = pattern.matcher(r); r = matcher.replaceAll(""); r = Pattern.compile(" +").matcher(r).replaceAll(" "); r = Pattern.compile(" (\\d{1,2}) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (20\\d{2})").matcher(r).replaceAll("$3/$2/$1"); for(int i=1;i<13;i++){ rr = r; r = Pattern.compile(m[i]).matcher(r).replaceAll(String.valueOf(i)); if(!r.equals(rr)){ r = Pattern.compile("(/)(\\d)(/)").matcher(r).replaceAll("$1"+"0"+"$2$3"); } } r = r.trim(); return(r); }
んで、これを読みだしてGUIに吐き出すコード。表示にはJEditPanelでも使おうか。名前はjeditpane1にした。
@Action public void getNhkNews() { String u = "http://www3.nhk.or.jp/rss/news/cat0.xml"; String x = ""; String x2 = "<ul>"; Map<String,String> map = xmlAnl2(u); for(String title:map.keySet()){ x = x + "<li><a href=\""+map.get(title)+"\">"+title+"</a></li>"; } if(x != ""){ x = x + "</ul>"; jeditpane1.setText(x); } }
「さぁこれが動くか」いーやとんでもない。このままではクリックしても反応しないのだ。クリッカブルにしてやらなくちゃならない。で、呪文を示そう。
まず以下。実際にはNetBeans側のメニューでhyperlinkUpdateを有効にすると自動的に宣言されるが、生成されるコードはこんな感じだ。
jeditpane1.addHyperlinkListener(new javax.swing.event.HyperlinkListener() { public void hyperlinkUpdate(javax.swing.event.HyperlinkEvent evt) { jeditpane1HyperlinkUpdate(evt); } });
次に、上で呼び出してる jeditpane1HyperlinkUpdate(evt) だが、こいつは空っぽで中身がないので記述してやる。といっても何処かでもらってきたフレーズだけどなww
private void jeditpane1HyperlinkUpdate(javax.swing.event.HyperlinkEvent evt) { if (evt.getEventType() == EventType.ACTIVATED) { //クリックされた時 URL url = evt.getURL(); Desktop dp = Desktop.getDesktop(); try { // たぶん「お気に入り」とかで登録されてるブラウザが呼び出される dp.browse(url.toURI()); } catch (Exception ex) { ex.printStackTrace(); } } }
これでリンクをクリックすると該当記事に飛ぶようになる。