package net.javainthebox.flickr;
import javafx.ext.swing.SwingList;
import javafx.ext.swing.SwingListItem;
import javafx.ext.swing.SwingScrollPane;
import javafx.scene.Scene;
import javafx.stage.Stage;
// リストで表示する項目
var items: SwingListItem[];
var rssReader = AtomReader {
url: "http://api.flickr.com/services/feeds/photos_public.gne?id=57085156@N00&lang=en-us&format=atom"
onDone: function(infos: PhotoInfo[]) {
// パースが終了したら、HTMLでリストの項目を表示する
for (info in infos) {
var item = SwingListItem {
text: "<html><p>{info.title}</p><img src='{info.thumbnailUrl}' /></html>"
}
insert item into items;
}
}
}
rssReader.read();
Stage {
title: "FlickrAtomReader"
scene: Scene {
width: 400
height: 600
content: [
// リストをスクロールペインで表示する
SwingScrollPane {
width: 400
height: 600
view: SwingList {
items: bind items
}
}
]
}
}
package net.javainthebox.flickr;
import javafx.data.pull.Event;
import javafx.data.pull.PullParser;
import javafx.data.xml.QName;
import javafx.io.http.HttpRequest;
import java.io.InputStream;
import java.lang.Exception;
public class AtomReader {
public-init var url: String;
// 処理が終了した後にコールするコールバック関数
public var onDone: function(:PhotoInfo[]): Void;
// サムネイルのURLを取り出すための正規表現
def pattern = java.util.regex.Pattern.compile("http://farm.*_m.jpg");
public function read(): Void {
var request = HttpRequest {
location: url
// 入力の解析はparse関数で行う
onInput: parse
// エラー処理
onException: function(ex: Exception) {
println("exception: {ex.getMessage()}");
}
};
request.enqueue();
}
// Atomのパース
function parse(stream: InputStream) {
var infos: PhotoInfo[];
var info: PhotoInfo;
var inEntry: Boolean;
var parser = PullParser {
documentType: PullParser.XML;
input: stream
onEvent: function(event: Event) {
if (event.type == PullParser.START_ELEMENT) {
if (event.qname.name == "entry") {
// <entry>の開始
// 新たなPhotoInfoオブジェクトを生成する
inEntry = true;
info = PhotoInfo {};
}
}
if (event.type == PullParser.END_ELEMENT) {
if (event.qname.name == "entry") {
// </entry>の場合
// 作成したPhotoInfoオブジェクトをシーケンスに追加
inEntry = false;
insert info into infos;
} else if (inEntry and event.qname.name == "title") {
// </title>の場合
// PhotoInfoオブジェクトのtitleを設定
info.title = event.text;
} else if (inEntry and event.qname.name == "content") {
// </content>の場合
// 正規表現を用いて、サムネイルのURLを取り出し、
// PhotoInfoオブジェクトのthumbnailUrlに設定
var matcher = pattern.matcher(event.text);
if (matcher.find()) {
var url = matcher.group();
info.thumbnailUrl = url.replaceAll("_m", "_t");
}
}
}
}
}
// パースの開始
parser.parse();
if (onDone != null) {
// パースが終了したら、コールバック関数をコールする
onDone(infos);
}
stream.close();
}
}