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

RecordSetを使用したデータハンドリング

Curlでは、構造化データを扱う際は、基本APIのRecordSetを使用します。RecordSetを使用することで、1つ以上のデータベースから取得したデータを、クライアント側でDBを操作するようにフィルタリングやソート等の処理を行うことが可能になります。

RecordSetは”deta centric”なアプリケーションには必須のAPIです。

RecordSet Data

RecordSetはRecordの集合を保持しています。各Recordは事前に定義されたキー(カラム)に対しての値を保持しています。カラム構造はフィールド定義(RecordfieldとRecordFieldsを使います)によって定義されます。

/wiki/samples/images/RecordSet.jpg

Curlでは、RecordSetを作成するのに、2種類の方法があります。
1.プログラミングにより生成する方法
2.CSV形式のファイルデータを読み込み生成する方法

また、CurlAPIにはデータベース、もしくはリモートのデータファイルと直接接続できるものもあります(RecordSetを使用したデータハンドリング:2 でご紹介いたします。)

プログラミングによりRecordSetを生成する方法

他のCurlオブジェクトと同じように、RecordSetもコンストラクタを呼び出し、引数を使うことでインスタンスを生成します。

・RecordFieldsはRecordFieldの集合体を定義するために使用されます。各RecordFieldの記述は各カラムの名前とデータ型を宣言しています。)
・RecordDataオブジェクトは1組のレコードの値を操作、管理するために使用されます。

 

{curl 5.0, 6.0 applet}

{value
   let items:RecordSet =
       {RecordSet
           {RecordFields
               || 各フィールドの名前や使用するデータ型(ドメイン)を定義
               {RecordField “Item”, domain = String},
               {RecordField “Description”, domain = String},
               {RecordField “Quantity”, domain = int}
           },
           || 各フィールドに値を代入したレコードを定義、RecordSetに代入しています。
           {RecordData Item = “PR1400”, Description = “Blue pens”, Quantity = 12},
           {RecordData Item = “LG4597”, Description = “Envelopes”, Quantity = 100},
           {RecordData Item = “NP3400”, Description = “Notepads”, Quantity = 6},
           {RecordData Item = “PN5601”, Description = “Pencils”, Quantity = 28}
       }
  ||RecordSetを表形式で表します
   let record-display:RecordGrid =
       {RecordGrid
           record-source = items
       }
   record-display
}

 

*基本のドメインは次のCurl型によって定義されています。: char, String, int, int64, float, double, bool, DateTime, Time, or any

 CSV形式のファイルデータを読み込み生成する方法

CSVは、データをカンマで区切って並べたデータ形式であり、大量のデータを一気にスプレッドシートやデータベース等からアプリケーションへ移行する際に有効な形式です。

CurlもこのCSV形式をサポートするAPIを持っています。CsvRecordSetはRecordSetのサブクラスであり、RecordSetの中に複数のRecordを自動で作成することが可能です。

それではまず、CSV形式のデータを作成してみましょう。 Microsoft ® Excel を使って、下記のようなデータを作成し、CSV形式で保存します。 inventory_items.csvという名前で任意のフォルダに保存して下さい。

 

/wiki/samples/images/csvdata.jpg

 次にCurlアプレットを作成してみましょう。コードは下記のようになります。
下記のコードをstart.curlとして、CSVファイルと同階層に保存してください。
今回は、CsvRecordSetを使用し、CSV形式のファイルをCurlにインポートします。

{curl 5.0, 6.0 applet}

{value
   let rs:CsvRecordSet =
       {CsvRecordSet  
           ||CSVファイルの場所を指定します。
           {url “inventory_items.csv”}
       }
   {RecordGrid record-source =  rs,
       width = 6in,
       height = 2in
   }
}

CsvRecordSetは以下のステップでCSVデータを読み込みます。

・CSVデータの各行からRecordを作成
・データの各フィールドをパース
・各フィールドをCurlデータ型へ変換

イベントの作成

Curlはユーザや他のプログラムが実行した操作(イベント)に対応して処理を行なうことができるイベントドリブン方式のプログラム言語です。一般的なイベントは「テキスト入力エリアに文字を入力する」時に発生するイベント(Curlの場合はValueChengedイベント)やボタンを押下するイベント(Curlの場合はActionイベント)また選択式のリストからデータを選択したときのイベント(Curlの場合はValueChangedイベント)があります。通常のWebのユーザーインタフェースのイベントは「ボタンを押下する」イベントによって処理が実行されるのみのものが多いのですが、その他にもユーザーの操作というものはさまざまになってきました。まさにこれらの操作に対応していることがリッチクライアントCurlの醍醐味です。

 

GUIコントロール部品の一般的なイベント

ボタンやリストボックスなどで発生する一般的なイベント処理のサンプルをご紹介します。以下にそれぞれのボタンを使用したサンプルソースを紹介します。

{curl 6.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}
{CommandButton
   label = “OK”,
   {on Action do
       {popup-message “ボタンが押されました!” }
   }
}
{CheckButton
   label = “Check for a kayak”,
   {on ValueFinished at cb:CheckButton do
       {if cb.value==true then
           {popup-message “チェックされました”}
        else
           {popup-message “チェックが解除されました”}
       }
   }
}
{VBox
   {text Select your favorite city},
   ||{italic Combo},
   {ComboBox
       width=3cm,
       “Milan”,
       “Moscow”,
       “Manchester”,
       value = “Milan”,
       {on ValueFinished at combo:ComboBox do
           {popup-message “Your favorite city is: ” & {value combo.value}}
       }
   },
   {italic Dropdown},
   {DropdownList
       width=3cm,
       “Milan”,
       “Moscow”,
       “Manchester”,
       value = “Moscow”,
       {on ValueFinished at drop:DropdownList do
           {popup-message “Your favorite city is: ” & {value drop.value}}
       }
   }
}

基本的なイベントの操作ははon構文を使用してダイナミックイベントハンドラを設定してイベントを処理します。
上記のサンプルを例に説明しますとCommandButtonやDropdownListオブジェクトの中に”{on Action do …}”や”{on ValueFinished do …}”という構文がありますように、”{on XXX do …}”でダイナミックイベントを設定できます。XXXの部分にはそれぞれイベントタイプを設定します。
CommandButtonの場合はActionクラスを指定していまして「押された時」に発生するイベントクラスです。”…”の部分にはイベントが発生した時の処理を記述します。Commandbuttonの例ですとボタンを押したときにポップアップで「ボタンが押されました。」と出力されます。

ポインタイベント

一般的なWebアプリケーションのGUIの処理は「押す」や「選択する」といったイベントのみの場合が多いですが、Curlはより複雑なユーザー操作のイベントを処理できます。
以下はマウスポインタの処理の例です。

{VBox
    height = 2in,
    width = 1in,
    background = “blue”,
    {on e:PointerPress at v:VBox do
        set v.background = “red”
        {e.consume}
    },
    {on e:PointerRelease at v:VBox do
        set v.background = “blue”
        {e.consume}
    }
}
{VBox
    height = 1in,
    width = 1in,
    background = “blue”,
    {on e:PointerEnter at v:VBox do
        {if e.shift? then
            set v.background = “red”
         else
            set v.background = “cyan”
        }
        set v.height = 2in
        {e.consume}
    },
    {on e:PointerLeave at v:VBox do
        set v.background = “blue”
        set v.height = 1in
        {e.consume}
    }
}

上記の例では2つのVBox(垂直方向に子オブジェクトをならべる箱)にダイナミックイベントを設定しています。
上のVBoxではポインタが「左クリックされた」ときと「左クリックを離した」ときのイベントを設定します。
下のVBoxではポインタが「VBoxに入った」ときと「出ていった」ときのイベントの設定にくわえて、「Shiftキーを押しながら入った」ときとそうでない時で処理を分けています。
このようにポインタの処理だけでも色々なイベントを処理することができ、またキーボード操作と組み合わせて処理することもできます。

キーイベント

キーボードの操作に対する処理もポインタイベントと同じように処理することができます。
以下はキーボードイベントのサンプルコードです。

{Frame
   width=2in,
   height=1in,
   background=”blue”,
   {on p:PointerPress at f:Frame do
       {f.request-key-focus}
       set f.background = “green”
       {p.consume}
   },
   {on kp:KeyPress at f:Frame do
       {if kp.shift? then
           set f.background = “red”
        else
           set f.background = “yellow”
       }
       {if kp.value == KeyPressValue.home then
           {popup-message “You pressed home”}}
   }
}

Frameに先ほどのポインタ操作のイベントにくわえ、”KeyPress”というイベントを使ってキーボード操作に対する処理を記述しています。
このサンプルはFrameにフォーカスがある状態のときに何かのキーを押すと黄色になり、またShiftキーを押しながら、任意のキーを押すと赤になります。最後のコードはHomeキーを押したときのイベント処理を設定しています。このように特定のキー入力に対してや、またショートカットキーでよくある”Ctrl+C”や”Ctrl+V”などの修飾キーとの連携イベントまでも制御できます。

 

ドラッグアンドドロップイベント

ドラッグアンドドロップイベントはまさにリッチクライアントでユーザーインタフェースを使うことの醍醐味です。
ドラッグアンドドロップを実現するのは難しいと思われがちですが、Curlの場合は他のイベント処理と同じようにドラッグアンドドロップイベントを操作することができます。
以下に簡単なドラッグアンドドロップのサンプルを紹介します。

drag-drop.jpg

{text 丸を四角エリアにドラッグしてください。}
{text CTRを押しながらドラッグするとコピーされます}

{HBox
    valign = “center”, width = 9cm,
    {EllipseGraphic
        width = 1cm, height = 1cm, dragee = {ImageDragee}},
    {Fill width = {make-elastic preferred-size = 10cm}},
    {VBox
        width = 1.5cm, height = 1.5cm, border-width = 1pt,
        border-color = {FillPattern.get-black},
        opaque-to-events? = true,
        {on e:DragOver do
            {e.will-accept-drop?
                {proc
                    {a:Type,
                     b:Distance,
                     c:Distance,
                     d:#DragEffect
                    }:DragEffect
                    {if {d.has-effect? “copy”} then
                        {return drag-effect-copy}
                     else
                        {return drag-effect-move}
                    }
                }
            }
        },
        {on e:Drop at vb:VBox do
            {e.accept-drop
                {proc
                    {w:any,
                     x:Distance,
                     y:Distance,
                     z:#DragEffect
                    }:DropResult

                    {if {z.has-effect? “copy”} then
                        {return
                            {DropResultCopy
                                action =
                                    {proc {}:void
                                        {vb.add {w.clone-appearance}}
                                    }
                            }
                        }
                     else
                        {return
                            {DropResultMove
                                action =
                                    {proc {}:void
                                        {vb.add w}
                                    }
} } } } } } } }

ソースサンプル

関連ヘルプドキュメント

Curl開発者ガイド-グラフィカルユーザーインタフェース-イベント
Curl開発者ガイド-グラフィカルユーザーインタフェース-ドラッグアンドドロップ

 

 

グラフィカルコンテナ

グラフィカルコンテナとはグラフィカルインターフェースを作成するときに使用するコンテナつまり箱です。グラフィカルコンテナの中にテキストやイメージ、メニュー、コントロールを含めることができます。HTMLの場合はframeというものがありますがそのようにエリアを割り付けたりする場合にも使えますし、グラフィカルコンテナに含まれるコンテンツを自動的に並べたりすることもできます。通常、「画面」を作る場合は最初にグラフィカルコンテナを配置し、その中にコントロールなどのコンテンツを配置していくことが一般的です。

グラフィカルコンテナの種類

グラフィカルコンテナは主に以下のようなものを良く使います。左のVBoxとHBoxは中に入るコンテンツ(コントロールとかイメージなど)を簡単に縦方向、横方向に並べてくれます。Frameは写真のフレームスタンドと同じようなイメージで中のコンテンツを入れ替えて使う場合に良く使います。また、座標指定でコンテンツを配置できるCanvasなども良く使われますが、動的に画面のサイズが変更されるような場合はあまり適しておらず、画面サイズが固定の場合に使用されます。

 

graphical-container01.jpg

Frame

以下にFrameを使用して中のコンテンツ(テキスト)をレイアウトするサンプルソースを紹介します。

{curl 6.0 applet}

{Frame
    background = “yellow”,
   “Curl’s Tutorial Tours”
}
{Frame
   width = 2in,
   height = 1in,
   background = “yellow”,
   “Curl’s Tutorial Tours”
}

Frameは1つのコンテンツを含むことができます。上記の例では”Curl’s Tutorial Tours”という文字列を含めています。Frameやその他のグラフィカルコンテナには上記のwidth(幅)やbackground(背景色)などさまざまな見た目を変更するためのオプションも用意されています。

VBoxとHBox

以下にVBoxとHBoxを使用して中のコンテンツ(RectangeleGraphicという四角い箱)を並べるサンプルソースを紹介します。

{curl 6.0 applet}

{HBox
   {RectangleGraphic
       width = 1cm,
       fill-color = “blue”,
       height = 1cm
   },
   {RectangleGraphic
       width = 1cm,
       fill-color = “red”,
       height = 1cm
   }
}
{VBox
   {RectangleGraphic
       width = 1cm,
       fill-color = “blue”,
       height = 1cm
   },
   {RectangleGraphic
       width = 1cm,
       fill-color = “red”,
       height = 1cm
   }

}

VBoxは中のコンテンツを上から縦方向に並べることができます。逆にHBoxは左から横方向にコンテンツを並べます。どちらのコンテナも中に含めるコンテンツをいくつも持つことができるので動的に中に入るコンテンツが変わる場合などは非常に便利です。ちなみに動的にコンテンツを追加する場合は”add”というメソッドを使用すると追加することができます。

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

Frameサンプル

VBoxとHBoxのサンプル

関連ヘルプドキュメント

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

コンテンツの読込み・書き込み

外部リソースについて

Curlアプリケーションでは外部リソースから情報を取得したり外部の送信先に情報を送信する必要があるケースがほどんとです。一般的に以下のような場所でデータがあります。

  • ファイル
  • ディスク
  • ネットワーク上
  • メモリ
  • 別のプログラムあるいはプロセス

Curlはありとあらゆるファイル(テキスト、バイナリ、イメージ)・Webページなどのリソースに対しデータの読込・書込を行うことができます。
ファイルシステム内にある場合はファイルの削除や名前の変更など、一部データリソースを操作することができ
ます。

 

テキストファイルの読込

ほとんど多くの場合データはテキスト形式で保持されてます。
テキストファイルを読み取るにはTextInputStreamオブジェクトを作成する必要があります。TextInputStreamオブジェクトはリソースから一連のデータを取り表すストリームクラスの1つです。ちなみにローカルディスク上のファイルの読み取りと、ネットワークまたは他のソース上のデータのストリームからの読み取りは同じです。ただし、ネットワークリソースと対話(Httpのpostメソッドやgetメソッドなどを使用して)する場合はCurlからリクエストデータおよび返却データを受け渡しする必要があるので少し変わってきます。そちらについては「逆引きリファレンス-サーバー連携」を参照してください。
以下にネットワーク上(あるいはローカルファイルシステム)のテキストファイルを読み込むサンプルをご紹介します。
 

{curl 5.0, 6.0 applet}

{pre {read-from {url “business.txt”}}}

上記のサンプルはread-fromプロシージャを使用したサンプルで、read-fromプロシージャは第一引数のUrlを指定するだけでそのコンテンツを文字列として読込み、StringBufという文字列のオブジェクトを返却します。
上記の例ではpreマクロを使用して読込み結果を表示しています。

 

テキストファイルの一行づつの読み取り

read-fromプロシージャはコンテンツのすべての内容を文字列オブジェクト(StringBuf)に読込みますが、コンテンツがCSVデータのような場合は1行づつ読み込んで処理することが多いと思います。
以下に1行づつ読み込むサンプルを紹介します。

{curl 5.0, 6.0 applet}

{value
   let lines:StringArray = {StringArray}
  
   let location:Url = {url “business.txt”}

   {with-open-streams in = {read-open location} do
       {until in.end-of-stream? do
           {lines.append {{in.read-one-line}.to-String}}
       }
   }

   let display:VBox =  
       {VBox
           background = “beige”,
           border-style = “sunken”,
           border-width = 2pt,
           border-color = “navy”,
           margin = 4pt
       }
   {for line key k in lines do
       {if k==0 then
           {display.add {bold {underline {value line}}}}
        else
           {display.add line}
       }
   }
  
   display
}

上記のサンプルは少し複雑ですが以下にポイントを説明します。

  1. 文字列の配列を作る(これはコンテンツから読み込んだ1行づつの内容を保持するためです。)
  2.  read-openプロシージャを使用してTextInputStreamオブジェクトを生成する。
  3. TextInputStreamクラスのread-one-lineメソッドを使用して一行ずつ読込み、最終行(EOF)まで1の文字列の配列に格納していく。

上記のステップでシーケンシャルファイルを一行ずつ読み込むことができます。

 

イメージの読込み

イメージを簡単に読み込むにはimageテキストプロシージャを使用する方法があります。
以下にImageテキストプロシージャを使用したサンプルをご紹介します。

{image
    source = {url “sample-image.gif”},
||–    下の幅(width)と高さ(height)を設定すると指定したサイズになります。
||–    指定してない場合はイメージのサイズが適用されます。
||–    width = 500pixel,
||–    height = 500pixel,
    tooltip = {Tooltip “画像の説明を記述したりします。”}
}
サポートしているイメージファイル形式は以下の通りです。
  • GIF
  • JPG
  • BMP 4、8、24、または32 ビット深度
  • PPM
  • PNG 8 ビット深度の透過度をサポート

TIFF 複数イメージのファイルの最初のイメージのみ。なお、追加のイメージにアクセスするには、ImageDataクラスを使用する必要があります。

 

書込について

書込みの手順も基本的に読込と同じになります。使用するクラスはTextOutputStreamクラスを使用します。
詳しくは「Curl開発者ガイド→外部リソースとの対話→ファイルやその他のリソースへのアクセス→テキストファイルの読み取りと書き込み →テキストファイルへの書き込み」を参照してください。

  

その他の形式へのアクセスおよび方法

上記で紹介したテキストおよびイメージデータ以外にも様々なデータにアクセスすることができます。例えばバイナリデータや圧縮データです。
また同期読み取りだけでなくAjaxなどで注目された非同期読み取りももちろん可能です。

 

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

データの読込みサンプル

 

関連ヘルプドキュメント

ヘルプドキュメントの使い方

 ヘルプドキュメントは、Curl言語の記述方法やAPIの解説方法のほか、IDEと共に提供されている各種ツールも紹介しています。 このCurlのヘルプドキュメント自体、CurlのAPIで構築されており、ヘルプに記載されているサンプルコードのほとんどはその場で実行することができるようになっています。また、ヘルプドキュメント自体がCurlのエディタとなっており、その場でコードのカスタマイズを行うことも可能です。ヘルプドキュメントの起動は、IDE実行中にF1キーまたは、IDEのメニューのヘルプを選択することで行います。(図.6)debug07.jpg

 

 

 

 

 

 

 

 

 

 

 

 

 

 

図.6 ヘルプドキュメントの例

①.③で表示する情報を設定します。

②.目次は、インデックスはインデックス検索、検索は検索、ブックマークは登録したページを一覧で表示します。

③.②で選択した内容を表示します。また、右クリックでコンテキストメニューのこのページをブックマークに追加を選択すると、表示しているページをブックマークに追加します。

 

 

 

グラフィック階層の使い方

 グラフィック階層は、すべてのオブジェクトをツリーで表示するツールです。グラフィック階層の起動は、起動中のアプレット上でCtrlキーを押しながら右クリックし、コンテキストメニューのグラフィック階層を選択することにより行います。(図.5)

debug06.jpg

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

図.5 グラフィック階層の例

 

 

①.クリックすると、グラフィック階層全体をツリーで追加表示します。

②.クリックすると、オブジェクトの親をツリーに追加表示します。

③.クリックすると表示されている画面が印刷します。

④.オブジェクトにカーソルを合わせると、オブジェクトのメンバと値をツールチップで表示します。また、ダブルクリックすると、グラフィック統計を表示し、右クリックすると、グラフィック統計とインスペクトがコンテキストメニューで表示します。

 

HTTP監視の使い方

 HTTP監視は、Curlのアプリケーションで発生したHTTP通信のパケットを捕捉して、詳細を表示することが出来るツールです。これを用いることで、アプリケーション内で発生したリクエスト・レスポンス情報に不備が無いかを分析したり、ログをエビデンスとして保存し、分析することができます。HTTPモニターの起動はIDEの上部にあるメニューから「ツール」から「HTTP監視」を選択することにより行います。HTTPのキャプチャを開始、終了するには、起動中のアプリケーション上でCtrlキーを押しながら右クリックするとコンテキストメニューの「HTTP監視の開始」または「HTTP監視の停止」を選択することにより行います。その間アプリケーションを操作すると、HTTPを介する通信が発生した時点で自動的に通信情報がキャプチャし、HTTPモニターの一覧に蓄積します。(図.4)

 debug05.jpg

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

図.4 HTTP監視の例

①.各httpパケットに関する情報を表示できます。

②.①で選択したパケットの内容を詳細に表示できます。

プロファイルビューアの使い方

 プロファイルビューアは、アプリケーション上で発生した処理内容を捕捉してボトルネックの分析を行うために用いるツールです。これを用いることで、どの処理に時間が掛かっているかを分析したり、ログをエビデンスとして保存し、分析することができます。プロファイルビューアの起動は、IDEの上部にあるメニューから「ツール」から「プロファイルビューア」を選択することにより行います。プロファイリングの開始、終了は起動中のアプリケーション上でCtrlキーを押しながら右クリックするとコンテキストメニューの「プロファイリングの開始」または「プロファイリングの終了」を選択することにより行います。その間アプリケーションを操作すると、ユーザの操作に伴って実行された処理が、逐次キャプチャします。(図.3)

debug03.jpg
debug04.jpg

 

 

 

 

 

 

 

 

図.3 プロファイルビューアの例

①.実行された関数の一覧を表示します。一覧には呼び出された関数の名前やその処理の呼出元であるパッケージ名、さらに処理の所要時間や割合等を表示します。

②.①で選択した関数が呼び出されるまでの手順を逆追跡したコールスタックを表示します。

③.②で選択した関数がキャプチャした期間中、どの箇所からの呼び出されることが多かったのか、その比率を表示します。

④.②で選択した関数がキャプチャした期間中、次にどの処理を呼び出すのか、その呼び出し先の比率を表示します。

⑤.表示されている関数名をダブルクリックまたは右クリックして「ソースの表示」を選択すると、IDEのソースコードが表示し、左端には処理に要した時間の全体に掛かる割合を表示します。

 

クラスブラウザの使い方

 クラスブラウザは、アプリケーションのクラス構成をビジュアルに表示するツールです。クラスブラウザの起動は、IDEの上部にあるメニュー「ツール」から「クラスブラウザ」を選択することにより行います。(図.2)

debug02.jpg

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 図.2クラスブラウザの例

①.テキストフィールドに記述したクラス名を記述すると、そのクラスをマークすることができます。

②.チェックを入れると多重継承を表示します。

③.チェックを入れると基本クラスを全て表示します。

④.クリックすると表示している画面を印刷します。

⑤.クラス構成を表示します。クラス名を右クリックすると、コンテキストメニューでクラスのメンバを表示し、表示したメンバをクリックすると、その定義のIDEのソースコードを表示します。また、クラス名をダブルクリックすると、クラスの定義のIDEのソースコードを表示します。

 

OS環境変数の値取得

端末の環境変数を取得するためには、clone-host-environmentプロシージャを利用します。以下にサンプルを紹介します。

{curl 6.0 applet}

{import * from CURL.RUNTIME.HOST-ENVIRONMENT}
{value
    let table:Table = {Table columns = 2}
    {for v key k:String in {clone-host-environment} do
        {table.add k}
        {table.add v}
    }
    table
}

 

実行結果

windir  C:\WINDOWS
ALLUSERSPROFILE  C:\Documents and Settings\All Users
HOMEPATH  \Documents and Settings\XXXXXX
OS  Windows_NT
PROCESSOR_IDENTIFIER  x86 Family 15 Model 75 Stepping 2, AuthenticAMD
ProgramFiles  C:\Program Files
LOGONSERVER  xxxxx
NUMBER_OF_PROCESSORS  2

….

 

Curl RTEのバージョン情報取得

端末にインストールされているRTEのバージョン情報を取得するには、get-installed-api-versionsというプロシージャを利用します。

{curl 6.0 applet}

{import * from CURL.LANGUAGE.COMPONENT}
{value
    {spaced-vbox
        {splice {get-installed-api-versions}}
    }
}

実行結果

6.0.0
5.0.4
4.0.6

 

ブレイクポイントの使い方

 ブレイクポイントは、プログラムの途中に設定することができ、プログラムを実行すると、設定した箇所で実行が一時停止し、その時点の変数の値等を調べることができるツールです。ブレイクポイントは、IDEソースコードの左端にあるグレーのボーダーをクリックすることによって設定し、赤い点をクリックすることによって解除できます。または、IDEの上部にあるメニュー「デバッグ」から行えます。(図.1)

 debug01.jpg

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

図.1ブレイクポイントの例

①.実行中のアプレットの停止、中止、実行、ステップ実行が行えます。

②.ブレイクポイントが設定されている箇所を表示します。

③.ローカルのタブは、アクティブなローカル変数と値を表示します。式のタブは、現在アクティブなローカル変数を含むCurl言語式を入力することで、式を評価できます。

各ブレイクポイントのファイル名と行数を一覧で表示します。また、ブレイクポイントで停止する条件式を設定できます。各ブレイクポイントの左側にあるチェックボックスはブレイクポイントが有効であるかどうかを制御します。

 

cometdを用いたリアルタイム通信/サーバ・プッシュ

Webアプリケーションではサーバからのデータ配信をクライアント側でリアルタイムに受信する方法が必要となるケースがあります。従来これは画面のリロードやポーリング等による実装がなされてきました。しかし、さらなるリアルタイム性を実現するために「Comet(コメット)」と呼ばれるHTTPセッションを接続し続けて、疑似的にサーバ・プッシュ(サーバ配信)を実装する手法がAjaxとともに多く使われるようになってきました。これをCurlで実装するための方法を記載していきたいと思います。

当サンプルでは、BAYEUXプロトコル(1.0Draft1)というJSONフォーマットで定義されたプロトコルの実装であるcometdのクライアントサイドライブラリを用いて、サーバ・プッシュを実現できるようにしています。そこで、Javaの実装の一つであるJettyに搭載されているcometdを利用して、サンプルを説明していきたいと思います。ちなみにcometd/BAYEUXプロトコルの詳細については以下のサイトを参照してください。
  http://www.cometd.com/

cometd準備及びサンプル実行

1.以下のサイトからJetty6.1.7をダウンロードします。
  http://www.mortbay.org/

2.上記でダウンロードしたzipファイルを展開します。

3-1.Windowsの場合、Jettyを展開したディレクトリのbin/Jetty-Service.exeをダブルクリックし、Jettyを起動します。
3-2.UNISの場合、jetty.shによりJettyサーバを起動します。

4.サンプルpublish-stock-price.curlを実行しますと以下のような画面が表示されますので、「株価配信ボタン」を押下します。

5.別ブラウザにてsubscribe-stock-price.curlを起動し、以下の画面を表示させ、「リアルタイム株価受信開始」ボタンを押下しますと、株価をリアルタイムで受信することができます。

リアタイムアプリケーション・サンプル

これらのサンプルプログラムを元に、実装方法を説明していきます。

我々は、cometdのCurlクライアントであるCometdClientクラスを用意しています。このクラスは以下のメソッドを用意しています。(COM.CURL.MESSAGE-SERVICEパッケージを参照)←リンク

  || 初期化を行います。urlに対象のサーバを指定します。
|| ここでは、http://localhost:8080/cometdを指定しています。
  {method public {initialize url:Url}:void }

  || 購読を開始します。
  {method public {subscribe channel:String, …:EventHandler}:void }

  || 購読を終了します。
  {method public {unsubscribe channel:String}:void }

  || データを購読しているクライアントに対して送信します。
  {method public {publish channel:String, message:JsonValue}:void }

  || サーバとの接続を切断します。
  {method public {disconnect}:void }

まず、はじめにCometdClientクラスのインスタンスを生成し、initializeメソッドを実行します。これによりcometdサーバとの接続が確立されます。

    def client:Client = {CometdClient}
    {client.initialize {url cometd-server}}

次に受信する側(ここでは株価情報を受信するsubscribe-stock-price.curl)で、subscribeメソッドを用いて、配信(publishメソッド)データを受け取るための処理を開始します。その後、他のクライアントもしくはローカルからpublishメソッドが実行されますと(ここでは株価情報を配信しているpublish-stock-price.curl)、受信側ではsubscribeメソッドの引数として指定されたイベントMessageReceiveEventが発生します。publishによる送信されたデータはMessageReceiveEventのmessageゲッターで取得することができます。この値はJSONオブジェクトとなっています。また、subscribe/subscribe/unsubscribeメソッドの引数にある”channel”とは、グループのようなものです。この同一チャネル間の中のみでデータ送受信を行います。複数のチャネルに対してsubscribe/publishをすることが可能となっていますが、違うチャネル間ではデータ送受信を行うことができません。 

{client.subscribe
channel,
    {on e:MessageReceiveEvent do
        let msg:JsonValue = e.message
        || ….
     }
}

 

{client.publish
channel,
{JsonObject
“ticker”, tickers[{rand.next-in-range 0, 3}],
“price”, {rand.next-in-range -20, 20} & “”
    }
}

subscribeを中止する場合は、unsubscribeメソッドを実行します。また、コネクションを切断するためには、disconnectメソッドを実行します。

おまけ

Apache Tomcatでcometdを稼動させるには、Jettyに格納されている以下のファイルをTomcatのホームディレクトリ配下のwebappsにコピーしてください。

  cometd-bayeux-6.1.6rc1.jar
  cometd-api-0.9.20070918.jar
  jetty-util-6.1.6rc1.jar

サポートバージョン

RTE6.0以上

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

cometdクライアントサンプル

comtedソースコード(Apps Galleryから)

 

パーシスタントデータ

Web アプリケーションでは、クライアント マシンに少量のデータを格納するために HTTP cookie を使用して、ユーザー名またはID、セッション IDなどの設定情報を格納しています。Curl アプレットもHTTP cookie を使用できます。さらにCurl API ではクライアント側 パーシスタントデータという小さなサイズのデータを格納する機能を提供しています。

では、具体的にサンプルを見ていきましょう。

プライベートパーシスタントデータ

これは、1つのアプレットのみからアクセス可能なパーシスタントデータです。これらを扱うためにまずは管理のためのリポジトリをpersistent-dataというプロシージャにより作成する必要があります。この際に有効期限等を設定することもできます。

{persistent-data
    “my persistent data.”,
    duration = 90days,
    max-size = 1024
}

リポジトリ作成後、以下のようにパーシスタントデータを取得(set-persistent-data)やセット(get-persistent-dataプロシージャ)することができます。

    let date:#String = {get-persistent-data
                           “last-visit”,
                           error-if-missing? = false}
    {output date}
    || set persistent data and commit.
    {set-persistent-data “last-visit”, {format “%s”, {DateTime}}}
    {commit-persistent-data} 

扱える型としては、null、プリミティブ形、String、FastArray-of、Array-of、HashTable-ofなどがあります。(詳細はCurlヘルプを参照ください。)set-persistent-data後、値をコミットするためにcommit-persistent-dataプロシージャを実行する必要があります。注意事項として、アプレットは最大で20までのリポジトリと256Kまでのデータしか扱うことができません。

共有パーシスタントデータ

パーシスタントデータ識別子(PDI)ファイルの persistent-data を呼び出すことで、複数のアプレットが共有できるパーシスタント データ リポジトリを作成することができます。これを利用するには、共有のscurlを作成し、その中でpersistent-dataプロシージャを呼び出す必要があります。

|| create repository
{persistent-data
    “shared persistent data”,
    duration = 90days,
    max-size = 1024

一方、各アプレットでは、パーシスタントデータを利用する前にget-persistent-data-repositoryプロシージャを用いてリポジトリ(Repositoryオブジェクト)を取得する必要があります。この際、上記の共有scurlのパスを指定する必要があります。
その後、プライベートと同様にget-persistent-data/set-persistent-dataを用いてパーシスタントデータを上記で取得したRepositoryオブジェクトを指定して扱うことができます。 

{let repo:Repository =
    {get-persistent-data-repository
        pdi-name = “http://localhost/share.scurl
    }
}
{do
    let date:#String =
        {get-persistent-data
            “last-visit”,
            repository = repo,
            error-if-missing? = false}
   
    {output date}
   
    || set persistent data and commit.
    {set-persistent-data “last-visit”,
        {format “%s”, {DateTime}},
        repository = repo
    }

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

パーシスタントデータのサンプル

 

ソケット通信

ソケットとは通信を行うアプリケーションの仮想的なインターフェースのことです。サーバは指定したポート番号でクライアントからの接続を待ち、クライアントはIPアドレスもしくはホスト名とポート番号を指定してサーバに接続します。接続が成功するとサーバ、クライアントともにソケットが生成され、そのソケットに対してデータ送受信を行うことができます。Curlでは、ソケットサーバ及びクライアントを実装することができます。

TCPサーバ

以下は、TCPサーバのコードサンプルです。

{let socket-server:AcceptorTCPSocket = {AcceptorTCPSocket}}
{server-socket.bind
    local-port = port,
    acceptable-handler =
        {on e:AcceptableSocketEvent do
            def socket = {server-socket.accept}
            {try 
                || receive
                {with-open-streams 
                    input-stream = {socket.to-InputStream} 
                 do
                    {print {input-stream.read allow-short-read? = true}}

                    || send 
                    {with-open-streams 
                        output-stream = {socket.to-OutputStream} 
                     do
                        {output-stream.write {make-bytes “back!”}}
                    }
                }
              finally
                {socket.close}
             }
       }

AcceptorTCPSocketクラスをnewすることによりサーバソケットを生成し、bindメソッドを実行することで、ローカルアドレスの指定したポートにバインドします。ここでbindメソッドの引数としてクライアントから受信した際に発生させるイベントAcceptableSocketEventをacceptable-handler引数にセットします。ここでは、受信した場合にクライアントから送信されたストリームデータを文字列として表示し、結果をOutputStreamとして返しています。

TCPクライアント

以下は、TCPクライアントのコードサンプルです。

let socket:DataTCPSocket =
    {DataTCPSocket remote-port = port, remote-name = hostname}
{try
    {socket.connect}
    || send
    {with-open-streams 
        output-stream = {socket.to-OutputStream} 
     do
        {output-stream.write {make-bytes “send!”}}

        || receive
        {with-open-streams
            input-stream = {socket.to-InputStream} 
         do
            {print {input-stream.read allow-short-read? = true}}
        }
    }
 finally
    {socket.close}
}

DataTCPSocketクラスを用いてクライアントソケットを生成し、connectメソッドにてサーバに接続します。サーバにデータを送信するには、ソケットのto-OutputStreamメソッドでOutputStreamを生成し、データを書き込みます(writeメソッド)。また、サンプルでは、サーバからのレスポンスをソケットのto-InputStreamメソッドによりInputStreamを受け取り、コンソールに出力しています。ソケットを閉じるにはcloseメソッドを利用します。

また、CurlではUDPサーバ及びクライアントも取り扱うことができますし、非同期通信も可能となっています。詳細はCurlのヘルプをご確認ください。

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

ソケット通信のサンプル

 

非同期通信と同期通信

Ajaxは(Asynchronous JavasScript + XML)という名前の通り、XMLHttpRequestというクラスを利用しAsynchronous(非同期通信)を実現できるという点が取り上げられ流行しています。もちろんCurlでも非同期通信を実現できるので、実装方法を紹介していきたいと思います。

同期通信

以下に、サーバへアクセスし、応答結果をアプレット上に表示するというサンプルコードを紹介していきます。

{curl 6.0 applet}

{let out:Frame = {Frame}} || 表示用
{value
    def remote-url = {url “http://www.curlap.com“}
    def http-file = {remote-url.instantiate-File} asa HttpFile
    {with-open-streams tis:HttpTextInputStream =
        {http-file.http-read-open} || 同期通信
      do
        let buf:StringBuf = {StringBuf}
        {tis.read-one-string buf = buf}
        {out.add {buf.to-String}}
    }
    out
}

サーバのURLからHttpFileオブジェクトを生成します。そのHttpFileオブジェクトのread-openメソッドを利用しサーバへリクエストします。サーバが返した結果(ここではHTML)をアプレットに表示しています。

非同期通信

非同期通信のサンプルコードも同様に結果をアプレットに表示します。非同期ではリクエストした結果を受け取った際に実行するためのコールバックプロシージャを用意します。以下のサンプルでは、callback-procプロシージャを用意し、非同期通信処理の終了後にこのプロシージャに結果を引数として渡して実行されるようにしています。

{curl 6.0 applet}

{let out:Frame = {Frame}}
{value
    let callback-proc:{proc-type {#Exception, #String}:void}
        = {proc {ex:#Exception, value:#String}:void
    {if-non-null ex then
        {output ex.message}
        {return}
    }
    {out.add value}
}

def remote-url = {url “http://www.curlap.com“}
def http-file = {remote-url.instantiate-File} asa HttpFile

let worker:AsyncWorker =
    {http-file.http-async-read-open
        {on e:AsyncFileOpenEvent do
            {if-non-null ex = e.exception then
                {callback-proc ex, null}
                {return}
             else
                {if-non-null tis = e.stream asa #TextInputStream then
                     let buf:StringBuf = {StringBuf}
                     set worker =
                          {tis.async-read-string
                              buf = buf,
                              {on e:AsyncStreamReadEvent do
                                  {callback-proc null, {buf.to-String}}
                                  {tis.close}
                              }
                          }
                }
            }
        }
    }

    out
}

HttpFileオブジェクトを生成するところまでは同期通信と同様ですが、非同期通信ではHttpFileオブジェクトのasyn-read-openメソッドを利用し、サーバにリクエストします。非同期通信の場合は結果を受け取るとAsyncFileOpenEventが発生し、このイベントのstreamゲッターから結果のストリームデータを取得することとなります。また、非同期処理は例外をキャッチできないため、例外もAsyncFileOpenEventのexceptionゲッターから取得します。さらにストリームデータを非同期に読み込むために、TextInputStreamにはasync-read-stringメソッドが用意されています。

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

通信のコードサンプル

 

オフライン実行(OCC)

随時接続コンピューティングとはリモート環境下においてクライアントPCがネットワークから切り離されていても、ユーザはあたかもネットワークに接続しているかのようにローカルにあるファイルにアクセスし、通常通りにWeb業務アプリケーションを使用できる機能です。

occ00.gif

OCCを利用するアプレットの作り方

*事前準備:
・Apache(IIS等でも可)を起動して、http://localhost が動いていることを確認してください。
・インストール先ディレクトリ\Curl Corporation\Surge\7\ide\etc\localhost-proの中のcurl-license-5.datファイルを localhost のルートに置いてください。(また、この動作を検証するためにはCurl/Proの機能を必要とします。)
・localhostに特権が与えられているか確認してください。(ローカルフォルダにアプレットを置くため、特権が必要になります。)

1.任意のディレクトリに新規プロジェクトを作成します。
OCCの機能を実現するために、 occ-install-or-update プロシージャを使います。その引数として、occ-root-installer というプロシージャを使います。この occ-root-installer が機能するには、サーバ上のアプレットの curl-root に特別な curl-timestamp.txt ファイルと特別な curl-archive.car ファイルが存在する必要があります。

2.コードを記述します。ハイライトしてある箇所を記述します。

{curl 6.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}
{applet manifest = “manifest.mcurl”,
curl-root = “.”
}
{do {occ-install-or-update occ-root-installer}}

これでOCCの機能が使えるようになります。たったこれだけです。

3.[ツールバー]→[プロジェクト]→[OCC用のディプロイメント]を実行します。
“deploy-default”という名前のフォルダが、1で作成したプロジェクトと同じ階層に作成されます。
フォルダの中に、curl-archive.car, curl-timestamp.txt, manifest.mcurl, start.curl の4つのファイルが作成されていることを確認してください。

4.deploy-defaultフォルダをlocalhostのルートディレクトリに配置します。
*今回は便宜上、全てルートディレクトリで行います。

5.IEを立ち上げ、アドレスバーに以下のアドレスを入力します。

curl://occ/http://localhost/deploy-default/start.curl
*OCCの機能を使用するためにはアドレスの前に curl://occ/というプレフィックスが必要となります。これは独立型アプレットと似ていますね(curl://launch/URL)。

6.結果の確認(オンライン)
Apacheを起動して立ち上げるとアドレスが以下のようになっていると思います。

http://localhost/deploy-default/start.curl

7.結果の確認(オフライン)
次に、サーバを停止して、5を実行してみます。すると、Curlランタイムがオフラインであることを検知してローカルにコピーしたアプリにリダイレクトします。(*うまくいかない場合は物理的にケーブルをPCから抜いてください)

どうでしょうか、これが最もシンプルなOCCの機能の紹介です。ポイントは
・ オンライン、オフラインで記述するコードは変更されないこと
です。

8.色々な確認
[1]で作成したフォルダの中の start.curl に対して以下のコードをコピー&ペーストし、[2-7]までの手順を実行してください。

{curl 6.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}
{applet curl-root = “.”}

実際のアプレットのURLは… ‘{value {get-the-applet}.url}’.

curl-rootは… ‘{process-get-curl-root}’.

有効なルートは… ‘{process-get-effective-root}’.

有効なアプレットURLは… ‘{value {get-the-applet}.effective-url}’.

‘curl://local-data’ のロケーションは… ‘{{url “curl://local-data”}.canonicalize}’.

ローカルに保存するコピーの更新を行います…
{{get-the-applet}.flush}

{let (permission?:bool, network?:bool,
allowed?:bool, updated?:bool)
=
{occ-install-or-update occ-root-installer}
}

{if updated? then
“ローカルへのコピーが更新されました。”
elseif allowed? then
“ローカルのコピーは既に最新です。”
elseif network? then
“今回はローカルのコピーを更新できませんでした。”
elseif permission? then
“現在ローカルにコピーされたアプレットが実行されています。”
else
“ユーザによりローカルへのコピーは禁止されています。”
}

9.OCCのリンクを示すためのcurlファイルを作ります。

{curl 6.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}
{value
{link href={url “curl://occ/http://localhost/deploy-default/start.curl”},
“OCC機能を使ったアプリへのリンク”}
}

*ただのリンクを表示するファイルなので、HTMLで作成していただいてもかまいません。

上手く動作しないときは・・・

・ 物理的にも切断されるように、PCからケーブルを抜いてみてください。
・ サーバが完全に停止していないかもしれません。停止させてから少し時間を置いてアプリを実行してみてください
・ ブラウザのキャッシュが影響しているかもしれません。IEの場合は[プロパティ]→[全般]タブから一時ファイルの削除を行ってから再度実行してみてください。
・ localhostに特権を与えていないことが問題かもしれません。[コントロールパネル]→[セキュリティ]→[ホストの追加]から localhostを追加してください。

外部ライブラリコール

Curlは外部ライブラリにアクセスすることができます。これによりC言語等で作成されたライブラリをコールし、結果を取得することができます。以下にサンプルをもとにして説明していきます。(ちなみにこのサンプルはWindowsのみで動きます。UNIX用のライブラリであれば、UNIX上でも実行することができます。)

当サンプルは、user32.dllに格納されているMessageBox 関数へのインターフェースを使用します。MessageBox は、単にメッセージ ボックスを表示します。インターフェースは以下のようになっています。

int MessageBox(
  HWND hWnd;
  LPCTSTR lpText;
  LPCTSTR lpCaption;
  UINT uType;
):int

パラメータには以下のような意味があります。
hWnd
メッセージボックスの上位ウィンドウへのハンドル。NULL の場合、このウィンドウにオーナーはありません。

lpText
表示されるテキスト。

lpCaption
ダイアログ ボックスのタイトルに表示されるテキスト。NULL の場合、既定のタイトルとしてエラーが使用されます。

uType
指定されたフラグに応じて、ダイアログ ボックスの内容と動作を変更します。フラグの種類は多数ありますが、この例で紹介しているのは、その一部です。

ライブラリをコールするクラスは、define-dll-classマクロを使って定義します。以下のようにサンプルでは、このコンストラクタ内で、SharedLibraryクラスを用いて対象DLL(user32.dll)をロードしています。construct-superでスーパークラスのコンストラクタを呼び出していますが、このスーパークラスはDLLInterfaceクラスです。 

{define-dll-class public WinMessageBox
  {defaults
    calling-convention = stdcall,
    string-rep = CStringUTF16
  }
 
  {constructor public {default}
    {construct-super {SharedLibrary “user32”}}
  } 

次にdll-methodで対象となる関数を定義することとなります。{defaults …} 句により、クラスに含まれた dll-method に直接、いくつかの既定値を設定できるようになります。これらの既定は、このクラスのサブクラスには適用されません。詳細はCurlのAPIリファレンスdefine-dll-classマクロを参照してください。

対象となる関数の定義については、同様の関数名をdll-methodのメソッド名としてセットするか、任意の名前を振り、括弧()で関数名を記載します。このサンプルでは後者の方法で定義しており、関数名はMessageBoxA、Curl内でのメソッドへのアクセスはshow-ascii-messageとなります。

{dll-method public {show-ascii-message (“MessageBoxA”)
                       hwin:CPointer = null,
                       text:StringInterface (rep = CString),
                       title:#StringInterface = null (rep = CString),
                       button-code:int = WinMessageBox.button-ok
                     }:int
}

…. 省略 ….

let box:WinMessageBox = {WinMessageBox}
let result:int =
    {box.show-message
        “Would you like a cookie?”,
         button-code =
             {bit-or
                 WinMessageBox.button-yes-no,
                 WinMessageBox.icon-question
             }
    }

実行結果 

 

 

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

外部DLLコールのコードサンプル

 

ローカルファイルアクセス

ブラウザ上のWebアプリケーションではローカルファイルへのアクセスが制限されていますが、Curlでは簡単にアクセスすることができます。(但し、セキュリティ面を考慮しており、特権の設定が必要となります。)

では、具体的にサンプルを見ていきましょう。

ファイルの読み込み

read-fromプロシージャを利用し、簡単にファイルを読み込むことができます。

def str = {read-from {url “test1.txt”}}

ファイルの書き込み

write-toプロシージャを利用し、簡単にファイルへ書き込みを行うことができます。

{write-to {url “test1.txt”}, “書き込み成功!”}

ファイルのコピー・名前変更

以下のサンプルコードのようにコピーや名前変更、削除も1行で記述することができます。

{copy {url “test1.txt”}, {url “test2.txt”}, error-if-exists? = false}

|| rename
{rename {url “test2.txt”}, {url “test3.txt”}}

|| delete
{delete {url “test3.txt”}}

ディレクトリ作成

ディレクトリの作成も以下のように簡単にできます。

let dir:Directory =
{create-Directory {url “dir1”}, error-if-exists? = false}

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

ローカルファイルアクセスのコードサンプル

 

コントロールの作成1

画面に表示されるコンテンツは色々ありますが、一般的なものとしてはコントロールと呼ばれる「ボタン」、「入力用のテキストコントロール」、「リストコントロール(選択式のコントロール)、さらに「テキスト」、「イメージ」などがあります。Curlにはそれ以外にもアニメーションコンテンツや2D、3Dまで作成することができます。

ボタンの作成

ボタンと言ってもCurlの場合は通常の「押す」だけのボタン以外にも候補の中から複数選択するようなチェックボタンや1つを選ぶ場合のラジオボタンなどがあります。

 

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

 

{curl 6.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}
||-コマンドボタンの例
{CommandButton
   label=”Press me!”,
   style =”rollover”
}
{CommandButton
   label = “Don’t press me!”,
   enabled? = false,
  height=.5in
}
||-チェックボタンの例
{VBox
   spacing = 3.5pt,
   {CheckButton
       label = “Uncheck me!”,
       value = true
   },
   {CheckButton
       label = “Can’t select me!”,
       value = true,
       enabled? = false,
       height = 1in,
       background =”yellow”
   }
}
||-ラジオボタンの例
{RadioFrame
   {VBox
       {RadioButton
style=”command-button-standard”,
 label = “Italy”,
 radio-value = “ITY”
},
       {RadioButton label = “Spain”, radio-value = “SPN”},
       {RadioButton label = “Germany”, radio-value = “GMY”}
   },
   value = “SPN”
}

 

 

ボタンはCommandButtonクラスを使用して作成します。 ボタンに表示されるラベルについてはlabelオプションを使用し、スタイルについてはstyleオプションを使用します。standard、 rollover、または  label-only のスタイルから選択できます。それぞれ試してみてください。また、高さ(height) および 幅(width)が指定されていない場合は、ラベルの内容に合わせて、ボタンのサイズが調整されます。
チェックボタンはCheckButtonクラスを使用します。
ボタンと同じようにstyleを設定でき、standard、 label-only、 command-button-standard、または  command-button-rollover のスタイルから選択できます。

状態(チェックされているかされていないか)は”true “または “false “(オンまたはオフ) というbool型になります。
ラジオボタンはRadioButtonクラスを使用しますがラジオボタンを使用するときは「どれか1つを選択する」というインタフェースを作ることが一般的なのでRadioButtonを含むRadioFrame クラスを使用してRadioButtonをまとめます。

オプション等についてはボタンやチェックボタンと基本的に同じです。

 

選択式コントロール

選択式コントロールとはユーザーが表示されたデータなどの中から1つまたはどれかを選ぶコントロールです。以下の図の左のようなリストコントールが一般的なインタフェースだと思いますが右のようなリストボックスの中にチェックボタンが入ったようなものもあります。

 

 
更に複合型の選択式コントロールとして「スピンコンロール」、「カレンダーコントロール」、「スライダ」などもあります。

選択式コントロールの作成

以下に色々な選択式コントロールを使用したサンプルを紹介します。 
select-control.jpg

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

{VBox
   {italic{bold 好きなアクティビティを選択してください。}},
   {ComboBox
       value=”Biking”,
       {ListValueItem “Hiking”,label={text color=”red”, Hiking}},
       {ListValueItem “Biking”,label={text color=”blue”, Biking}},
       {ListValueItem “Kayaking”,label={image
                          source = {url “images/kayaking.jpg”},
                          width = 2cm,
                          height = 1cm
                      }
       }
      
   }
}

{DropdownList
   prompt=”Tシャツの色を選択してください。”,
   width=2in,
   {ListValueItem 1,label={RectangleGraphic fill-color=”red”}},
   {ListValueItem 2,label={RectangleGraphic fill-color=”blue”}},
   {ListValueItem 3,label={RectangleGraphic fill-color=”yellow”}}
}

{spaced-vbox
   {italic{bold 好きなアクティビティを選択してください(複数選択可)}},
   {ListBox
       style=”checkbutton”,
       height=1in,
       {ListValueItem “HIK”,label={text color=”red”, Hiking}},
       {ListValueItem “BIK”,label={text color=”blue”, Biking}},
       {ListValueItem “RAF”,label={text color=”cyan”, Rafting}},
       {ListValueItem “SWM”,label={text color=”purple”, Swimming}},
       {ListValueItem “SKY”,label={text color=”green”, Sky Diving}}

   }
}
 

 上記のサンプルの3種類のコントロールは表示方法が異なります。 ListBoxクラスでは、常にすべての値が直接画面またはページに表示されます。一方、他の 2 種類のコントロールで値を表示するには、通常、最初から表示されているフィールドの右にある小さな矢印をクリックするという操作が必要です。 ComboBoxは、ドロップダウン リストに表示されている値から選択するのではなく、ユーザーが値を直接入力できるテキスト フィールドがあるという点でDropdownListとは異なります。 
上記3つの選択式コントロールには、さまざまな表示オプションを設定できるプロパティがあります。次に挙げるものは一般的に設定されている選択肢の一部です。
注目すべき部分はコントロールに表示されるものが通常は「文字」というのが一般的ですが、Curlの場合は画像や色などといったCurlで表現できるグラフィカルオブジェクトであればほとんどのオブジェクトを表示することができるところです!

select-image-control.jpg

以下にはそれぞれのコントロールに設定できるオプションの代表的なものをご紹介します。

  •  ローカル オプション
    border-style:このオブジェクトの枠線の外観を指定します。
    border-width:このオブジェクトの枠線の幅を指定します。
    height: Dimension を指定し、オブジェクトの元の高さを書き換えます。
    tooltip:この  Visual  にヒントを関連付けます。
    width: Dimension を指定し、オブジェクトの元の幅を書き換えます。
  •  非ローカル オプション
    control-content-background:コントロールのコンテンツに背景色がある場合、これを制御します。コントロールの非ローカル オプションのControlFrame.control-appearance-changeable? が true でない場合は、効果はありません。
    control-color:コントロールのボタンのようなパーツの主要部分の色を制御します。
    enabled?: Graphic  を有効に指定します。
  •  アクセッサ
    label:ボタンに表示できる文字列、イメージ、書式設定されたテキストなどです。
    style:ボタンの視覚的なスタイルです。

その他の選択インタフェース

ユーザーが選択するものは上記で説明したようなチェックボタンやリストボックスだけでなくテキストを反転(ドラッグして選択)させてコピーしたり、イメージを保存したりしますが通常のHTMLベースの画面の場合はテキストの反転を検知したり画像を選択したりすることは難しいと思います。
しかしCurlには個別選択、範囲選択、テキストコントロールの選択をサポートしております。
詳しくは「Curl開発者ガイド→グラフィカルユーザーインターフェイス→選択」を参照してください。

ソースサンプル

関連ヘルプドキュメント

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