2008/03/22

AIRでWindowsのシステムトレイにアイコンを表示

Airではデスクトップアプリケーションのようにシステムトレイにアイコンを表示することができます。

簡単なサンプルを作成したので掲載します。



<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="applicationCompleteHandle()">

<mx:Script>
<![CDATA[
import mx.controls.Alert;

private function applicationCompleteHandle():void {

/* システムトレイがサポートされているか判定 */
if (NativeApplication.supportsSystemTrayIcon) {

var images:Array = new Array();
images.push(new BitmapData(16, 16, false, 0xFFFFFF));
nativeApplication.icon.bitmaps = images;

var systemTrayIcon:SystemTrayIcon
= (nativeApplication.icon as SystemTrayIcon);

/* ツールチップを表示 */
systemTrayIcon.tooltip = "RiverStone";

var nativeMenu:NativeMenu = new NativeMenu();
nativeMenu.addItem(new NativeMenuItem("メニュー1"));
nativeMenu.addItem(new NativeMenuItem("メニュー2"));
nativeMenu.addItem(new NativeMenuItem("メニュー3"));
nativeMenu.addItem(new NativeMenuItem("メニュー4"));
systemTrayIcon.menu = nativeMenu;

/* クリックイベント */
systemTrayIcon.addEventListener(MouseEvent.CLICK, systemTrayIconClickEventHandle);

}
}

private function systemTrayIconClickEventHandle(event:MouseEvent):void {
Alert.show("システムトレイアイコンをクリック", "アラート");
}

]]>
</mx:Script>
</mx:WindowedApplication>


上記のプログラムを実行するとシステムトレイに白いアイコンが表示されます。



システムトレイをクリックするとアラートが表示されます。



システムトレイに表示されているアイコンを右クリックするとメニューが表示されます。

ラベル: ,

2008/03/17

EclipseでAndroidプロジェクトを作成

前回の投稿でAndroidの開発環境を構築したので、今回はAndroidプロジェクトを作成します。

■ 手順1
プロジェクトエクスプローラ上で右クリックして「新規→プロジェクト」を選択。

■ 手順2
新規プロジェクトダイアログのカテゴリー「Android」を展開して「Androidプロジェクト」を選択して「次へ」ボタンをクリック。


■ 手順3
プロジェクト名・パッケージ名・アクティビティー名・アプリケーション名を入力して「終了」ボタンをクリック


■ 手順4
これでAndroidのプロジェクトが作成されました。最後に作成したプロジェクトを実行してエミュレータを表示します。

プロジェクトを右クリックして「実行→Androidアプリケーション」を選択します。

ラベル: ,

2008/03/16

Androidの開発環境

Androidの開発環境を構築したのでメモします。

1. JDKのインストール
2. Eclipse3.3のインストール
3. Android SDKのインストール
4. ADT Plugin for Eclipseのインストール

■JDKのインストール
Androidの開発にはJDK5.0以上が必要になるので、最新のJDK6.0をインストール。

■Eclipse3.3のインストール
Pleiades All in One を使えば簡単です。

■Android SDKのインストール
ここから各OS用のアーカイブをダウンロードできます。ダウンロードした後に任意の場所に解凍して、環境変数「ANDROID_HOME」に解凍したフォルダへのパスを設定し、環境変数「PATH」の最後に「;%ANDROID_HOME/tools」を追加します。

■ADT Plugin for Eclipseのインストール
Eclipseを起動して「ヘルプ→ソフトウェア更新→検索およびインストール」を選択すると「インストール/更新」ダイアログが表示されます。
ここでは「インストールする新規フィーチャーを検索」を選択して「次へ」ボタンをクリック。



右側に表示される「新規更新リモート・サイト」をクリックして

名前: Android
URL: https://dl-ssl.google.com/android/eclipse/



を入力して「OK」ボタンをクリックする。


Androidにチェックが付いていることを確認して「終了」ボタンをクリック。



更新ダイアログに表示される「Android」をチェックしてから「次へ」ボタンをクリック。



使用条件に同意して、「次へ」ボタンをクリック。



「終了」ボタンをクリック(インストールするのに少し時間がかかります)。


Eclipseを再起動して、「ウィンドウ→設定→Android」を開きSDKロケーションを設定。


これでAndroidのプロジェクトを作成できるようになります。

ラベル: ,

2008/03/14

PDFの閲覧にはFoxit READERがおすすめ

最近までPDFのドキュメントを見るのにAdobe Readerを使用していました。しかし、あまりにも起動に時間がかるのと、リソースをたくさん使うのに嫌気がさしてきました。(私の使用しているマシンは低スペックではありません)

Webで他のPDFを閲覧するソフトウェア探して、試してみたところ・・・
Foxit READERというソフトウェアに落ち着きました。



これは起動も高速で閲覧するのにまったくストレスを感じません。

12MBのPDFをAdobe ReaderとFoxit READERで開いてみたところ、Adobe Readerが12秒、Foxit READERが3秒ぐらいでした。(スクロールもFoxit READERの方が圧倒的にスムーズです)

私にとっては高機能で遅いソフトウェアよりも、それなりの機能で早いソフトウェアの方が魅力的です。

Adobe Readerにストレスを感じているかたは、是非おためしください。

ラベル: , ,

2008/03/12

AIRに画像ファイルをドラッグ&ドロップして表示

AIRで作成したアプリケーションに画像ファイルをドラッグ&ドロップして表示するサンプルを作成しましたので掲載します。

AIRで作成したアプリケーション外からドラッグ&ドロップするには「NativeDragEvent」に定義してある「NATIVE_DRAG_ENTER」と「NATIVE_DRAG_DROP」のイベント処理を行います。

ポイントは

1.
NATIVE_DRAG_ENTERイベントにて「NativeDragManager.acceptDragDrop」を呼び出しドラッグ&ドロップを許可する

2.
NATIVE_DRAG_DROPイベントにてイベントクラスのプロパティ「Clipboard」からデータを取得して処理する

となっています。
詳細は下記のサンプルをご覧ください。


<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="applicationCompleteEventHandle()">

<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.managers.DragManager;

var loader:Loader;

private function applicationCompleteEventHandle():void {

canvas.addEventListener(
NativeDragEvent.NATIVE_DRAG_ENTER, nativeDragEnterEventHandler);

canvas.addEventListener(
NativeDragEvent.NATIVE_DRAG_DROP, nativeDragDropEventHandler);
}

private function nativeDragEnterEventHandler(event:NativeDragEvent):void {

if (event.clipboard.hasFormat(
ClipboardFormats.FILE_LIST_FORMAT)) {
NativeDragManager.acceptDragDrop(canvas);
}
}

private function nativeDragDropEventHandler(event:NativeDragEvent):void {

var fileList:Array
= event.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;

if (fileList.length > 1) {
return;
}

var file:File = fileList[0];
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);

var byteArray:ByteArray = new ByteArray();

fileStream.readBytes(byteArray, 0, fileStream.bytesAvailable);

loader = new Loader();

loader.contentLoaderInfo
.addEventListener(Event.COMPLETE, completeEventHandle);

loader.contentLoaderInfo
.addEventListener(IOErrorEvent.IO_ERROR, ioErrorEventHandler);

loader.loadBytes(byteArray);
}

private function completeEventHandle(event:Event):void {

if (loader.content is Bitmap) {
image.data = loader.content;
}
}

private function ioErrorEventHandler():void {
Alert.show("画像を読み込めませんでした。");
}

]]>
</mx:Script>

<mx:Canvas id="canvas" x="0" y="0" width="100%" height="100%" backgroundColor="#FFFFFF">
<mx:Image id="image" horizontalCenter="0" verticalCenter="0"/>
</mx:Canvas>

</mx:WindowedApplication>

■実行結果

ラベル: ,

2008/03/10

AIRでディスプレイの情報を取得する

AIRでディスプレイの幅・高さ・色深度を取得するには「flash.display.Screen」クラスを使用します。Screenクラスに定義されている静的フィールド「screens」・「mainScreen」からScreenクラスのインスタンスを取得してフィールドにアクセスします。

screensには「Screen」クラスのインスタンスを格納した「Array」が、mainScreentはメインとなるディスプレイのScreenクラスのインスタンスが設定されています。

下記にサンプルを掲載します。


var screenArray:Array = Screen.screens;

for (var i:int = 0; i < screenArray.length; i++) {

var screen:Screen = screenArray[i] as Screen;
trace(screen.colorDepth);
trace(screen.bounds.width);
trace(screen.bounds.height);
}


■実行結果

色深度: 32
幅: 1440
高さ: 900

ラベル: ,

2008/03/08

AIRからSQLiteを使用する

AIRでは「flash.data」パッケージのクラスを使用するとSQLiteというデータベースを使用することができます。

JavaのJDBCを使用した経験があれば、すぐに理解できると思います。(非同期なことを除けば)

簡単なサンプルを作成したので掲載します。このサンプルではSQLiteのデータベースにアクセスしてテーブルのデータを取得し、グリッドコンポーネントに表示しています。


<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="applicationCompleteEventHandle()">

<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.Alert;

private var conn:SQLConnection;
private var stmt:SQLStatement;

private function applicationCompleteEventHandle():void {

var dbFile:File
= File.applicationStorageDirectory.resolvePath("local.db");

conn = new SQLConnection();

conn.addEventListener(SQLEvent.OPEN, databaseOpenEventHandle);
conn.addEventListener(SQLErrorEvent.ERROR, databaseOpenErrorEventHandle);

conn.open(dbFile);
}

private function closeEventHandle():void {

if (conn != null) {
conn.close();
}
}

private function databaseOpenEventHandle(event:SQLEvent):void {
readCustomerData();
}

private function databaseOpenErrorEventHandle(event:SQLErrorEvent):void {
Alert.show("データベースに接続できませんでした。", "データベース");
}

private function readCustomerData():void {

stmt = new SQLStatement();
stmt.sqlConnection = conn;
stmt.text = "SELECT ID, NAME, ADDRESS FROM CUSTOMERS";

stmt.addEventListener(SQLEvent.RESULT, queryExecuteResultEventHandle);
stmt.addEventListener(SQLErrorEvent.ERROR, queryExecuteErrorEventHandle);

stmt.execute();
}

private function queryExecuteResultEventHandle(event:SQLEvent):void {

var result:SQLResult = stmt.getResult();

var dataSource:ArrayCollection = new ArrayCollection();

for (var i:int = 0; i < result.data.length; i++) {

var obj:Object = new Object();
obj["id"] = result.data[i]["ID"];
obj["name"] = result.data[i]["NAME"];
obj["address"] = result.data[i]["ADDRESS"];
dataSource.addItem(obj);
}

customersGrid.dataProvider = dataSource;
}

private function queryExecuteErrorEventHandle(event:SQLErrorEvent):void {
Alert.show("SQL実行時にエラーが発生しました。", "データベース");
}

]]>
</mx:Script>
<mx:VBox y="0" height="100%" width="100%" x="0" verticalGap="0">
<mx:Canvas width="100%" height="100%">
<mx:DataGrid id="customersGrid" width="95%" height="95%" horizontalCenter="0" verticalCenter="0">
<mx:columns>
<mx:DataGridColumn headerText="顧客番号" dataField="id"/>
<mx:DataGridColumn headerText="顧客名" dataField="name"/>
<mx:DataGridColumn headerText="住所" dataField="address"/>
</mx:columns>
</mx:DataGrid>
</mx:Canvas>
</mx:VBox>

</mx:WindowedApplication>


■実行結果


SQLiteのデータベースファイルを指定する際に「File.applicationStorageDirectory」を使用しています。これはWindowsXPでは「Documents And Settings/ユーザ名/ApplicationData/アプリケーション名/Local Data」を指しているようです。

そのうちAdobe AIR用のO/Rマッピングソフトが流行りそうですね。(もう存在するのでしょうか?)

ラベル: ,

2008/03/07

AIRでWebサイトを表示する

AIRではHTMLクラスを使えば簡単に任意のWebサイトを表示することができます。
Flex2ではいろいろ細工をすれば表示できましたがAIRでは驚くほど簡単にできます。

下記がサンプルです。

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" title="RiverStone">

<mx:Script>
<![CDATA[

private function addressKeyDownEventHandle(event:KeyboardEvent):void {

if (event.keyCode == Keyboard.ENTER) {
browser.location = address.text;
}
}

]]>
</mx:Script>

<mx:VBox x="0" y="0" height="100%" width="100%" verticalGap="2">
<mx:HBox width="100%" height="50" verticalAlign="middle" horizontalGap="2" paddingLeft="5" paddingRight="5">
<mx:Button id="backButton" width="45" height="40" click="{browser.historyBack()}" label="戻る"/>
<mx:Button id="forwardButton" label="進む" width="45" height="40" click="{browser.historyForward()}"/>
<mx:Button id="stopButton" label="中止" width="45" height="40" click="{browser.cancelLoad()}"/>
<mx:TextInput id="address" width="100%" keyDown="addressKeyDownEventHandle(event)"/>
</mx:HBox>
<mx:HTML id="browser" width="100%" height="100%" location="http://www.r-stone.net/"/>
</mx:VBox>

</mx:WindowedApplication>


■実行結果

HTMLクラスの「historyBackメソッド」でブラウザの戻る、「historyForwardメソッド」でブラウザの進む、「cancelLoadメソッド」でブラウザの中止と同様の処理を行うことができます。

その他にも履歴情報を取得できたり、HTMLコントロールで表示しているHTMLのDOM情報にもアクセスできるようです。

ラベル: ,

2008/03/06

AIRのFileSystemDataGridを使ってみました

Flex3の「FileSystemDataGrid」クラスを使用すれば、ローカルにあるディレクトリの中身を表示することができます。

簡単ですがサンプルを作成しました。

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.FileEvent;

private function fileChooseEventHandle(event:FileEvent):void {
Alert.show(event.file.nativePath);
}

]]>
</mx:Script>

<mx:FileSystemDataGrid id="grid" horizontalCenter="0" width="90%" height="80%" directory="{File.documentsDirectory}" fileChoose="fileChooseEventHandle(event)" verticalCenter="0"/>
<mx:Button x="45" y="10" label="上へ" enabled="{grid.canNavigateUp}" click="{grid.navigateUp()}"/>
<mx:Button x="99" y="10" label="下へ" enabled="{grid.canNavigateDown}" click="{grid.navigateDown()}"/>
<mx:Button x="153" y="10" label="戻る" enabled="{grid.canNavigateBack}" click="{grid.navigateBack()}"/>
<mx:Button x="207" y="10" label="進む" enabled="{grid.canNavigateForward}" click="{grid.navigateForward()}"/>

</mx:WindowedApplication>


■実行結果


「FileSystemDataGrid」クラスには上下のディレクトリに移動するメソッドや、ブラウザの戻る・進むボタンのような動きをするメソッドもあります。

他にも表示する内容をフィルタリングできたり、ソートすることもできます。

なかなか高機能ですよね。

ラベル: ,

2008/03/05

ActionScript3のE4Xでハイフンを含む属性の扱い

ActionScript3のE4Xでハイフンを含む属性の値を取得する場合、通常のように@属性名ではコンパイルエラーとなってしまいます。


E4Xでハイフンを含む属性値を取得する場合は、下記のようにすれば取得することができます。


var customers:XML =
<customers>
<customer customer-id="001">佐藤工業</customer>
<customer customer-id="002">田中建築</customer>
</customers>;
trace(customers.customer[0].@["customer-id"]);


「@」の後ろを角かっこで囲み、角かっこの中に属性名を文字列型で指定します。
E4Xを使い始めた当初は、この方法がわからず小一時間ほど調べました。

ラベル:

2008/03/02

Adobe AIRのNativeWindowクラス

Adobe AIRでネイティブのデスクトップウィンドウを作成するには「flash.display.NativeWindow」クラスを使用します。

NativeWindowを作成する初期化オプション「flash.display.NativeWindowInitOptions」をNativeWindowのコンストラクタ渡してNativeWindowの「activateメソッド」を呼び出せばウィンドウが表示されます。

NativeWindowInitOptionsクラスの「type」プロパティに、NativeWindowTypeに定義してある定数を設定すればウィンドウの種別を変更できるようです。

下記にサンプルを掲載します。


<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

<mx:Script>
<![CDATA[
import mx.core.Window;

private function newWindowButton1ClickHandle():void {

var options:NativeWindowInitOptions = new NativeWindowInitOptions();
options.type = NativeWindowType.NORMAL;

var win:NativeWindow = new NativeWindow(options);
win.title = "NORMAL";
win.width = 200;
win.height = 200;
win.stage.addChild(createTextField("サンプル"));

win.activate();

}

private function newWindowButton2ClickHandle():void {

var options:NativeWindowInitOptions = new NativeWindowInitOptions();
options.type = NativeWindowType.LIGHTWEIGHT;

/* NativeWindowTypeがLIGHTWEIGHTの場合はsystemChromeをNONEにする */
options.systemChrome = NativeWindowSystemChrome.NONE;

var win:NativeWindow = new NativeWindow(options);
win.title = "LIGHTWEIGHT";
win.width = 200;
win.height = 200;
win.stage.addChild(createTextField("サンプル"));
win.activate();

}

private function newWindowButton3ClickHandle():void {

var options:NativeWindowInitOptions = new NativeWindowInitOptions();
options.type = NativeWindowType.UTILITY;

var win:NativeWindow = new NativeWindow(options);
win.title = "UTILITY";
win.width = 200;
win.height = 200;
win.stage.addChild(createTextField("サンプル"));
win.activate();
}

private function createTextField(text:String):TextField {

var button:TextField = new TextField();
button.text = text;
button.width = 100;
button.height = 20;
return button;
}

]]>
</mx:Script>

<mx:Canvas x="0" y="0" width="100%" height="100%" backgroundColor="#FFFFFF">
<mx:Button id="newWindowButton1" x="10" y="10" label="新しいウィンドウ1" click="newWindowButton1ClickHandle()"/>
<mx:Button id="newWindowButton2" x="10" y="40" label="新しいウィンドウ2" click="newWindowButton2ClickHandle()"/>
<mx:Button id="newWindowButton3" x="10" y="70" label="新しいウィンドウ3" click="newWindowButton3ClickHandle()"/>
</mx:Canvas>

</mx:WindowedApplication>
■上記のプログラムを実行すると表示されるウィンドウ

■NativeWindowType.NORMALのウィンドウ

■NativeWindowType.LIGHTWEIGHTのウィンドウ

■NativeWindowType.UTILITYのウィンドウ


Flex2ではコンテナにコンポーネントを追加する場合、コンテナの「addChild」メソッドを呼び出してコンポーネントを追加していましたが、NativeWindowクラスではNativeWindowのプロパティ「stage」に対して「addChild」を呼び出し追加するようです。

しかし、私の環境ではFlexのコンポーネントをNativeWindowに追加することができませんでした。これはベータ版のときの制約だったようですが、正式にリリースされたバージョンでも対応していないようです。

ラベル: