今回は、前回作成したサービスを利用して、ビデオ一覧を表示するビューを作成します。
ビューを作成する前に、自動生成された Application.e4xmi をオープンして、アプリケーションモデルの初期状態を変更します:
これらの変更結果は以下のようになります。
次は、追加したギャラリーパートにビュー(GalleryView) をリンクします。
必須プラグインの追加
ギャラリービューでは、ビデオ一覧の表示に Nebula Gallery Widgetを使用します。 更新サイト:http://download.eclipse.org/technology/nebula/snapshot から Gallery Widget をインストールします。 次に、plugin.xml を開いて依存関係ページで、必須プラグインとして、org.eclipse.nebula.widgets.gallery を追加してください。 また、ギャラリービューは依存性注入により、前回作成したビデオサービスファクトリを使用します。以下のプラグインも追加する必要があります:
ビュークラスの作成
com.itrane.myvideo プラグインに com.itrane.myvideo.views パッケージを作成します。作成したパッケージに GalleyView クラスを作成します。E4 では、ビューはプラットフォームに依存しません。 作成した GalleryView のコードは以下のようになります:
上記コードでは、次の処理を行っています。
Application.e4xmi を開き、先に追加したギャラリーパートを選択して、"Class URI" 項目の "Find" ボタンを押して、作成したギャラリービューを選択します(下図):
また、e4 テンプレートによって作成された、ハンドラやコマンド、メニューバー、ツールバーは使用しないので、モデルから削除します。変更を保存して、アプリケーションを起動します。アプリケーションを起動する前に、製品構成ファイル(com.itrane.myvideo.puroduct) を開き、"Dependencies"ページで "Add Required Plug-ins" ボタンを押して、追加した必須プラグインが確実に反映されるようにします。 これで、ビデオサービスを利用して、ビデオの一覧を表示するところまで完成しました(下図):
次回は選択ビデオを再生する機能を追加します。
ビューを作成する前に、自動生成された Application.e4xmi をオープンして、アプリケーションモデルの初期状態を変更します:
- ウィンドウの位置、サイズを変更: Bounds(5,5,1000,600)
- ウィンドウのラベルを変更:マイビデオ
- PartSashContainer の 分割方向(Orientation) を水平(Horizontal)に変更。
- 自動的に作成されたパートスタックを削除。
- PartSashContainer に2つのパートを追加:
ギャラリーパート (Id = "com.itrane.myvideo.GalleryPart")
ビデオパート (Id = "com.itrane.myvideo.VideoPart")
これらの変更結果は以下のようになります。
次は、追加したギャラリーパートにビュー(GalleryView) をリンクします。
必須プラグインの追加
ギャラリービューでは、ビデオ一覧の表示に Nebula Gallery Widgetを使用します。 更新サイト:http://download.eclipse.org/technology/nebula/snapshot から Gallery Widget をインストールします。 次に、plugin.xml を開いて依存関係ページで、必須プラグインとして、org.eclipse.nebula.widgets.gallery を追加してください。 また、ギャラリービューは依存性注入により、前回作成したビデオサービスファクトリを使用します。以下のプラグインも追加する必要があります:
- org.eclipse.e4.ui.di
- com.itrane.myvideo.videoservice
- com.itrane.myvideo.videoservice.impl
ビュークラスの作成
com.itrane.myvideo プラグインに com.itrane.myvideo.views パッケージを作成します。作成したパッケージに GalleyView クラスを作成します。E4 では、ビューはプラットフォームに依存しません。 作成した GalleryView のコードは以下のようになります:
publicclass GalleryView {
private List<String> fGalleryGroups;
private Map<String, List<IVideo>> fVideoMap;
private Gallery fGallery;
private DefaultGalleryGroupRenderer fGalleryGroupRenderer;
private DefaultGalleryItemRenderer fGalleryItemRenderer;
private IVideoHomeFactory zVideoHomeFactory;
private IVideoHome fVideoHome;
@Inject
public GalleryView(IVideoHomeFactory videoHomeFactory) {
zVideoHomeFactory = videoHomeFactory;
}
/**
* ビューパートのコンテンツを作成.
*/
@PostConstruct
publicvoid createControls(Composite parent) {
initData();
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
createGallery(composite);
}
privatevoid initData() {
String root = "C:/$mydoc/video/music";
fVideoHome = zVideoHomeFactory.createHome(
root,
new String[] {"mp4", "divx", "flv", "avi", "wmv"});
fVideoMap = new HashMap<String, List<IVideo>>();
for (IVideo video: fVideoHome.getVideoList()) {
String artist = video.getGroup();
List<IVideo> videos = fVideoMap.get(artist);
if (videos == null) {
videos = new ArrayList<IVideo>();
videos.add(video);
fVideoMap.put(artist, videos);
} else {
videos.add(video);
}
}
fGalleryGroups = new ArrayList<String>(fVideoMap.keySet());
Collections.sort(fGalleryGroups);
}
privatevoid createGallery(Composite composite) {
composite.setLayout(new FillLayout());
fGallery = new Gallery(composite, SWT.VIRTUAL | SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
//項目をダブルクリックしたときの処理
fGallery.addMouseListener(new MouseAdapter() {
@Override
publicvoid mouseDoubleClick(MouseEvent e) {
// TODO doubleclick
}
});
// グループレンダラーの作成
fGalleryGroupRenderer = new DefaultGalleryGroupRenderer();
fGalleryGroupRenderer.setMaxImageWidth(60);
fGalleryGroupRenderer.setMinMargin(0);
// fGroupRenderer.setAlwaysExpanded(true);
// 項目レンダラーの作成
fGalleryItemRenderer = new DefaultGalleryItemRenderer();
// サムネールの表示方法を設定
fGalleryGroupRenderer.setItemSize(120, 90);
fGalleryItemRenderer.setShowLabels(true);
//レンダラーをギャラリーに設定
fGallery.setGroupRenderer(fGalleryGroupRenderer);
fGallery.setItemRenderer(fGalleryItemRenderer);
//パフォーマンスのため仮想グループにする
fGallery.setVirtualGroups(true);
fGallery.addListener(SWT.SetData, new Listener() {
publicvoid handleEvent(Event event) {
String imgPath = fVideoHome.getCaptureDir();
GalleryItem item = (GalleryItem) event.item;
int pindex = 0, cindex = 0;
if (item.getParentItem() != null) {
//%%% ビデオ項目を作成する %%%%%
String key = item.getParentItem().getText();
cindex = item.getParentItem().indexOf(item);
item.setItemCount(0);
List<IVideo> videos = fVideoMap.get(key);
if (videos != null) {
IVideo video = videos.get(cindex);
if (video != null) {
//項目のイメージとテキストの表示
item.setText(video.getTitle());
//item.setData(video);
String fileName = fVideoHome
.getCaptureFileName(video);
setImage(item, imgPath + fileName);
if (cindex == 0) {
item.getParentItem().setImage(item.getImage());
}
}
} else {
item.setText("Video " + item.getParentItem().getText() + " - " + cindex); //$NON-NLS-1$
}
} else {
//%%% グループ項目を作成する %%%%%
pindex = fGallery.indexOf(item);
String key = fGalleryGroups.get(pindex);
List<IVideo> videos = fVideoMap.get(key);
if (videos != null) {
IVideo video = videos.get(0);
if (video != null) {
//グループのイメージとテキストの表示
String fileName = fVideoHome
.getCaptureFileName(video);
File imgFile = new File(imgPath + fileName);
if (imgFile.exists()) {
final Image img = PluginImages.getImage(imgPath + fileName);
item.setImage(img);
} else {
item.setImage(PluginImages.NOCAPTURE_IMG.createImage());
}
}
item.setItemCount(videos.size());
}
setGroupToItem(fGalleryGroups.get(pindex), item);
}
}
});
fGallery.setItemCount(fGalleryGroups.size());
}
privatevoid setImage(GalleryItem item, String filePath) {
System.out.println("filePath="+filePath);
File imgFile = new File(filePath);
if (imgFile.exists()) {
final Image img = PluginImages.getImage(filePath);
item.setImage(img);
} else {
item.setImage(PluginImages.NOCAPTURE_IMG.createImage());
}
}
privatevoid setGroupToItem(String group, GalleryItem item) {
item.setText(group);
Image groupImage = getGroupImage(group);
if (groupImage != null) {
item.setImage(groupImage);
}
}
private Image getGroupImage(String group) {
return null;
}
@PreDestroy
publicvoid dispose() {
}
@Focus
publicvoid setFocus() {
fGallery.setFocus();
}
}
上記コードでは、次の処理を行っています。
- @Inject アノテーションにより、コンストラクタに VideoHomeFactoryのインスタンスが渡されます。
- 続いて createControls() メソッドが実行されます(@PostConstruct アノテーションは、DIが完了した後にこのメソッドが呼ばれることを保障します)。
- createControls では、最初に initData() メソッドを実行します。
- initData() メソッドでは、VideoHomeFactory により VideoHomeインスタンスが生成されます。 このとき、ビデオファイル一覧を取得する、トップディレクトリとビデオファイルのタイプを指定します。 VideoHome#getVideoList() で指定されたパス以下のビデオ情報を取得し、グループ別のビデオ一覧マップ(fVideoMap)を作成します。
- createControls の残りの部分で、このマップを使って、Nebula Gallery Widgetにより、グループ別のビデオギャラリーを作成します。
Application.e4xmi を開き、先に追加したギャラリーパートを選択して、"Class URI" 項目の "Find" ボタンを押して、作成したギャラリービューを選択します(下図):
また、e4 テンプレートによって作成された、ハンドラやコマンド、メニューバー、ツールバーは使用しないので、モデルから削除します。変更を保存して、アプリケーションを起動します。アプリケーションを起動する前に、製品構成ファイル(com.itrane.myvideo.puroduct) を開き、"Dependencies"ページで "Add Required Plug-ins" ボタンを押して、追加した必須プラグインが確実に反映されるようにします。 これで、ビデオサービスを利用して、ビデオの一覧を表示するところまで完成しました(下図):
次回は選択ビデオを再生する機能を追加します。