「逆引きリファレンス」カテゴリーアーカイブ

XMLフォーマットの利用(DOMパーサー)

XMLフォーマットを扱うために、Curlでは拡張コンポーネントのWSDKにDOM(Document Object Model)機能が用意されています。DOMは、XMLをツリー構造として扱い、これを「DOMツリー」といいます。XML全体を解析してDOMツリーとしてメモリ上に保存するのでデータの多いXMLを解析する場合は多くのメモリを消費します。

ここではDOMパーサーを利用したXML解析方法について、下記サンプルXMLを用いて説明します。 

<RecordSet>
  <Record name=”AAA”>
    <Value>”123″</Value>
    <Value>”456″</Value>
  </Record>
  <Record name=”BBB”>
    <Value>”xyz”</Value>
  </Record>
</RecordSet>

DOMパーサーを使用するためには、まずWSDKをインストール及びデリゲートする必要があります。下記サンプルは、XMLから取得した値をoutputプロシージャにて結果表示させています。

XMLの読取り

XMLフォーマットをデータモデルに変換する場合、build-xmlプロシージャを使用します。build-xmlプロシージャの戻り値はXDMDocumentオブジェクトになります。build-xmlプロシージャで解析可能なデータはUrl、StringInterface、TextInputStream、ByteInputStreamです。

let xml:XDMElement = {build-xml preserve-whitespace? = true, XMLデータ}

XMLの解析

XMLを解析するために、まずXDMElementのrootでルートの要素を取得します。また、各子要素のを取得するにはget-elementsメソッドを実行します。取得した要素から属性を取得するにはattributes、テキストを取得するにはget-textを利用します。以下にコメント入りでサンプルを掲載します。

||build-xmlプロシージャを用いて、XMLをのCurlのXML構造体オブジェクトに変換します。
||更に、build-xmlの戻り値であるXDMDocumentから、そのXMLのルートとなるエレメントを取得します。

let root:XDMElement = {build-xml preserve-whitespace? = false, XMLデータのURL}.root

||以下XMLの解析
||get-elementsメソッドで、エレメントを取得します。

let record-elements:{Array-of XDMElement} = {root.get-elements}
  {for record-element:XDMElement in record-elements do
   ||attributesアクセッサで、属性を取得します。
      {output “Record attribute = “ & record-element.attributes[“name”]}
      let value-elements:{Array-of XDMElement} = {record-element.get-elements}
      {for value-element in value-elements do
     ||get-textメソッドでテキストを取得します。
        {output ” Value text = “ & {value-element.get-text}}
      }
  }

実行結果 

Record attribute = AAA
 Value text = “123”
 Value text = “456”
Record attribute = BBB
 Value text = “xyz”

 参考サイト

XML Data

Transforming XML

Using XPath

 

オブジェクトのシリアル化

オブジェクトのシリアル化(直列化)とは,オブジェクトの内部状態をバイトストリームに変換し,そのバイトストリームから再び元と同じ内容を持ったオブジェクトを再現することができる機能のことです。ただし、すべてのデータクラスをシリアル化できるのではなく、serializableとして宣言する必要があります。このような機能はJavaやActionScript(AMF0、AMF3)にもあります。

早速使い方を説明していきます。まずは、CURL.IO.SERIALIZEパッケージをインポートします。

{import * from CURL.IO.SERIALIZE}

次に対象となるデータクラスを宣言します。このクラスはserializableとして宣言します。 

{define-class public serializable AAA
  field name:#String
  field value:#String
 
  {constructor {default name:#String = null, value:#String = null}
    set self.name = name
    set self.value = value
  }
  {method public {getNameAndValue}:#String
    {return self.name & ” ” & self.value}
  }
}

シリアライズするには、SerializeOutputStreamのwrite-oneメソッドを利用します。以下の例では、ファイル(test.byte)にシリアライズしたデータ(AAA)を保存しています。 

{with-open-streams
    out:SerializeOutputStream = {SerializeOutputStream 
                                    {write-open-byte {url “test.byte”}}}
 do
    {out.write-one {AAA name = “OKADA”, value = “123”}}
}

逆にデシリアライズ(バイトストリームから元のオブジェクトを生成)するには、deserializeプロシージャを利用します。ここでは上記で作成したファイルを読み込み、オブジェクトを生成しています。 

{with-open-streams
    in:SerializeInputStream = {SerializeInputStream 
                                  {read-open-byte {url “test.byte”}}}
 do
    let read-obj:AAA = {deserialize in, AAA}
    {dump {read-obj.getNameAndValue}}
}

実行結果

{read-obj.getNameAndValue}=OKADA 123

 

コントロールの作成2

タブコンテナの作成

タブコンテナは一組の情報をいくつかのサブセットに編成します。
各サブセットはコントロール内で別々のペインに表示されます。
以下に簡単なサンプルをご紹介します。

以下にソースを示します。

{TabContainer
    {TabPane
        {text font-size = 28pt, 1}
    },
    {TabPane
        {text font-size = 28pt, 2}
    },
    {TabPane
        {text font-size = 28pt, 3}
    }
}

TabContainerはTabPaneを含みます。TabPaneは、ペインに表示されるコントロールと、
ペインの概観および動作を制御するいくつかのオプションを提供します。
TabPaneを含まないTabContainerを作成し、後からアプレットでペインを追加することもできます。
上記の例は、コンストラクタに3つのTabPaneを追加する、簡単なTabContainerを作成しています。

テキストフィールドの作成

TextFieldを使用すると、テキストをダイアログもしくはアプレットに入力することができます。
TextFieldは一度にテキストを一行表示します。
以下に簡単なサンプルをご紹介します。


以下にソースを示します。
{let last-event:Frame =
    {Frame width = 4in, margin = 2px, background = “silver”}
}
{let field:TextField =
    {TextField
        {on e:Action at tf:TextField do
            {last-event.add replace?=true,
                {format “event=%s value=\”%s\””, e, tf.value}
            }
        },
        {on e:DialogEvent at tf:TextField do
            {last-event.add replace?=true,
                {format “event=%s value=\”%s\””, e, tf.value}
            }
        }
    }
}
 
{HBox spacing = 6px,
    field,
    {CommandButton
        label = “Set Value”,
        {on Action do
            set field.value = “new value”
        }
    },
    last-event
}


テキストフィールドに入力するとTextFieldのvalueプロパティが変化し、TextField自身がTextFieldイベントを
起動します。テキストフィールド内で切り抜き、コピーまたは貼り付けを行うと、ValueChangedが起動します。
また、ENTERキーを押すと、ValueFinishedイベントが起動した後にTextField自身がActionイベントを起動し、
値の入力が完了したと解釈します。

テキスト領域の作成

TextFieldはテキストの一行のみの表示でしたが、TextAreaを使用すると複数行のプレーンテキストを
ダイアログもしくはアプレットに入力することができます。TextAreaはテキストの入力だけでなく、表示も
サポートしています。表示する複数行のテキストが所定のスペースに入りきらない場合は、
垂直スクロールバーが表示されます。
以下に簡単なサンプルをご紹介します。

以下にソースを示します。

{let experience:any,
    vb:VBox = {VBox}
}
{spaced-vbox
    background = {FillPattern.get-beige},
  {text Describe your prior experience in the space below:},
    {TextArea
        height = 2cm,
        prompt = “PRIOR EXPERIENCE: “,
        || Attach dynamic event handler
        {on ValueFinished at ta:TextArea do
            set experience = ta.value
            {vb.add
                {text
                    color = “blue”,
                    {value experience}
                }
            }
            {popup-message
                modal? = true,
                vb
            }
        }
    }
}


TextAreaのvalueプロパティの現在値は、TextArea内の現在のテキストと関連づけられています。
これをプログラムから設定すると、表示されているテキストも変化します。
入力したテキストは自動的に次の行へ折り返されます。TextAreaの形状が変化するとそれに伴って
再び折り返されます。明示的に改行を入力した場合、その改行は保持されます。
TextFieldとは異なり、TextAreaはENTERキーを押してもActionやイベントは起動せず、値の入力が
完了したとは解釈しません。代わりに、カーソルを次の行に移動してさらにデータを入力できるように
します。テキストの入力を終了するには、ウィンドウの他の部分をマウスでクリックしてフォーカスを
TextAreaの外へ移動する必要があります。
この動作によりValueFinishedイベントが起動されます。

スクロールボックスの作成

スクロールボックスは、表示したいグラフィカルオブジェクトがコンテナに完全に収まらない場合に、
コンテンツを圧縮せずに水平または垂直スクロールバーを提供します。
以下に簡単なサンプルをご紹介します。


以下にソースを示します。
  {ScrollBox

    width = 5cm,
    height = 3cm,
    {Frame
        width = 7cm,
        {text
            {paragraph
                The {monospace ScrollBox} class is used to
                contain a graphical object and provide
                horizontal and/or vertical scroll bars should
                the entire graphical object not fit entirely
                within the container.
            }
            {paragraph
                The {monospace ScrollBox} class is used to
                contain a graphical object and provide
                horizontal and/or vertical scroll bars should
                the entire graphical object not fit entirely
                within the container.
            }
            {paragraph
                Graphical options specific to the {monospace
                ScrollBox} include:
            }
        }
    }
}

ScrollBoxは、子グラフィックと呼ばれるグラフィカルオブジェクトを含むFrameの1つの型です。
したがって、直接複数の子オブジェクトを含むことができません。

ProgressBarの作成

プログレスバーは、アプリケーションで時間のかかる操作の進捗状況を視覚的に表すコントロールです。
処理の進行速度と、処理がどの程度完了しているかがわかります。
以下に簡単なサンプルを示します。

以下にソースを示します。

{let max:double = 700}
{let simple-bar:ProgressBar =
    {ProgressBar
        width = 5cm,
        min-value = 0,
        max-value = max,
        value = 0,
        caption = “Press Start to Begin”,
        {on e:ValueChanged at pb:ProgressBar do
            set pb.caption = pb.percent-complete & “%”
            {pb.update-view}
        }
    }
}
{HBox
    “Progress:”,
    simple-bar,
    {CommandButton
        label = “Start”,
        {on Action at cb:CommandButton do
            {with-busy-cursor
                {for i = 1.0 to max do
                    {simple-bar.set-value-with-events i}
                    || 待機時間を作ります。
                    {sleep .01s}
                }
            }
        }
    },
    {CommandButton
        label = “Show Popup”,
        {on Action do
            {popup-message “Message”}
        }
    }
}

一般的に、アプリケーションがファイルのコピーやドキュメントの印刷などのタスクを実行する際に
使用されます。ユーザーは、視覚的な表示がないとアプリケーションが応答していないと考える
場合があります。アプリケーションでProgressBarを使用すると、アプリケーションが長時間の
タスクを実行していて、応答中であることを示すことができます。

関連ヘルプドキュメント

Curl開発者ガイド→グラフィカルユーザーインターフェイス→タブコンテナ
Curl開発者ガイド→グラフィカルユーザーインターフェイス→テキストコントロール→テキストフィールド
Curl開発者ガイド→グラフィカルユーザーインターフェイス→テキストコントロール→テキスト領域
Curl開発者ガイド→グラフィカルユーザーインターフェイス→グラフィカルコンテナ→フレーム→スクロールボックス
Curl開発者ガイド→グラフィカルユーザーインターフェイス→その他のコントロール→プログレスバー

WSDK(Web Service Development Kit)のインストール

WSDK(Web Service Development Kit)とは、Webサービスを利用したアプリケーションをCurlで開発する為に有用なAPIがまとめられた拡張コンポーネントです。

WSDKのAPI及び機能の一覧

 ・XDM(XML Document Model:XMLのドキュメントを、その構造を保った形でCurlオブジェクト化したもの)
 ・Webサービス接続用API(SOAP通信)
 ・WSDL(Curlモジュールへのコンバージョン)
 ・XHTML/CSS解析API
 ・RSS解析用API

WSDKを使用する手順は以下の通りです。

ダウンロード

 1.ここからWSDKをダウンロードする。
 2.ダウンロードしたファイルを解凍する。

ドキュメントのインストール

Note: 下記手順は古いので、最新の8.0 IDEでは、WSDKパッケージがCURL-UTIL-V7V8-V1.1を必要となった為、WSDKダウンロードして解凍後、WSDK(WSDK-V7V8-V2.1フォルダ)のドキュメントインストール後に、UTIL(CURL-UTIL-V7V8-V1.1フォルダ)も同様にインストールする必要があります。

 1.IDEを起動する。
 2.IDEのメニューから、「ヘルプ」→「ドキュメンテーションのインストール」を選択する。
wsdk-install04.jpeg

 

  3.以下の画面にて「インストール」ボタンを押下し、解凍したディレクトリ配下のdocs-install\WSDKにあるmanifest.mcurlを選択する。
wsdk-install05.jpeg

 

 4.パッケージ名が表示されたらインストール終了。
wsdk-install07.jpeg

 

 5.ヘルプドキュメントに表示される。
wsdk-install08.jpeg

 

WSDKプロジェクトの作成

 1.IDEを起動し、プロジェクトを開く。
 2.IDEのメニューから、「プロジェクト」→「デリゲート先の追加」を選択する。
wsdk-install01.jpeg

 

 3.以下の画面にて、解凍したディレクトリ配下のwsdk-source/lib/WSDKにあるmanifest.mcurlを選択する。
wsdk-install02.jpeg

 

 4.プロジェクトに追加されるとパッケージが表示される。
wsdk-install03.jpeg

 

これで、WSDKを利用可能となります。

 

日付と時刻の利用

Curlで日付と時刻を扱うには、DateTimeクラスを利用します。

DateTime

現在時刻を表示するには、以下のようにします。

let now:DateTime = {DateTime}
{output now}

指定した時刻のDateTimeオブジェクトを生成するには、以下のようにします。 

let past1:DateTime = {DateTime “01/01/2001”}
{output past1}

let past2:DateTime = {DateTime year = 2001, month = 1, day = 1}
{output past2}

文字列への変換

DateTimeオブジェクトを文字列に変換するには、DateTimeInfoクラスを利用します。これはDateTimeクラスのinfoゲッターにアクセスすることで取得できます。

let now:DateTime = {DateTime}
{dump
    now.info.iso-date, || yyyy-mm-dd
    now.info.iso-time, || hh:mm:ss
    now.info.year,       || 年(int)
    now.info.month,    || 月(int)
    now.info.day,        || 日(int)
    now.info.hour,       || 時(int)
    now.info.minute,    || 分(int)
    now.info.second     || 秒(int)
}

2038年問題について

以下のようにDateTimeを用いた場合は2038年までしか扱うことができません。(参考Wikipedia:2038年問題

let v:DateTime = {DateTime year = 2039}

上記コードを実行すると以下のような例外が発生します。

DateTimeException: DateTimeInfo ‘2039-01-01 00:00:00.000000’ を DateTimeData に変換することができません:指定された日時が範囲外です。

これを回避するためには、キーワード引数「zone」に以下のように指定して、インスタンスを生成します。

let v:DateTime = {DateTime year = 2039, zone = {DateTimeZone mode = DateTimeZoneMode.utc}}

もしくはDateTime.dateファクトリを用いることでも回避することができます。

 

PHPでCurlコードを動的生成

サーバサイドのテクノロジーを利用して、Curlコードを動的に生成し、アプレットを実行することができます。ここではPHPの例を説明したいと思います。(もちろんASPやJSP・サーブレットでも同様のことが実現可能です。)

サンプルコードは以下のようになります。

dynamic02.jpg

必要な点は、
 1. MIMEタイプにtext/vnd.curlを指定します。(Content-typeヘッダーに左記タイプを指定)
 2. Curlのコードを出力します。(PHPの場合は、echoを使います。)

例えば、ApacheのDocumentRootに上記ファイル(例えば、curl.php)とCurlライセンスファイルを配置し、ブラウザからhttp://localhost/curl.php へアクセスしますと以下のような画面が表示されます。

dynamic01.jpg

よく出るエラーの種類と回避方法

ここでは、Curlを利用し始めた時に経験しがちなエラーとその解決方法を説明します。


メッセージ

コンテンツが、システムにインストールされていない Curl API の次のバー ジョンの 1 つを必要としています。このコンテンツを表示するには、バー ジョンのサポートに必要なコンポーネントをダウンロードし、インストールする必要があります:

原因と解決策

実行使用としたCurlアプレットに対応するCurlRTE(ランタイム)がインストールされていないことによります。対応するCurlRTEを入手しインストールしてください。


メッセージ

アプレット’http://****’をロードできませんでした。SyntaxError’http://****’規定のマニフェストをインポートできません。
SecurityException:非特権状態のアプレットは、ローカルファイル’http://****’を読み取ることは出来ません。このメッセージはアプレット内のエラーによるものです。

原因と解決策

ローカルファイルの読み込みという”特権”設定が必要な操作を行おうとしています。アプレットを信用する場合は、Curlコントロールパネルから”セキュリティタブ”を選択し、当該アプレットのホストを追加してください。


メッセージ

Error: ‘http://xxx/start.curl’
アプレットはライセンス キーを取得できません。 HttpMissingFileException:
‘http://xxx/curl-license-4.dat’ を開いている間のステータスは 404 です。

原因と解決策

Curlサーバーライセンスが正しく配置されていません。ライセンスファイルを配置してください。その後IEのキャッシュファイルをクリアし、CurlRTEが起動している場合は終了した後に、アプレットを再度実行してください。

 


 

症状

アプレットを実行するとブラウザにCurlのソースコードが表示されてしまう。

原因と解決策

原因は二つ考えられます。

  1. WebサーバーにcurlのMIMEタイプが登録されていない。
  2. CurlRTE(もしくはIDE)をインストールした後に、ブラウザをインストールした。

1の場合は、Webサーバーのマニュアルを参照してMIMEを設定してください。詳細は、Curl開発者ガイドの「Webサーバーの構成」の「CurlファイルソースのMIMEタイプ」をご覧ください。

2の場合は、再度CurlRTE(もしくはIDE)をインストールし直すことで解決します。


メッセージ

SyntaxError:xxx/yyy/start.curl規定のマニフェストをインポートできません
アプレットはライセンスキーを取得できない
HTTP Permisshon Denied File exceptionHTTP://xxx/curl-licence-5.datを開いてる間のステータスは403です。
HTTP Permisshon Denied Fileexception
HTTP://xxx/curl-licence-5.datを開いてる間のステータスは403です。

原因と解決策

ライセンスファイル(curl-licence-5.dat)に対してアクセス許可が与えられていません。アクセス権を変更してください。


メッセージ

Error: ‘any’ から暗黙的キャストは禁止(または不正使用)されています。 この作業を行う場合は、このコードを ‘{with-compiler-directives allow-implicit-any-casts? = true do <ユーザーコード>}’ でラップし、コンパイラのディレクティブをオーバーライドする必要があります。

原因と解決策

start.curlやload.scurl等のアプレット宣言部分に下記のように{compiler-directives careful? = true}が宣言されており、
{applet manifest = “manifest.mcurl”,
{compiler-directives careful? = true}
}

かつ、変数の宣言時に let aaa = xxxxのように型を宣言していないことが原因だと思われます。

対応としては、
・ アプレット宣言部分を次のように変更する: {applet manifest = “manifest.mcurl”} (compiler-directives careful? = true をはずす。)
・ let  で宣言している部分には必ず型を指定する。
・ def で宣言する

 

コレクション・クラスの利用

Curlの持つコレクション・クラスについて、説明します。

配列(FastArray-of)

Curlで配列を扱うには、FastArray-ofを利用します。FastArray-ofの宣言時に引数として、配列の型を定義します。また、配列は最大サイズを宣言時点で指定する必要があります。

def a = {new {FastArray-of int}, max-size = 3}

または

def a = {{FastArray-of int} max-size = 3} || newは省略可

{a.append 1} || 追加
{a.append 2} || 追加
{a.append 3} || 追加

{dump a[0], a[1], a[2], a.size}

データを追加する際は、appendメソッドを利用し、値を参照する場合は、変数名[インデックス]でアクセスできます。インデックスは0から始まります。

リスト(Array-of)

Javaのようなリスト(List、ArrayList)を扱うには、Array-ofを利用します。これはFastArray-ofのように、最大サイズは指定する必要がありません。 

def a = {new {Array-of int}, 1, 2, 3} || 初期値も設定

または

def a = {{Array-of int} 1, 2, 3} || newは省略可

{dump a[0], a[1], a[2], a.size}

ハッシュテーブル(連想配列)(HashTable-of)

Javaのハッシュマップ(Map、HashMap)のような連想配列を扱うには、HashTable-ofを利用します。これはキーと値をもちますので、引数にキーの型と値の型を指定する必要があります。値を参照するには、変数名[“キー名”]でアクセスできます。値をセットするには、setメソッドを利用します。

def h = {new {HashTable-of String, int}, “key1”, 1, “key2”, 2, “key3”, 3}

または

def h = {{HashTable-of String, int} “key1”, 1, “key2”, 2, “key3”, 3} || newは省略可

{h.set “key4”, 4}

{dump h[“key1”], h[“key2”], h[“key3”], h[“key4”], h.size}

コンテナループ

上記のような配列やリスト・連想配列をFor文で繰り返して、値を取得するには以下のようにin句を利用します。(連想配列の場合は、key句でキーの値も取得できます。)

|| 配列・リスト
{for v in a do
    || vに値
    {dump v}
}

|| 連想配列
{for v key k in h do
    || kにキー値
    || vに値

    {dump k, v}
}

タプル

バージョン6.0からタプルがサポートされました。これはPython等にサポートされている編集不可のコレクションクラスです。これを利用するには、Tuple2-ofTuple3-ofTuple4-ofTuple5-ofクラスを使います。具体的な例を以下に記載します。

|| Tuple2-ofの例
def t2 = {{Tuple2-of int, String} 
             1, “hoge.”
         }
{output t2[0], t2[1]} || アクセス方法は配列と同様

|| Tuple5-ofの例
def t5 = {{Tuple5-of int, int, String, String, bool}
             1, 100, “hoge”, “foo”, true
         }
{for v in t5 do
    {output v} || コンテナループも利用可能
}

メモ

ちなみにFastArray-ofからArray-ofを生成するには、Array-ofのfrom-FastArrayコンストラクタを利用し、逆にArray-ofからFastArray-ofを生成するには、underlying-FastArrayアクセサを利用します。

文字列操作

Curlの文字列クラスは、StringInterfacceを継承したStringStringBufがあります。Stringは値を代入した後は変更が不可です。逆にStringBufは値を代入した後も変更することが可能です。具体的に利用方法を以下に紹介します。

String

let str1:String = “abc”
let str2:String = {String “efg”}
set str1 = str & “efg” || 値を代入しなおす。

{output str1.size} || サイズ

{if {str1.equal? str2} then
    {output “一緒”}
}

{if {str1.prefix? “ab”} then
    {output “最初の文字列が一致!”}
}

{if {str1.suffix? “fg”} then
    {output “最後の文字列が一致!”}
}

let str3:String = {str1.substr 1, 3}

Stringクラスのequal?メソッドは文字列が一致するか否かをチェックし、boolを返します。

prefix?やsuffix?は文字列の最初もしくは最後の一部が一致するかをチェックし、boolを返します。

また、よく利用するメソッドとして、substrがあります。これは、文字列から指定した部分を切り取ります。

その他Stringのメソッド等についての詳細は、こちらを参照ください。

StringBuf 

let buf1:StringBuf = {StringBuf}
let buf2:StringBuf = {StringBuf “abc”}

{buf1.append ‘e’}
{buf1.concat “efg”}
{buf1.replace “ab”, “zz”}
{buf1.reverse}
{buf1.clear}

Stringクラスで利用できたprefix?、suffix?、substrは、StringBufでも利用できます。それ以外に、append(1文字の追加)、concat(文字列の結合)、replace(文字列の変換)、reverse(文字列の順番を逆にする)、clear(文字列をクリア)などがあります。

その他StringBufのメソッド等についての詳細は、こちらを参照ください。

 

また、StringとStringBufは以下のようなこともできます。

CSVなどのように区切り文字で分割し、それを配列に格納するためのメソッドとして、splitがあります。これは以下のように利用します。 

let str:String = “www.curl.com
let array:StringArray = {str.split split-chars = “.”}
{for a in array do
    {output a}
}

 

 

 

印刷

印刷用APIを使用することによってユーザーがプリンタの選択や、印刷設定を行えるアプレットを作成できます。

以下に、ボタンを押下すると四角形を印刷する簡単なサンプルソースをご紹介します。

{curl 6.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}
{applet manifest = “manifest.mcurl”,                                                 
   {compiler-directives careful? = true}                                       
}
{let pf:#PrintRootFrame}                                                                
{let rect:Graphic={Fill width=1in, height=1in, background=”lime”}} 
{CommandButton label=”test printing”,                                            
    {on Action do                                                                       
      set pf = {print-graphic rect}                                           
    }
}  

印刷には、print-graphicプロシージャを使用します。
Curlグラフィックをプリンタに送信するためのPrintRootFrameを使用して、印刷したいGraphicを設定します。
既定では、日付とページ番号がページの下部に印刷されます。この設定を変更するには、下記のようにPrintRootFrameを設定する際、print-date?とprint-page-numbers?をfalseに設定します。

set pf = {print-graphic rect,
                          print-date?=false,
                          print-page-numbers?=false
        }

 

 

 

関連ヘルプドキュメント

Curl開発者ガイド→グラフィカルユーザーインターフェイス→印刷

チャートの作成

チャートとは、グラフを表すオブジェクトです。グラフの種類は大きく分けて、X,Y座標を使用して2次元でプロットするグラフと、円グラフの2種類あります。

基本的なグラフの作成方法

以下のようなグラフを作成する簡単なサンプルをご紹介します。

ソースを以下に示します。

{curl 6.0 applet}           

{curl-file-attributes character-encoding = “shift-jis”}
{applet manifest = “manifest.mcurl”,
    {compiler-directives careful? = true}

}

{import * from CURL.GUI.CHARTS}

||データの作成
{let records:RecordSet =
    {RecordSet
        {RecordFields
            {RecordField “name”,caption = “名前“,domain = String },
            {RecordField “age” ,caption = “年齢“,domain = int }
        },
        {RecordData name = “John”,    age = 25},
        {RecordData name = “Jane”,    age = 29},
        {RecordData name = “Julie”,   age = 12},
        {RecordData name = “Josh”,    age = 58},
        {RecordData name = “Jon”,     age = 6},
        {RecordData name = “Damian”, age = 30},
        {RecordData name = “Nova”,    age = 41},
        {RecordData name = “Gabriel”, age = 35}
    }
}
 
||表示
{value
    {ShapeBox
        width = chart.width,
        height = chart.height,
        chart
    }
}

 

||チャートの作成
{let chart:LayeredChart =
    {LayeredChart
        width = 15cm,
        height = 6cm,
        {BarLayer
            {ChartDataSeries records, “age”},
            x-axis-data = {ChartDataSeries records, “name”},
            {DataSeriesColorPair
               {ChartDataSeries records, “age”},
                FillPattern.orange
            }
        },
        {LineLayer
            {ChartDataSeries records, “age”}
        },
        {ScatterLayer
            {ChartDataSeries records, “age”},
            {DataSeriesColorPair
                {ChartDataSeries records, “age”},
                FillPattern.orange
            }
        }
    }

}

グラフを作成するには、Chartクラスを使用します。
また、グラフのデータはRecordSetに入力してから使用する必要があります。
LayeredChartは、X座標とY座標を使用して2次元でデータをプロットするグラフです。棒グラフや折れ線グラフなどのグラフは、ChartLayerオブジェクトによって実装されます。ChartLayerオブジェクトは、データおよびそのプロット方法を定義するための抽象クラスであるため、実際にはLineLayer,AreaLayer,ScatterLayer,BubbleLayer,BarLayerといったグラフレイヤをLayeredChartに追加することにより実装します。また、1つ以上のChartLayerオブジェクトを用い、より複雑なグラフを作成することもできます。
上記の例では、以下のグラフレイヤを使用して複数のグラフを表しています。
 ・BarLayer(棒グラフ)
 ・LineLayer(折れ線グラフ)
 ・ScatterLayer(散布図)

円グラフの作成方法

次に、以下のような簡単な円グラフを作成するサンプルをご紹介します。

以下はサンプルソースです。

{curl 6.0 applet}

{curl-file-attributes character-encoding = “shift-jis”}

{applet manifest = “manifest.mcurl”,

    {compiler-directives careful? = true}

}

{import * from CURL.GUI.CHARTS}

||データの作成

{let records:RecordSet =

    {RecordSet

        {RecordFields

            {RecordField “name”,caption = “名前“,domain = String},

            {RecordField “age” ,caption = “年齢“,domain = int}

        },

        {RecordData name = “John”,   age = 25},

        {RecordData name = “Jane”,   age = 29},

        {RecordData name = “Julie”,  age = 12},

        {RecordData name = “Josh”,   age = 58},

        {RecordData name = “Jon”,    age = 6},

        {RecordData name = “Damian”, age = 30},

        {RecordData name = “Nova”,   age = 41},

        {RecordData name = “Gabriel”,age = 35}

    }

}

||グラフ作成

{AntialiasedFrame

    {PieChart

        width = 10cm,

        height = 10cm,

        {PieSet

            records,

            “age”,

            label-data = {ChartDataSeries records, “name”}

        }

    }

}

円グラフはPieChartを使用して作成します。基本的なグラフを作成する際、ChartLayerを用いてLayeredChartを構成したのと同様に、PieChartはPieSetオブジェクトを用いて構成します。また、PieChartに複数のPieSetを追加した場合は、最初のPieSetが中央に、それ以外のPieSetが追加された順に同心円状に配置されたグラフになります。

サンプルではRecordSetにデータを入力していましたが、データベースサーバーからのデータをConnectedRecordSetに入力してグラフ化することもできます。
RecordSetとConnectedRecordSetの使用については、下記をご参照ください。
Curl開発者ガイド→データの管理と表示

関連ヘルプドキュメント

Curl開発者ガイド→グラフ

高さや幅の自動伸長・圧縮設定

従来の企業システムのクライアントサーバーアプリケーションやデスクトップアプリケーションでは画面のサイズを固定(変更できないように)してエンドユーザーに提供していたものが多くありました。それは技術的にユーザーの操作によってレイアウト変更が生じた場合、中で表示されているコンテンツの配置を制御することが非常に難しく工数がかかるため提供側として断念していたという実態があります。
しかし昨今ブラウザベースのWebアプリケーションに企業システムも移行されてきて自由にブラウザのサイズを変更することが当たり前になり、提供側(開発側)はブラウザの制御を実装するのが大変になりました。その結果、スクロールを多用して見づらい画面になってしまっていました。
CurlはElastic(日本語でいうとゴムひも)という伸張圧縮技術をもっています。Curlで表現できるグラフィックオブジェクトの幅や高さにElasticを設定するとユーザーの操作に応じて自動的に伸張したり圧縮したりできます。そのため開発者はグラフィックコンテンツを作るのに幅や高さに対する制御に神経を使うことなく柔軟なレイアウトが実現できる画面を簡単に作成することができます。

make-elasticプロシージャの使い方

グラフを表示する簡単なサンプルをご紹介します。
以下のようにグラフが表示されますがブラウザのサイズを変更してもあわせて自動的に伸び縮みします。

elastic0.jpg

 

 

以下にそれぞれのボタンを使用したサンプルソースを紹介します。

{document-style PlainDocument}

||–データ部
{let records:RecordSet =
    {RecordSet
        {RecordFields
            {RecordField
                “region”,
                caption=”地域”,
                domain = String
            },
            {RecordField “M1”, caption = “1月”, domain = int},
            {RecordField “M2”, caption = “2月”, domain = int},
            {RecordField “M3”, caption = “3月”, domain = int}
        },
        {RecordData region = “東京”, M1 = 100, M2 = 140, M3 = 130 },
        {RecordData region = “名古屋”, M1 = 110, M2 = 140, M3 = 170},
        {RecordData region = “大阪”, M1 = 140, M2 = 100, M3 = 130},
        {RecordData region = “福岡”, M1 = 160, M2 = 190, M3 = 140}
    }
}

||–チャート
{let chart:LayeredChart =
    {LayeredChart
||–        width = 10cm,
||–        height = 6cm,
        {BarLayer
            stacking-mode = ChartStackingMode.stacked,
            {ChartDataSeries records, “M1”},
            {ChartDataSeries records, “M2”},
            {ChartDataSeries records, “M3”},
            x-axis-data = {ChartDataSeries records, “region”}
        }
    }
}

||–表示部分
{value
    {ShapeBox
        margin=5pt,
        width={make-elastic preferred-size=1m},
        height={make-elastic preferred-size=1m},
        chart
    }
}

 

上記の例ではデータ定義とチャート定義、表示部分があります。
チャートの作り方とデータ(RecordSet)については以下を参照ください。

 「Curl開発者ガイド → データの管理と表示
 「Curl開発者ガイド → グラフ

チャートに固定の大きさを指定した場合はブラウザの大きさを変更しても大きさは変更されませんが、チャートを含んでいるShapeBoxのwidthとheightの部分が”make-elastic”プロシージャを使用しています。”make-elastic”プロシージャを使用すると自動的に親のオブジェクトに合わせて自動的に伸張・圧縮することができます。
一方、オブジェクトの幅と高さの動作を指定したい場合もあります。その場合は固定の高さ・幅(例えば10ptや1mなどのDistance)を設定します。

複合的な画面の設定

次のサンプルではmake-elastricプロシージャを使って、いくつかのグラフィカルオブジェクトを組み合わせてそれぞれのオブジェクトのサイズの割合を制御するものです。
通常Curlで作られる画面では複数のグラフィカルオブジェクトが組み合わさって作られます。
以下の例ではグラフィカルオブジェクトが階層構造になっています。
この画面は青のFrameと黄色のFrameが常に1:4の割合で伸張圧縮します。
したの白黒の部分は1:4を確認するためのスケールとしてHBoxにFillを組み合わせて作っています。白黒のFillは等間隔で伸張します。

elastic1.jpg

下のように画面サイズをユーザーが変更すると常に1:4で青と黄色のFrameが伸張圧縮するのが分かると思います。

elastic2.jpg

 

{curl 6.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}
{document-style PlainDocument}

{value
    {VBox
        width={make-elastic preferred-size=10cm},
        margin=5pt,
        background=”red”,
        {HBox
            margin=5pt,
            background=”green”,
            width={make-elastic
                      preferred-size=10cm},
            {Frame
                background=”blue”,
                height={make-elastic},
                width={make-elastic
                          stretchiness=1
                      }
            },
            {Frame
                background=”yellow”,
                height={make-elastic},
                width={make-elastic
                          stretchiness=4
                      }
            }
        },
    
        {HBox
            margin=5pt,
            background=”aqua”,
            {Fill height=5mm, width={make-elastic preferred-size=1cm},background=”white”},
            {Fill height=5mm,width={make-elastic preferred-size=1cm},background=”black”},
            {Fill height=5mm,width={make-elastic preferred-size=1cm},background=”white”},
            {Fill height=5mm,width={make-elastic preferred-size=1cm},background=”black”},
            {Fill height=5mm,width={make-elastic preferred-size=1cm},background=”white”},
            {Fill height=5mm,width={make-elastic preferred-size=1cm},background=”black”},
            {Fill height=5mm,width={make-elastic preferred-size=1cm},background=”white”},
            {Fill height=5mm,width={make-elastic preferred-size=1cm},background=”black”},
            {Fill height=5mm,width={make-elastic preferred-size=1cm},background=”white”},
            {Fill height=5mm,width={make-elastic preferred-size=1cm},background=”black”}
        }}
}

ソースコードを見ると全体を伸張させるために赤のVboxと緑のHBoxのwidth(幅)にそれぞれmake-elasticプロシージャが設定されていますが青のFrameと黄色のFrameのwidth(幅)へのmake-elasticプロシージャの設定にはstrechinessというパラメータが設定されています。
このstretchinessというパラメータは日本語でいいますと「伸張係数」といいますが分かりやすく言いますと伸張圧縮の割合を設定することができます。
青の設定は“1”で黄色の設定は“4”となっており、つまり1:4の割合で伸張圧縮することになります。
それぞれの値を変更すると伸張圧縮のしかたが変わりますので色々試してみてください。
そのほかにも様々なパラメータがありますのでヘルプCurl開発者ガイドで確認してみてください。

 

サンプルコードのダウンロード

 サンプルソース

関連ヘルプドキュメント

Curl開発者ガイド→グラフィカルユーザーインターフェイス→エラスティックとページレイアウト
 

正規表現の利用

正規表現とは文字列のパターンを表現する手法です。
Curl言語は Perl プログラミング言語の高レベルの正規表現構文を採用しており、多くの異なる種類のデータ抽出やレポート作成タスクに適しています。

正規表現を Curl 言語で使用するためには、import を使用して正規表現パッケージをインポートする必要があります。具体的には CURL.LANGUAGE.REGEXPパッケージをインポートすることで正規表現の比較 regexp-match? マクロが使用できるようになります。
 
 
{import * from CURL.LANGUAGE.REGEXP}
 
では、具体的な正規表現の方法を見てみましょう。ここでは、[開発者ガイド-逆引きリファレンス-イベント-バリデーションチェック]のサンプルコードで使用している正規表現を使って説明します。
 
{define-enum PhoneValidationPattern
    ||携帯電話を含む正規表現
    ja-phone-number = |”(0dd?-?d{4}-?d{4})|((0dd?)d{4}-d{4})|(0d{3}-dd-d{4})|(0dd-d{3}d?-d{4})|(0dd?(d{4})d{4})”|
}

構文 意味
((0dd?)d{4}-d{4})|(0d{3}-dd-d{4})

|(パイプ)で区切られた左右どちらかの正規表現を含む文字列とマッチします。

d 1つの数値とマッチします。
d{4} 4つ連続した数値とマッチします。
d? 数値がない、あるいは1つの数値とマッチします。
-? -を含まない、あるいは1回含む部分文字列とマッチします。
( (を認識させるために (エスケープシーケンス)をつけています。
 
 
以下は、リファレンスです。
 

一文字のマッチング-ワイルドカード使用による正規表現

構文  意味
.

改行文字以外の任意の文字とマッチします。

d 任意の数字とマッチします。
D 数字以外の任意の文字とマッチします。
s 任意の空白文字とマッチします。
S 空白以外の任意の文字とマッチします。
w 単語を構成する任意の文字とマッチします。
W 単語を構成する文字以外の任意の文字とマッチします。

繰り返しを含むマッチング

構文 意味
regexp* regexp (正規表現) を 0 回以上連続して含む部分文字列とマッチします。
regexp+ regexp を 1 回以上連続して含む部分文字列とマッチします。
regexp? regexp を含まない、あるいは 1 回含む部分文字列とマッチします。
regexp{m,n} regexp を m 回以上、n 回以下連続して含む部分文字列とマッチします。
regexp{m,} regexp を m 回以上連続して含む部分文字列とマッチします。
regexp{n} regexp を n 回連続して含む部分文字列とマッチします。

文字列内の任意の位置に対するマッチング

^ 行頭の直前の空白とマッチします。
$ 行末の直後、または文字列の末尾の改行の直前の空白とマッチします。
A 文字列の先頭の直前とマッチします。
Z 文字列の末尾の直後、または文字列の末尾の改行の直前とマッチします。
z 文字列の末尾の直後とマッチします。
b 単語の境界、つまり単語を構成する任意の文字とそれ以外の文字の間の空白とマッチします (文字列の先頭と末尾の範囲外にある存在しない文字は、単語を構成しない文字として扱われます)。
B b とマッチしない任意の空白とマッチします。
 
 
正規表現に関しては、IDEの[Curl開発者ガイド→基本概念-ライブラリ→正規表現]で実際に文字列を操作しながら確認することが最も理解が深まると思いますので、IDEを持っている方は、ぜひ試してみてください。

関連ヘルプドキュメント

Curl開発者ガイド→基本概念-ライブラリ→文字列→文字列での作業→文字列の検索→正規表現

Curl開発者ガイド→基本概念-ライブラリ→正規表現

バリデーションチェック

Validationとは、入力フィールドに入力された値が、一定の規則にしたがっているかをチェックする機能です。

Curlでは、このチェックをサーバ側ではなくクライアント側で行うことが可能です。全てのフォームを入力して[送信]ボタンを押したら間違いが・・・・というような状況を回避し、ユーザーエクスペリエンスの向上を実現することが可能です。

ここでは、個別フィールドに対してのValidationチェックを紹介していきます。

個別アイテムのValidationチェック

 まずは、色々な検証フィールドを見てみましょう

||数値検証
{let numeric-val:TextField =
    {TextField
        width = 3cm,
        {validate-with
            {NumericValidator},
            message = “年齢は数値で記入してください。”
        }
    }
}
||文字列検証
{let string-val:TextArea =
    {TextArea
        height = 3cm,
        width = 3cm,
        {validate-with
            {StringValidator max-chars=30},
            message = “コメントは30文字以内です。”
        }
    }
}

Curlでの検証機能には、validate-with プロシージャを使用します。その中で、Validatorクラスの引数を指定して、検証する法則を決定します。

上記の検証では、1つ目が数値(NumericValidator)、2つ目が文字列の検証(StringValidator)を行っています。文字列では、最小文字数(min-chars)や、最大文字数(max-chars)を設定することが可能です。

では、次の例を見てみましょう

||正規表現検証
{let phone-val:TextField =
    {TextField
        width = 3cm,
        {validate-with
            {RegExpValidator.from-ValidationPattern ValidationPattern.ja-phone-number},
            message = “電話番号が不正です。”,
            dialog-on-finished? = true
        }
    }
}

||正規表現検証2
{let md:MessageDisplay = {MessageDisplay}}
{let email-val:TextField =
    {TextField
        width = 3cm,
        message-display = md,
        {validate-with
            {RegExpValidator.from-ValidationPattern ValidationPattern.email-address},
            message = “メールアドレスが不正です。”
        }
    }
}
||ドメイン検証
{let md2:MessageDisplay = {MessageDisplay}}
{let domain-val:TextField =
    {TextField
        width = 3cm,
        message-display = md2,
        {validate-with
            {DomainValidator {StandardDateDomain}},
            message = “日付は、[日/月/西暦]の形式で記入してください。”
        }
    }
}

 

RegExpValidator クラスは、正規表現に基づいた検証を行います。今回はfrom-ValidationPatternコンストラクタを使用し、標準APIに組み込まれているValidationPattern という列挙型のクラスを使用しています。正規表現については、[逆引きリファレンス-データ操作-正規表現]をご覧ください。

DomainValidator クラスは、ドメイン(データ型から生成されます。例えばString,int,Time等の型を指します)の検証を行います。今回は日付のみの検証を行うために、StandardDateDomain クラスを使用しています。

以下のサンプルコードをダウンロードして、実際の挙動をお確かめください。(現状では、ValidationPatternのja-phone-numberに携帯電話の番号が対応していませんので、サンプルコードにて携帯電話用を検証可能な正規表現の列挙型を追加しておきました。)

ソースサンプル

色々な検証

関連ヘルプドキュメント

開発者ガイド-グラフィカル ユーザー インターフェイス – ガイアログとコントロール – コントロールにおけるデータ検証

APIリファレンス – CURL.GUI.CONTROL – VALIDATION – validate-with

APIリファレンス – CURL.GUI.CONTROL – VALIDATION – validate-dialog

APIリファレンス – CURL.GUI.CONTROL – VALIDATION – ValidationPattern

ActiveXを使用したExcelデータの操作

一般的なWebアプリケーションからアクセスされるコンテンツはWebサーバーを通じたデータベース内のデータなどです。
しかしCurlはそれらの一般的なサーバーサイドにあるデータでなくローカルディスク上のデータにもアクセスすることができます。
通常のテキストデータやバイナリデータではなく(※)ローカルマシンにインストールされたアプリケーションに依存したファイルなどにアクセスする必定があり場合があります。例えば以下のようなコンテンツです。

  • Microsoft Excel ,Word ,PowerPoint ,VISIO
  • Flashムービー
  • CAD
  • Browserコンロール

上記のようなコンテンツにアクセスする場合は提供されているActiveXコントロールを使用してデータを読み込んだり、または再生したりすることができます。
今回はCurlアプリケーション上に表示されているRecordGrid(一覧形式のインタフェース)からExcelファイルに出力するサンプルを解説していきます。

activex.jpg

※ テキストファイルやバイナリファイルのアクセスについては以下を参照ください。

ActiveXObjectの作成

サンプルソースの7行目に以下のような記述があります。

 

  let obj_Excel:ActiveXObject =
        {ActiveXObject
            ProgId = “Excel.Application”
        }

Excelのような外部コンテンツとやり取りを行うにはまず、ActiveXObjectクラスを使用してExcelアプリケーションのActiveXObjectのインスタンスを生成します。
ちなみにMicrosoft Office 2003、Microsoft Office 2007で確認しましたがExcelのプログラムIDは”Excel.Application”です。

ActiveXObjectのメソッドやプロパティの使用

ActiveXオブジェクトのインスタンスが生成されたらあとはそのメソッドやプロパティを使用してコンテンツを制御することができます。
11行目から32行目までの処理はExcelのマクロの処理をCurlで記述しただけです。
ちなみ以下のセルのボーダーの設定をしている部分を
Curlで記述してる部分とExcelマクロで書いてる部分を比較してみましょう。

 

|| Curlの場合

    set {obj_Excel.Range “A2″,”C14”}.Borders.LineStyle = 1
    set {obj_Excel.Range “A2″,”C2”}.Borders.weight = 4
    set {obj_Excel.Range “A2″,”C2”}.Interior.ColorIndex=12

 

‘  Excel マクロの場合

    Range(“A2:C14”).Borders.LineStyle = 1
    Range(“A2:C2”).Borders.LineStyle = 4
    Range(“A2:C2”).Interior.ColorIndex = 12

 ほとんど同じ記述をしていることがわかります。
このようにActiveXObjectを使用して外部コンテンツをコントロールすることができます。

CurlからExcelファイルの生成とデータの出力

サンプルソースは以下の流れになっています。

1.ボタンを押し出力ファイルを選択する

80行目のCommandButtonの部分で実装しています。84行目のchoose-fileプロシージャを使用してファイル選択ダイアログを出力し、
choose-fileプロシージャの返却値(Url)を6行目で定義されたrecords-to-excelプロシージャに渡しています。

 

{CommandButton
    label=”Excel出力”,
    {on Action do
        let file-url:#Url
        {if-non-null file-url={choose-file
                                  style = FileDialogStyle.save-as,
                                  filters={{Array-of FileDialogFilter}
                                              {FileDialogFilter
                                                  “Microsoft Office Excel ブック”,
                                                  {new
                                                      {Array-of FileDialogTypeFilter},
                                                      {FileDialogTypeFilter “xls”}
                                                  }
                                              }
                                          }
                              } then
           
            {records-to-excel file-url.name,”海外ドラマ「HEROS」のキャスト”,rg.records}
        }
    }
}

2.Excelファイルが生成され保存される。

Excelファイルを生成し、データを出力する部分がrecords-to-excelプロシージャです。このプロシージャはパラメータとして以下を受け取っています。

  • ファイル名(String)
  • タイトル名(String)
  • レコードデータ(RecordView)

 

define-proc {records-to-excel str_FileName:String,title:String,records:RecordView}:void

メインの処理は3番目のレコードデータを35行目のロープ処理で1行づつ出力しているところです。それ以外は罫線や背景を設定しています。 

 

let i:int=3
{for r in records do
    set {obj_Excel.Cells i,1}.Value = {r.get “First”}
    set {obj_Excel.Cells i,2}.Value = {r.get “Last”}
    set {obj_Excel.Cells i,3}.Value = {r.get “Power”}
    set {obj_Excel.Cells 1,3}.ColumnWidth = 40
    set i = i + 1
 }

 

注意事項

  • AcitveXの削除
    ActiveXObjectは削除しない場合はガベージコレクションでされない限りメモリ上に残ってしまいますので処理の終了時にActiveXObjectを削除することをお勧めします。
  • クライアントマシンに依存するActiveXコントロール
    またActiveXコントロールはクライアントマシンの環境に依存するためActiveXコントロールの有無やバージョンなども十分に考慮し使用することをお勧めします。
  • セキュリティについて
    ActiveXコンロールはクライアント資源の一つです。クライアント資源にアクセスするにはセキュリティレベルを解除する「特権」を 付与しなければなりません。

詳しくはこちらをご覧ください。
Curlのセキュリティモデルについて」(Curl Blog)
チュートリアル-開発準備編-セキュリティの設定(特権設定)」 

 

サンプルコードのダウンロード

関連ヘルプドキュメント

Curl開発者ガイド→グラフィカルユーザーインターフェイス→ActiveXコントロール

Ajax連携(JavascriptからCurlのメソッドをコール)

Curl6.0からAjax相互運用性という機能が追加されました。これはJavascriptからCurlのメソッドをコールしたり、またはその逆でCurlからJavascriptの関数をコールすることができます。この機能を用いれば、GoogleMapのAPIをコールしてGoogleMapと組み合わせたアプリケーションなどを作成することができます。この機能をサンプルコードを元に説明していきます。

JavascriptからCurlのメソッドをコールする

Javascriptから、sharp.curlというCurlアプレットの中にあるMySharpクラスのchange-colorメソッドを実行するという例を紹介していきます。

まずは、Curl側のサンプルコード(sharp.curl)から説明していきます。以下のサンプルは、単純にRectangleSharpクラスを継承して四角形の図を表示するMySharpクラスを作っています。そのMySharpクラスの中に色を変更するchange-colorメソッドを作成し、このメソッドを後述するJavascriptから呼び出すこととします。

また、このオブジェクトを生成した後、Javascriptから実行可能なオブジェクトとして登録するために、自アプレットのハンドラとして登録する必要があります。これにはregister-applet-invoke-handlerメソッドを利用します。この行が存在しませんとJavascriptから実行することはできません。

{curl 6.0 applet}

{import * from CURL.GUI.SHAPES}

{define-class MyShape
  {inherits RectangleShape}
 
  {constructor {default …}
    {construct-super …}
  }
 
  {method public {change-color color:String}:#String
    set self.color = color
    {return “changed-color”}
  }
}
 
{value
    let shape =
        {MyShape
            {GRect 1cm, 1cm, 1cm, 1cm},
            color = “orange”,
            border-color = “silver”,
            border-width = 5px
        }
   
    {{get-the-applet}.register-applet-invoke-handler
        {Applet.applet-invoke-handler-for-object shape},
        || Allow ANY page to host this applet and send it commands.
        verifier = {proc {}:bool {return true}}
    }
   
    shape
}

次にHTML側を説明します。まずは、CurlのアプレットをHTML内に埋め込む場合は、objectタグを利用します。objectタグをサポートしていないブラウザの場合は、embedを利用します。

<object id=”shape” type=”text/vnd.curl”
  data=”sharp.curl” height=”200″ width=”200″>
</object>

このJavascriptオブジェクトのapplet_invoke関数を使って先ほど登録したCurlオブジェクトのメソッドを呼びます。 

var shape = document.getElementById(“shape“);
shape.applet_invoke(“change-color”, color);

また、その他に用意されているJavascriptオブジェクトの関数・フィールドとして、Curlアプレットの呼び出し準備が整っているか否かをチェックするためのapplet_invoke_readyフィールドと、アプレットの呼び出し準備が整った際に実行されるapplet_invoke_ready_callback関数があります。具体的な使い方を見せるためにすべてのコードを以下に載せておきます。

<html><head><title>Javascript sample</title>

<script type=”text/javascript”>

// change color
function changeColor(color) {
  var shape = document.getElementById(“shape”);
  if (shape.applet_invoke_ready)
  {
    alert(shape.applet_invoke(“change-color”, color) + ‘ to ‘ + color);
  }
  else
  {
    alert(“not ready”);
  }
}

function onLoad()
{
  var shape = document.getElementById(“shape”);
  shape.applet_invoke_ready_callback =
      function() {
          if (!shape.applet_invoke_ready)
          {
              alert(“not ready!”);
          }
      };
};

</script></head>
<body onload=”setTimeout(‘onLoad()’, 0)”
  onpageshow=”if (event.persisted) setTimeout(‘onLoad()’, 0);”>
<object id=”shape” type=”text/vnd.curl”
  data=”sharp.curl” height=”200″ width=”200″>
</object>

<p>
Color
<select id=”color” onchange=”changeColor(value)”>
  <option value=”red”>red</option>
  <option value=”orange” selected=”selected”>orange</option>
  <option value=”yellow”>yellow</option>
  <option value=”pink”>pink</option>
  <option value=”lightsalmon”>lightsalmon</option>
  <option value=”orchid”>gray</option>
</select>
</p><p>

</p></body></html>

CurlからJavascript関数をコールする

CurlからJavascriptの関数を呼び出す場合、AppletDataクラスのapplet-invoke-asyncメソッドを実行します。以下に呼び出し方のサンプルコードを載せておきます。

let ad:AppletData = {AppletData …}
{ad.applet-invoke-async
    finish-proc =
        {proc {ex:#Exception, result:any}:void
             || 終了処理
        },
    “change-color”,  || 呼び出すjavascriptの関数
    “green”         || 呼び出すJavascriptの関数の引数
}

 

関連サンプル

GoogleMapと組み合わせたサンプルはCurlをインストールすると、以下のディレクトリに提供されます。(等サンプルはLinuxやMAC版も同様にも含まれています。)

C:\Program Files\Curl Corporation\Surge\7\docs\default\examples\dguide\subapplets.zip

 

スタイルコントロールの使い方

スタイルコントロールは、Curlのバージョン6.0から追加された機能です。

スタイルコントロールを使うことにより、簡単にCurlアプレットの見た目(色やグラデーション)を自由に変更することができます。

1.スタイルコントロールのインストールとダウンロード

スタイルコントロールのインストールとダウンロードについては、「クイックスタート:デザインを変更してみる ~ スタイルコントロールの利用」を参照してください。

2.新規プロジェクトの作成と、スタイルシートの適用

IDEの[ファイル]→[新規プロジェクトの作成]を選択し、2番目のアプレット プロジェクトを選択してください。以下のように設定を行います。

マニフェスト名=スタイルシートサンプル
ディレクトリ=c:curlstyle-control-sample
APIバージョン=6.0

[スタイル シート の設定]を選択し、スタイル シートの使用にチェックを入れます。パッケージ、コンポーネント名については既定のままで結構です。

上記の設定後、[OK]ボタンを押します。

start.curlには、スタイル シート適用に必要な以下の2文が記述されているかと思います。

{import * from COM.CURL.GUI-STYLED-CONTROLS}

{install-style-sheet
{manifest-url “file”, “DEFAULT-STYLE-SHEET”}
}

まだこの段階でアプレットを実行してもエラーが出てしまいます。スタイル コントロールの機能を使うには、必ずスタイルコントロールライブラリのマニフェストファイルを、プロジェクトのデリゲート先に追加しなければいけません。

IDE の [プロジェクト] から [デリゲート先の追加] を選択してインストールしたスタイルシートのマニフェストファイル(manifest.mcurl)を指定してください。

start.curlに以下のコードを追加します。

{TextField} これは TextField です

{CommandButton} これは CommandButton です

これは RichTextArea です{br}
{RichTextArea height = 2in}

これはTabPaneです
{TabContainer
{TabPane
{text font-size = 28pt, 1}
},
{TabPane
{text font-size = 28pt, 2}
},
{TabPane
{text font-size = 28pt, 3}
}
}

保存し、実行してみます。
いかがでしょうか?下図のようにスキンが適用されている画面が見えるかと思います。

3.スタイルシートのカスタマイズ

次に、スタイルシートのカスタマイズとその適用方法をご紹介します。

Curl.incでは、見ばえのカスタマイズを簡単に行うことができるツール(スタイルデザイナー)を提供しています。

このツールを使って独自のスタイルシートを作成してみましょう。

スタイルデザイナー

下図は、スタイルデザイナーの画面紹介です。

style-designer-disp.jpg

左側のプロパティ変更パネルを操作すると、右側の結果確認パネルにその変更が反映されます。

一通りの設定が終わりましたら、[File]→[Write Style Sheet]をクリック、書き込みを許可するポップアップが出てきますので、OKを選択します。(*http://developers.curl.comに特権をつけてない場合にこのポップアップがでてきます。特権の設定方法については「チュートリアル:セキュリティの設定(特権設定)」を参照してください。)

ファイル名=my-style-sheet
ディレクトリ=c:curlstyle-control-sample

としてファイルを保存します。以下のようなポップアップが出てきた場合は、[OK]を押してください。(ここでは、特権についての説明は省略します。)

C:curlstyle-control-sample直下にmy-style-sheet.scurlが作成されていることを確認してください。

次に、プロジェクトにもどり、プロジェクトのマニフェストファイル(manifest.mcurl)に以下のコードを追加します。このことにより、作成したファイルの位置情報がこのプロジェクトに登録されます。(マニフェストの詳細は、ヘルプドキュメントを参照)

{component file MY-STYLE-SHEET,
location = “my-style-sheet.scurl”
}

start.curlに移り、

{install-style-sheet
{manifest-url “file”, “DEFAULT-STYLE-SHEET”}
}

の部分を

{install-style-sheet
{manifest-url “file”, “MY-STYLE-SHEET”}
}

に変更します。

マニフェストファイル、start.curlファイル共に保存し、実行します。

いかがでしょうか?先ほどと違う色、グラデーションで見えていますでしょうか?

以上がスタイルシートの作成、適用方法です。

サポートバージョン

Curl ver 6.0以上

関連ヘルプドキュメント

式とコメント

{Curly Bracket}

式とは基本的にCurl言語のコマンドを指します。Curlではほとんどの式が{と}で囲まれるようになります。そもそもCurlの名前の由来は、この”{“(Curly Bracket)からきています。式の中に式を記載する場合は、さらに{と}で囲むこととなります。そのため、式を囲むブラケットの数でコードのレベルを示すこととなります。

{define-proc {my-proc}:void
  {message-box “ABC”}
}

{my-proc}

 

value式

value式は、複数のコードを記載し、最後の部分式の値を結果として画面や変数へ返します。

{value
    let v = 1 || この式は{let v = 1}と記載することも可能です。
    set v = 2 || この式は{set v = 2}と記載することも可能です。
    v
}

実行結果
  2

 

do式

do式は、valueと似ていますが、doは結果を返しません。

{do
    let v = 1 || この式は{let v = 1}と記載することも可能です。
    set v = 2 || この式は{set v = 2}と記載することも可能です。
}

実行結果
 結果なし

 

コメント

Curlでの1行コメントは、||を利用します。複数行のコメントには|##|で囲みます。

{do
    let v = 1 || 1行のみコメント
    |#
        複数行コメント
    #|
}

 

透明な画面

Curlアプレットの透明な画面(View)の作り方です。これはCurl6.0からViewの不透明度を設定することが可能になり実現することができるようになりました。これにより透けたViewを作ることができます。

利用するにはViewクラスのset-opacityメソッドを利用します。

{View.set-opacity opacity:FloatFraction}

この一行を実行するだけで任意の透明度のViewが作成できます。opacityには、0(完全な透明)から1(不透明)を指定できます。

transparent01.jpg

 

全ソースコード 

{curl 6.0 applet}

{import * from CURL.GUI.SHAPES}
{value
    def view =
        {View
            visibility = “normal”,
            width      = 10cm,
            height     = 10cm,
            background = “blue”,
            valign     = “center”,
            halign     = “center”,
            {italic
                font-weight = “bold”,
                font-size   = 25pt,
                color       = “white”,
                View Opacity Sample
            }
        }
    {view.set-opacity .6 asa float}
    {view.show}
}

 

サポートバージョン

Curl6.0以上

 

サーバ・データベース操作(MySQL、Oracle)

Curlではデータベースサーバに接続し、RecordSetを生成することができる機能を持っています。これは、CDBC(Curl DataBase Connectivity)と呼ばれており、下図のようにJDBC経由でCurlからOracleやMySQLなどのサーバサイドデータベースに接続することができます。

cdbc01.jpg

 

この機能の操作方法を説明していきます。

事前準備

これを利用するには、以下のものが必要となります。

  • Javaサーブレットエンジン:Tomcat or JBoss
  • データベースサーバ:MySQL or Oracle
  • JDBCドライバ

これらのセットアップ及びserver.xml等のセッティング方法は、以下のページを参照してください。

サーブレットエンジンの構成

RecordSetの作成

まずは、CDBCを利用するために2つのパッケージをインポートします。 

{import * from CURL.DATA-ACCESS.BASE}
{import * from CURL.DATA-ACCESS.CONNECTED}

次にデータベースに接続するために、Connectionクラスを継承したBasicConnectionクラスのインスタンスを生成します。この際、BasicConnectionのコンストラクタの引数にCDBCサーバのURLを渡します。 

def conn:BasicConnection =
    {BasicConnection {url http://localhost:8080/cdbc-servlet/CdbcServlet}}

単純にRecordSet(ここではConnectedRecordSetを継承したCDBC用クラスのBasicCeoonectedRecordSet)を生成するには、BasicConnectionのcreate-record-setメソッドを実行します。この引数には、データベース名とテーブル名(もしくはSQL文)を指定します。以下の例では、RecordGridに表示させています。

{RecordGrid
    record-source = {conn.create-record-set “example”,”employee”}
}

SQL文の実行

SQL文を実行する際、create-record-setを用いて、select文よりRecordSetを取得できます。

{RecordGrid
    record-source = {conn.create-record-set “example”,”select * from employee“}
}

それ以外に、insert、update、delete、create、drop等のSQLを実行する際は、BasicConnection.executeメソッドを実行します。このメソッドは一度に複数のSQL文も実行することができます。

{conn.create-record-set “example”, “delete from employee“}

直接SQL文を実行しなくても、BasicConnectedRecordSetのappend等のメソッドを用いたり、RecordGridの操作で、自動的にSQLを生成し、データの追加・更新・削除等を行いことができます。

データベースメタ情報の取得

いくつかのデータベース・メタ情報を取得するConnectionクラスのメソッドを以下に記載します。

メソッド名 説明
get-database-names 操作できるデータベースの一覧を取得できます。
get-tables 操作できるテーブル一覧を取得できます。
get-fields 対象テーブルのカラム情報を取得できます。(カラム名、サイズ、キー、タイプ等)
get-keys キーの一覧を取得できます。

 

その他機能

Curl6.0からいくつかの機能(圧縮、非同期通信、認証、独自バイナリフォーマット通信など)が追加されました。それらの一部を紹介します。

大量データを扱う場合に、パフォーマンスを向上させるための方法として、2つサポートしています。1つはHTTP圧縮機能です。これを用いますとサーバとの通信時に自動的に圧縮・解凍され、トラフィックが低減されます。利用するには、BasicConnectionのインスタンス生成時にcompress?キーワード引数にtrueをセットします。 

def conn:BasicConnection =
    {BasicConnection
        {url http://localhost:8080/cdbc-servlet/CdbcServlet},
        compress? = true
    }

もう一つのパフォーマンス向上機能として、通信フォーマットのシリアル化があります。通常CDBCはXMLで通信を行いますが、通信及びパースの高速化を行うため、Curl独自バイナリフォーマットのシリアル化・デシリアル化を自動的に行うという機能がサポートされました。これは通常のXMLと比べ5分の1から10分の1程度のスピードアップします。(ただし、データ量やデータ内容などによりスピードアップ率が変わる可能性があります。)これを利用するには、BasicConnectionのインスタンス生成時にserialize?キーワード引数にtrueをセットします。下位互換のためデフォルトはfalseとなっていますが、基本的にはこのパラメータをtrueにすることをお勧めします。

def conn:BasicConnection =
    {BasicConnection
        {url http://localhost:8080/cdbc-servlet/CdbcServlet},
        serialize? = true
    }

その他の機能として、非同期通信及びrealmを利用した認証があります。どちらもBasicConnectionのインスタンス生成時にキーワード引数として指定します。非同期通信の場合には、async?、realm認証の場合にはusernameとpasswordを指定することにより、この機能を利用することができます。

また、JDBCで扱われるデータタイプのほとんどが、Curlのデータタイプに自動的にマッピングされますので、開発者は簡単にアプリケーションの開発を行うことができます。例えば、Curl6.0からサポートされた機能ですと、OracleのBLOBタイプをCurlのByteArrayにマッピングしてくれます。

関連ドキュメント

データベースからレコードデータを取得

クライアントデータベース(SQLite)