AIR アプリケーションで大きく分類して1つの機能のみを保持する場合は、特に意識せずに開発すればいいんですが、ふと、機能が横並び的に拡張して、親アプリケーション(mx:WindowedApplication や mx:Application)ではそのレイアウトのみを管理し、各子クラスがそれぞれ1つのアプリケーションの単位として考えられる場合はどうやるんだろう・・・と思ったので、調査してみた。
要は、各アプリケーションを表すアイコンがズラッと並んでいるだけで、各アイコンをクリックした時点で、各アプリケーションが起動する感じにしたい。

mx:Window 概略図
最初は、「ポップアップ機能を使うんじゃないのか?」と思い、NativeWindowInitOption や NativeWindow クラスを使用し、新規ウィンドウを立ち上げてみたが、これだと画像などを NativeWindow オブジェクトに addChild 出来るけど、そこからの拡張性がないようだ。ココでも取り上げられている様に、他の MXML Component を addChild しても描写はされないらしいし、シンプルにここで単純なコンテンツを表示する場合に適するのかなと思う。
▽ NativeWindow による通常のポップアップ
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"><mx:Script>
<![CDATA[
import flash.display.Sprite;
import flash.display.NativeWindow;
import flash.display.NativeWindowDisplayState;
import flash.display.NativeWindowInitOptions;
import flash.display.NativeWindowResize;
import flash.display.NativeWindowSystemChrome;
import flash.display.NativeWindowType;
import flash.events.Event;
import flash.events.MouseEvent;[Embed(source='../asset/sampleImage.png')]
private var SampleImage:Class;private var win1:NativeWindow;
private var win2:NativeWindow;/**
* Window 1 を開くための関数
*/
private function openWindow1():void {
var targetX:Number = stage.nativeWindow.x + stage.nativeWindow.width;
var targetY:Number = stage.nativeWindow.y;
win1 = makeWindow(
false,
false,
false,
NativeWindowType.NORMAL,
false,
NativeWindowSystemChrome.STANDARD,
"Window 1",
300,
300
);
win1.x = targetX;
win1.y = targetY;
var imageSprite:Sprite = new Sprite();
imageSprite.x = imageSprite.y = 0;
imageSprite.addChild(new SampleImage());
win1.stage.addChild(imageSprite);
}/**
* Window 2 を開くための関数
*/
private function openWindow2():void {
var targetX:Number = win1.x + win1.width;
var targetY:Number = stage.nativeWindow.y;
win2 = makeWindow(
false,
false,
false,
NativeWindowType.NORMAL,
true,
NativeWindowSystemChrome.NONE,
"window 2",
300,
300
);var imageSprite:Sprite = new Sprite();
imageSprite.addChild(new SampleImage());
win2.stage.addChild(imageSprite);
win2.x = targetX;
win2.y = targetY;
win2.stage.addEventListener(MouseEvent.MOUSE_DOWN, onWin2MouseDown);}
/**
* Window 2 をマウスダウンした際のイベントハンドラ関数
*/
private function onWin2MouseDown(evt:MouseEvent):void {
win2.startMove();
}/**
* 新規ウィンドウを作成するための関数
*
* @param Boolean maximizable
* @param Boolean minimizable
* @param Boolean resizable
* @param String type
* @param Boolean transparent
* @param Boolean systemChrome
*
* @return NativeWindow nativeWindow
*/
private function makeWindow(
maximizable:Boolean,
minimizable:Boolean,
resizable:Boolean,
type:String,
transparent:Boolean,
systemChrome:String,
title:String,
width:Number,
height:Number
):NativeWindow
{
var options:NativeWindowInitOptions = new NativeWindowInitOptions();
options.maximizable = maximizable;
options.minimizable = minimizable;
options.resizable = resizable;
options.type = type;
options.transparent = transparent;
options.systemChrome = systemChrome;
var nativeWindow:NativeWindow = new NativeWindow(options);
nativeWindow.title = title;
nativeWindow.stage.align = StageAlign.TOP_LEFT;
nativeWindow.stage.scaleMode = StageScaleMode.NO_SCALE;
nativeWindow.visible = true;
nativeWindow.stage.stageWidth = width;
nativeWindow.stage.stageHeight = height;
return nativeWindow;
}
]]>
</mx:Script>
<!-- Window 1 用ボタン -->
<mx:Button
id="Window1_btn"
label="window 1 を開く"
x="10"
y="10"
click="openWindow1()" />
<!-- Window 2 用ボタン -->
<mx:Button
id="Window2_btn"
label="window 2 を開く"
x="10"
y="50"
click="openWindow2()" /></mx:WindowedApplication>
じゃあ、どうやって ViewStack などで画面遷移などを管理できる MXML Component をアプリケーションの単位として制御できるんだろうと調べていたら、mx:Window という MX タグがあることにたどり着いた。これは先ほどのNativeWindow クラスで新規ウィンドを開く様に、新規ウィンドを起動することができるのだが、MXML コンポーネントとして制御できるため、この中で mx:Viewstack や mx:Canvas や mx:Script やら他の MXML タグを通常通り使える。要は、1つのアプリケーションを作っている感覚で、複数のアプリケーションを作れる訳だ。なお、結構文献はまだまだ少ないみたいで、最初、NativeWindowSystemChrome.NONE、transparent=true などで透過やフレームなしの新規画面を立ち上げるのに苦労したので、その状態にした新規ウィンドを立ち上げた例を今回は記述する。
▽ mx:Window による通常のポップアップ
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
showFlexChrome="false">
<mx:Style>
Application {
background-image: "";
background-color: "";
}
</mx:Style><mx:Script>
<![CDATA[
import view.SampleView;
import flash.display.NativeWindow;
import flash.display.NativeWindowDisplayState;
import flash.display.NativeWindowInitOptions;
import flash.display.NativeWindowResize;
import flash.display.NativeWindowSystemChrome;
import flash.display.NativeWindowType;import mx.core.Window;
public var testVar:String = "Hello World";
private var window:Window;/**
* 新しいウィンドウを起動するための関数
*/
private function openWindow():void {window = makeWindow(
SampleView,
false,
false,
false,
NativeWindowType.LIGHTWEIGHT,
true,
NativeWindowSystemChrome.NONE,
false,
false,
false,
300,
480
);
window.x = 10;
window.y = 10;
window.open();
}/**
* ウィンドウ作成用関数
*/
private function makeWindow(
ClassName:Class,
minimizable:Boolean,
maximizable:Boolean,
resizable:Boolean,
type:String,
transparent:Boolean,
systemChrome:String,
showStatusBar:Boolean,
showTitleBar:Boolean,
showGripper:Boolean,
width:Number,
height:Number
):Window
{
var window:Window = new ClassName();
window.minimizable = minimizable;
window.maximizable = maximizable;
window.resizable = resizable;
window.type = type;
window.transparent = transparent;
window.systemChrome = systemChrome;
window.showStatusBar = showStatusBar;
window.showTitleBar = showTitleBar;
window.showGripper = showGripper;
window.minWidth = width;
window.minHeight = height;return window;
}
]]>
</mx:Script><!-- 新規ウィンドを開くためのボタン -->
<mx:Button
id="Win_btn"
label="Window を開く"
x="10"
y="10"
click="openWindow()" /></mx:WindowedApplication>
【開発環境】
Flex Builder 3.0
【参考サイト】
http://www.fxug.net/modules/xhnewbb/viewtopic.php?topic_id=1353
http://livedocs.adobe.com/flex/3/langref/mx/core/Window.html











