時計を表示する i アプリ ( クラス定義ファイル ) package watch; * Created on 2001 / 04 / 06 , 13 : 21 * watch. java * @version * @author KIT-M import com.nttdocomo.ui.*ー m. start(); DispIay. setcurrent(m); m = new main( p は 0 void a ( ) ( / * * start of new application * / public static main m; public class watch extends IAppIication ( ROM に収録されているファイルから内容 ist 2 のように記述してください。付録 CD- t 1 のように , main クラス定義ファイルを L い。そして watch クラス定義ファイルを Lis ルクリックして , 工デイタを開いてくださ 工クスプローラのクラスファイルをダブ ・ソースを記述 は Fig. 3 のようになりました。 してください。この段階で工クスプローラ ッケージ名を「 watch 」としてそれぞれ作成 空のソースファイルの名前を「 main 」 , パ の名前とパッケージ名を「 watch 」として , } / / resume m. timer—start ( リ / / タイマー再開する public void resume( ) / / resume - 何らかの原因でタイマーが停止した場合の処理 ・ ADF ファイルの設定 割愛させていただきます。 ドの内容についての説明は , 誌面の都合上 をコピーしてもかまいません。 ソースコー ンツ」タグはどれをコンパイル ( パッケージ ) タ」タグは JAM ファイルの設定 , 「コンテ イアログが表示されます。「ディスクリプ く ] を選択してください。 ADF 設定用のダ す。 ADF ファイルを右クリックして , [ 開 ルするために ADF ファイルの設定をしま ソースが記述できたら , 正常にコンパイ 対象にするかの設定になります。 150 C MAGAZINE 2 1 6 それでは Fig. 4 のように「コンテンツ」タ 時計を表示する i アプリ ( main クラス定義ファイル ) package watch; import java. . C 引 en import com.nttdocomo.ui.も / / main クラス public class main extends Canvas / / start - 起動時の初期化作業 } 〃土 n setSoftLabeI (prame. SOFT-KEY—2, ”終了″ main( ) / / main - コンストラクタ private ShortTimer st = nul 嵭 } 〃 start timer-start ( system. out. println("start( ) . public VOid start( ) / / D てー描画処理 ) 〃 paint / / ダミーなので何もしない public void paint(Graphics —g) するためには in にを定義しておく必要がある 〃 paint - 描画処理 - 描画処理は醴で行っているがコンパイル } / / processEvent Draw(); / / 画面描画 IApplication. getCurrentApp( ) . terminate( / / so れ KEY2 が押された - アプリ終了 if (getKeypadState( ) = = 0X00400000 ) / / タイマーイベント if = = DispIay. TIMER-. EXPIRED—EVENT){ public VOid processEvent(int い rpe , int param) / / processEvent ーイベント処理 } / / timer-start . sta ( st = ShortTimer. getShortTimer(this, 0 , 1000 / 25 , true); System. gc( public void timer—start( ) / / timer-start - タイマー開始 sec = c. get(calendar. SECOND); min = c. get(Calendar. MINUTE); れ ou て = 0. get(CaIendar. HOUR—OF—DAY); day = c. get(CaIendar. DAY—OF—MONTH); month = 0. get(calendar. MONTH) 十 year = c. get(CaIendar. YEAR); Graphics —g = this. getGraphics( calendar 0 = calendar. getlnstance( リ yea.t' month' day' hour' sec; int private void Draw( ) —g. unlock(true); ”十 gec, 10 , 32 リ ″十 min 十 —g. drawstring(hour 十新 —g. drawString(year 十”年十 month 十を月″十 day 十新日 % 10 , 20 —g. setcolor(—g. getColorOfRGB(255, 255 , 255 ) / / 時間を表示する —g. fillRect(), 0 , getWidth( ) , getHeight( ) -g. setcolor(—g. getCOIorOfRGB(), 0 , 0 ) / / 背景を塗りっぷす -g.lock(); Canvas
Te 「 min アプリケーション Termin アプリケーションは , 典型的な UN Ⅸの CUI な開発スタイルで行えます。す なわち emacs のようなエデイタでソースを 編集し , cc でコンパイルするようなスタイ ルです。これとは別に Project Builder でも “新規プロジェクト”で T06 のカテゴリを選 ぶと , Termin 上で動作するプログラムを 作成できます。 Kernel 関係のドキュメントによれば , KerneIExtension とデバイスドライバ ーネルモシュール 御するために動的にロードされるカ バスに連結されているデバイスを制 ・デバイスドライパ・・・・・・コンピュータや コラム 7 その他の プログラム開発について Fig. 18 ・ KerneI Extension [ 注 A ] ・・・・・・再コン / ヾイル や再リンクをせずにカーネルに動的 にロードされるモジュール という OS の機能を動的に拡張する仕組み があります。 これらも Project Bu ⅱ der を使って開発し ます。興味深いトピックではありますが [ 注 B ] 誌面の都合上 , 今回は割愛させていただき ます。 なお詳細は HeIpViewer を立ち上げ [Deve loper Help Center] → [Kernel] の項目を手 がかりにしてください。 [ 注 A]kext という略称や拡張子が与え られている場合が多い [ 注 B ] デバイスドライバは I / 0 t とい うフレームワークを利用し , Embedde dC + + で開発するスタイルである ずです。 Objective-C のときと同様 , List 13 の MyV1ew クラスは白紙状態で , List 14 の MyControIIer クラスには lnterface Builder で 付け加えた Outlet と Ac ⅱ on が用意されてい ます。それぞれのファイルを List15 , 16 の ように変更します。プログラムの中身は Obj ective-C のものと , まったく同じなので解説 List 16 MyCont 「 olle 「 . java ( 変更後 ) / * MyControIIer * / import 00m. apple. 00C0a. foundation. import com.apple.0000a.application. * ー public c ね 88 MyControIIer { MyView myView; public void test1(Object sender) myview. changeTestFIag(2); public void test2(Object sender) myView.changeTestFIag(1); List 15 MyView. java ( 変更後 ) / * MyView * / import 00m. app 厄 . cocoa. fO ndat 土 on. も 土 mpo て t ・ com.apple.cocoa.application.も public class MyView extends NSView { 加セ mTest; / / 1 : で estl が押された , 2 : Test2 が押された if(mTest = = 1 Ⅱ mTest = = 2 ) { system. eてて . println( "drawRect."); public void drawRect(NSRect rect) { setNeedsDisplay(true); mTest = inFlag; if(inFIag ! = mTest) { system. eてて . println(") . System. eてて . print(inFlag); System. err. print("changeTestPlag(" public void changeTestFlag(int inFlag) mTest = 0 ・ system. err. print ー n ( "MyView constructor. super ( frame public MyView(NSRect frame) if(mTegt = = 1 ) { NSBezierPath thePath ー thePath = NSBezierPath. )else{ thepath = NSBezierPath. InRect(rect); thepath. fill ( NSCO て . て edCo て ( ) . set( クラスの Language を変更する (a) MyView の CIassInspecto 「を開く Edit ロ a55 を 5 FO 「 m 載 Layout Window T00 区 ・ 0 0 : 」 MainMenu.nib lnstances にね 55e5 lma Palettes Alignment Show C 0 Show 抦 fo Help 0 A 0 認 C マ MYView NSBo メ NSClipView NSCc 砒「引 NSBrowser NS Button NSPopUpButton NSCoiorWell NSI rnageView マ 4 ・ 3 ・ 3 ・ 10 ・ 8 ・ 8 ・ ↓ Java 0 切“ t Ⅳに ( 3 い ng い 9 を Attributes C 、、、 pe ロ 0 「 (b)Language を Java に変更する 5 イ C MAGAZINE 2001 6
的には , 以下の 2 つの作業が必要になりま す。 ・「 JRE(Java Runtime Environment) 」と 「 Java PIug-in 」を SunMicrosystems( 以 下 Sun と略 ) の Web ページなどから入手 して , アプレットを動かしたいコンピ タイマ版アニメーションアプレット (TimerAnim. java) ュータにインストールする E と HTML Converter は , Sun の同じ WebAt ・入手した「 Java P 旧 g - in 」に対応した「 H ージからダウンロードすることができます。 TML Converter 」を Sun の WebA—ジな 本稿の執筆時点では , どから入手して , アプレットの HTML http://java.sun.com/products/ ファイルを変換する plugin/index 」 a. html Java Plug-in は JRE に含まれています。 JR からダウンロードできました。バージョン は 1.3.0 ー 01 です。 JDK は JRE も含んでいるので , JDK をイン ストール済みならば , J を改めて導入す る必要はありません。 HTML Converter だ けが必要になります。 JRE は 7.6M バイト程 度のサイズがあるので , ダウンロードする よりも雑誌の付録 CD - ROM などを利用する ほうが簡単かもしれません。 以下 , HTML Converter のインストール から HTML ファイルの変換までの手順を説 明します。 手順 1 : 圧縮ファイルの展開 HTML Converter のサイズは 150K バイト 程度です。とくにインストーラは付属して いないので , 圧縮ファイルを適当なフォル ダに手動で展開します。圧縮ファイルの中 に converter フォルダと META-INF フォルダ がありますが , このうち展開が必要なのは converter フォルダだけです 手順 2 : HTML Conve e 「の起動 たとえば「 C : \ 」に展開した場合 , 「 C:Ycon verterYcIassesYHTMLConverter. bat 」を実行 すると , Fig. 2 のような HTML Converter が 起動します。 なお HTML Converter 自体も Java で作ら れているので , JDK/JRE などの Java 実行環 Fig. 2 HTML Conve 「 te 「の起動画面 クアイル報第ヘルプ オルダ病のすでのラ ) イル : C:tworkAnim ップイル律 html.*htm. •.asp サプフォルダを含める バックアップファイル用のブオルダ : C•Abak テンプレートつ。アイル : WlndOWS Solaris List ータイマーを用いたアニメーションアプレット import java. awt. *ー import Java. awt. event. *ー import Javax. swing. *ー - アプレットのクラス Timer ー AnimComponent animcomp; double theta=O. 0 , omega=O. の ーアプレットの初期化 public void init( ) { / / アプレットの Contentpane Container cp=getContentpane ( JPaneI p=new JPaneI( / / ボタン配置用のパネル 〃操作用のボタン JButton btnLeft , btnStop , btnRight ー / / レイアウトと背景色の設定 cp. setLayout(new BorderLayout( ) cp. setBackground(CoIor. white); / / アニメーション用コンポーネントの作成と配置 / / 画像ファイルは HT ファイルの AP 乳齲タグから取得 animcomp=new AnimComponent ( getImage(getDocumentBase( ) , ~ getparameter("image つ ) cp. add(animcomp, BO て de ても ayou し CEN で新、リ / / 操作用ボタンの作成と配置 p. setLayout(new GridLayout(1 ) p. add(btnLeft =new JButton( ”くく Left" ) p. add(btnStop =new JButton(" stop ” ) 馮 p.add(btnRight=new JButton( "Right > > つ cp. add(), BorderLayout.SOUTH); 〃操作用ボタンのイベント定義 btnLeft . addActionListener(new ActionListener( ) public void actionPerformed(ActionEvent e) { / / 左回りに加速 omega - = 0.0 btnStop . addActionListener(new ActionListener( ) public VOid actionPerformed(ActionEvent e) { / / 停止 omega = 0. btnRight. addActionListener(new ActionListener( ) pub lic VOid actionperformed ( ActionEvent e ) { / / 右回りに加速 omega 十 = 0.0 / / タイマー / / アニメーション用のコンポーネント / / 画像の角度と角速度 0 / / タイマーの作成 ±imersnew 衄 me てぐ 〃 30msec おきにイベント発生 を 30 , new ActionListener( ) { public void actionperformed(AetionEvent e) ( / / 画像を回転させる theta 十 =omega ー animcomp. rotate(theta); ノ / 画像の再描画 animcomp ・ repaint(); 一」第 ( ド ) P 朝 ) ト「、 M [ 0 Ⅳ e 日 第回ロ ーアプレットの開始 public void start( ) { timet,gtart()• - アプレットの停止 public void stop( ) { ()E N g 引 00 のみ 1 イ 0 c MAGAZINE 2 冊 1 6
List す。 アニメーションアプレットの操作には画 面下部の 3 つのボタンを使います。 を押すと左に一を押すと右に画像 が回転します。繰り返し押すと回転速度が 上がります。五を押すと回転が止まり ます。 スレッド版の プログラムの説明 スレッド版アニメーションアプレットの プログラム (List 1 , 2 ) の内容を , トビック 別に説明します。 画像の回転表示 List1 では画像描画用のコンポーネントと して , JComponent クラスをベースに「 lim Component 」というクラスを定義します。 AnimComponent クラスは , 指定した画像 を , 指定した回転角度でコンポーネントの 中心に表示します。 画像を回転表示するには「 Java 2D API 」と 呼ばれる一連のクラス群を使います。 Java 2D は java. awt. Gr 叩 hics クラスよりも高度な グラフィック機能を提供します。画像を回 転表示する場合には , java. awt. Graphics2D クラスと , java. awt. geom. AffineTransform クラスを使います。前者は Java2D の描画機 能全般を , 後者は平行移動・拡大縮小・回 転などの座標変換機能を提供するクラスで す。 Java2DAPI を用いたさまざまな画像の 操作については本連載の第 5 回で解説しま List 1- ①では AffneTransform クラスを使 うために java. awt. geom ノヾッケージを import します。 List 1- ②では AnimComponent が J Component のサプクラスであることを宣言 します (extends JComponent) 。 List 1- ③ ~ ⑤は AnimComponent の描画を 行う paint() メソッドの処理です。まず List 1- ③では Java2D の描画機能を利用するため に , Graphics2D オプジェクトを取得します。 Graphics2D クラスは Gr 叩 hics クラスのサプ クラスで , paint() メソッドには Graphics オ プジェクトの引数として渡されます。した スレッド版アニメーションアプレット ()h 「 eadAnim. java) - スレッドを用いたアニメーションアプレット import java. awt. *ー import java. awt. event. * ー import javax. swing ・ ーアプレットのクラス 〃スレッド Thread thread=nul 嵭 / / スレッドの実行許可 bO 引 ean running=fal se ー AnimComponent animcomp ー / / アニメーション用のコンポーネント / / 画像の角度と角速度 double theta=0.0 , omega=0. の ーアプレットの初期化 public void init( ) { Container cp=getContentPane ( JPaneI p=new JPaneI( JButton btnLeft, btnStop , btnRight; / / レイアウトと背景色の設定 cp ・ setLayout(new BorderLayout( ) cp. setBackground(Color. white); / / アニメーション用コンポーネントの作成と配置 〃画像ファイルは日 T ファイルの AP タグから取得 animcomp=new AnimComponent( getImage(getCodeBase( ) , getparameter(himage つ ) cp. add(animcomp, BorderLayout.CENTER 、 / / 操作用ボタンの作成と配置 p. setLayout(new GridLayout(), 3 ) p. add(btnLeft =new JButton( ”くく Left") p. add(btnStop =new JButton(" stop つ潺 p. add(btnRight=new JButton("Right > > つ cp. add(), BorderLayout. SOUTH); / / 操作用ボタンのイベント定義 btnLeft . addActionListener ( new ActionListener ( ) { public void actionpe て formed(ActionEvent e) { / / 左回りに加速 omega-=0.0 btnStop . addActionListener(new ActionListener( ) { public void actionperformed(ActionEvent e) ( / / 停止 omega = 0. btnRight.addActionListener(new ActionListener( ) public void actionperformed(ActionEvent e) { / / 右回りに加速 omega 十 = 0.0 / / アプレットの contentpane / / ボタン配置用のパネル / / 操作用のボタン - アプレットの開始 p は 0 void start( ) ( running=true; 、 ~ thread=new Thread(thiS); thread ・ start( リ ーアプレットの停止 public void stop()„、「 : / / 以レしドの実行を正する running=fal se ー t e 記 = 叩い引燾 ; ; 攣ノなスレッ下の破棄 ースレッドの処理 public void run(Y { 曲幻登はⅧ n 土 / / 時間待ち try 、 ( で ead. eep ( 3 の ) ′響第うを。 ~ -0 0 CInterruptedException eH - 田 k 引 ) / / 画像の再描画 / / 「画像を回転きせる theta 十 =omega ー animcomp. rotate( theta ー i 叩 0 叩・て e 垣い像の円描画 る す 可 許 を 行成始 、実作開 ののの ドドド レレレ 「ススス 1 38 C MAGAZINE 2001 6
特集 2 Mac 05X アコリケーション開発ガイド コラム 6 ( 1 ) MyContr011er クラスを NSObject クラ スからではなく java 」 ang. Object から 継承する (2)Fig. 18 のようにして MyView クラスの [Attributes] → [Language] を「 Java 」 にする の 2 点です。 こうしておかないと [CIasses] → [Create Files … ] で作成されるファイルが Java のソー スになってくれません。 また , MyControIIer の Action を testl: , tes 皀ではなく testl ( ) , tes ( ) にしておきます。 Objective-C の例のときと同様 , [Classes] → [Create Files … ] でプロジェクトに MyCon 仕 011er と MyView に関するファイル (MyCont roller.java , MyView.java) を追加します 0 この状態で , 追加されたファイルの中身は それぞれ List 13 , 14 のようになっているは List MYView. java ( 新規状態 ) Java Bridge Cocoa フレームワークでのプログラムは 原則として Objective-C を利用したものにな りますが , Java を利用することも可能です。 この恩恵をもたらすテクノロジが JavaB 「 id ge です。 Java から Cocoa フレームワークを利用す る場合 , いったん Objective - C のクラスをラ ップして上手に呼び出せるように工夫され ます。このラップ技術は Objective-C から Ja va 側を呼び出す場合にも利用できるため , Objective-C でできたモジュールと Java でで きたモジュールの混在が可能になります。 Java Bridge に関する詳細な情報は / Deve10 per/Documentation/Cocoa/ProgrammingT opics/JavaBridge/JavaBridge. pdf を参照し てください。 / * MyView * / import 00m. app 厄 .0000a. foundation. import com.apple.0000a ・ application. も public class MyView extends NSView { List MyControIIe 「 . java ( 新規状態 ) / * MyContr011er * / com.apple.cocoa.foundation.も com.apple.cocoa.application.*ー public class MYContr011er ( Object myView; public void test1(Object sender) { public void test2(Object sender) Fig. 17 project Builder による Pure Java アプリケーションの開発 ( a ) 新規プロジェクトとして Java AppIication を選択する AS 引れ一 ( b ) ソースを入力して Bu ⅱ d & 日 un する 習垣 v 誂”第 pb 可 ( ↓ ) 師 i 口を an AIt Run Debug Pause Continue 5 p 0 を「 5 0 い 1t0 5 0 0 歌 A ⅳ 2 ね ・ Groups & 日厄 5 気 Find D 曲四 ト java st ・今 0 0 MyCanvas ・ / / 0 05 〉 : プログラム特第用 ー a に 5 【 . i ( れ 5 / / javatest. 」ロ v ロ 0 ″ ( C ) 2 囲 1 取 T ー MRJApp p 「 opertl を、 0 ロ Products import j ロ va. 0 . import java ・ awt. event. i MyCanvas ー わⅱ c c javatest extends Frame { 北 t ー加 tt ( れ 1 = 「旧 w Button(); Button bt 」 tt612 = 印北 t51 ( ); HenuBar 。 rl = new " 印。 r ( Henu menuTest = new ー翹 ( ); HenuItem menuTestTest1 第 HenuItem(); HenuItem ænuTestTest2 = new HenuItem(); canvasl = mycmvas(); き public javatest() { avatest" New Project 望 Run Empty P 「 oj には マ AppIication Carbon Application ( 第 bO n AppIication (Nib Based) ( 0 ( oa AppIicati on ( 0 ( oa Document-based Application ( 0 ( oa - 垣 a Application ( 0 ( oa - 扣 Document-based AppIication 」 a AP が魎 00 VBundle Carbon Bundle ( 「円 u 可 n Bundle ( 0 ( oa Bu れ d 厄 旧 P をは マ Framework carbon Framework 瑩第 008 ↓ ( c ) 通常のアプリケーションと同様に実行される 朝い“ t ・“ Test 0 / 0 0 0 印 Application st 53 MacOSX アプリケーション開発ガイド 特集 2
List 1 ↓ appDir / / lnit Embedding = do—QueryInterface(macDir); rv = NS—InitEmbedding(appDir, nsnull リ / / Make pref D 土て ec セ 0 て y nsMPFi ー eLocProvider * ー ocationprovider = new nsMPFi ー eLocProvider ー NS—ENSURE—TRUE い ocationProvider , NS—ERROR—FAILURE nsCOMPtr«ns I Fi ー e> て OOtD 土て一 rv = NS—GetSpecia lDi て ec に 0 て y ( NS—MAC—PREFS—DIR , getter—AddRefs 仕 ootD 土て ) / / Needed because things read default prefs during startup if( NS-SUCCEEDED(rv) ) { NS—WITH—SERVICE(nsIPref, prefs, kPrefCID, / / lnit pref NS—ENSURE—SUCCESS(rv, NS-ERROR-FAILURE); rv = locationProvider—>Initialize(rootDir, NS—ENSURE—SUCCESS(rv, NS—ERROR—FAILURE); ” ma て b て ow ” & て v / / reduce the font size here by hand / / HACK ALERT: Since we don't have prefs UI , prefs->ReadUserPrefs( prefs->Resetprefs ( ncou れ Ot get preferences service" prefs->SetIntPref("font. size. fixed. x-western", 9 prefs->SetIntPref( "font. size. variable. x-westernn, 12 ) ・ て ow : :UpdateBookmarkMenu( リ / * Bookmark Menu * / NS—ASSERTION(PR-FALSE, )else{ prefs->SavePrefFile( / / ShutDown preferences nsresu ー t rv; static void TermWebShell ( void / / 終了 return NS—OK ー short itemNo; Dia ー ogptr if( IsDiaIogEvent( event ) ) { / * Modeless Dialog * / if( event->what ! = れⅲ IEvent ) { ー / * Some Event * / VOid ProcessEvent ( EventRecord *event イベント処理 List 2 NS-TermEmbedding ( / / Term Embedding UMacUnicode: :ReleaseUnit( リ prefs->SavePrefFile( リ if( NS-SUCCEEDED(rv) ) { NS—WITH—SERVICE(nsIPref' prefs, で指定しています。この初期化を呼び出し た後に , 工ンべッディングのさまざまな処 理が行えるようになります。 同じく TermWebShell() がエンべッティ ングの終了処理です。ほかにプリファレン スのセープ , UMacUnicode のクリーンアッ プも行っています。 イベント処理 ProcessEvent() がイベント処理を管理す るメソッドです (List 2 ) 。 こでは Mozilla kPrefCID, &rv 特有の処理を行っています。イベントルー プごとに nsRepeater::DoRepeaters ( ) を , nu Ⅱイベントごとに nsRepeater::DoIdlers ( ) を コールします。実際のイベント実行処理は , DoEvent() で行います。 ンスタンスへのポインタ , クロームインス でほかに子コントロールとして抱える各イ 前述の PPBrowser ではウインドウクラス ットへのポインタを持ちます。 の Mozi Ⅱ a 的表現であるウインドウウィジェ 連のメンバ変数として , メインウインドウ す。 MWind クラスの定義では , Mozilla 関 List 3 にウインドウクラスの定義を示しま インドウクラス (MWind) 、 static MView* mviewClicked; WMNG—WIND *mWmngWind; public: / * Attribute * / virtual NMWind( MWind( WMNG-WIND *wmngWind ); public: / * Constructor, Destructor * / typedef Wiew 工 e て土 t ー private : class MWind : public MView ウインドウクラスの定義 List 3 &itemNo ) ) { lDlog *mmidlog の g : :FindByDIog( dlog if ( D 土引 ogSe 厄 c セ ( event , & 引 og , Repeater; :DoIdIers( / * DO Moz ldle * / DoIdle( event / * DO Äpp ldle * / )else{ / * 齟日 DoEvent( event / * handle event * / て eturn ・ if ( mmidl og *event 房 Event * / mmidIog->DoEvent( itemNO Repeater: :DoRepeaters( *event / * DO MOZ Repeat * / DoRepeat( event / * DO App Repeat * / . :PR—Sleep(PR—INTERVAL—NO-WAIT); return ・ MView MBrow *mTarget; *mTargetBrow; / * BrowserWindow * / public: NS—METHOD GetWidget( nsIWidget** awidget ) ー MBrow* GetBrowserSheII ( UInt16 id=CNTLID—ANY ) cons void GetTitIe( S し r255 title void SetTitle( S い 255 title リ protected : nsCOMPtr<ns IWidget> mwindow ー 1 22 C MAGAZINE 2001 6
Fig. 1 プリミティプ型と参照型 intx = 3 : Data y = new Data(3); 3 代入と変更 Fig. 2 List 5 の実行結果 ( 注 1 ) int など , 最初から定義されている型 参照 ( ポインタ ) での使用 の va の場合直接の使用 参照 ( ポインタ ) での使用 ℃言語の場合直接の使用 TabIe 2 プリミティプ型と参照型の相違 :Data value = 3 基本型 ( 注 1 ) 〇 プリミティプ型 〇 〇 集成体型 ( 注 2 ) 〇 〇 参照型 〇 List 6 2 : 4 : 6 : 8 : 9 : 10 : 11 : 12 : 13 : ) 14 : 16 : 17 : 18 : 19 : ) 20 : 22 : 24 : 25 : 26 : 28 : 29 : 30 : 31 : 32 : 33 : } スタートアップ Ja a Java 言語事始 インタフェイス型の例 ( Speak. java ) * Speak. java 5 : interface SpeakabIe{ public void speak( class Enshou implements SpeakabIe{ pub lic void speak ( ) { system. 0uしPてin凵れ(”百年目と思いました” 15 : class Kosan implements SpeakabIe{ public void speak( ) { system ・ ou し prin 凵れに今なんどきだい ? つ・ 21 : class Speak{ public static void main(String[ ] args) { SpeakabIe 町 S = new Enshou( s ・ speak( s = new Kosan( s. speak( ( 注 2 ) 配列型や構造体型など ーインタフェイス型 プリミテイプ型と参照型の相違はしつか り理解してください。とくに C から移って きた人は注意すべきところです。 C 言語と の比較を TabIe 2 にあげておきます。この 特徴は , 人によっては制限と見るかもしれ ません。しかしこれによって Java の言語と しての堅牢性が保たれているのです ( もっ とも SmaIItaIk 派からは「プリミテイプ型を 特別扱いするなんて汚い仕様だ」と言われ そうですが ) 。 ークラス型 これは前回も説明しました。ある「クラス」 を元にして作られる「オプジェクト」を保 持するための型です。 例 : Data d = new Data( クラスのインタフェイス・・・・・・つまり「ど ういうメソッドがあるか」だけを決めてお いて , そのメソッドを持っているクラスを 保持できるようにした型です。 これだけではわかりにくいので例をあげ ましよう。 List 6 を見てください。 5 ~ 7 行目 で class の代わりに inte ace が付いて宣言さ れているのがインタフェイスと呼ばれるも のです。 あ , それから今までは 1 つのファイルに 1 つのクラスだけを記述していましたが List 6 のように複数のクラス宣言やインタ フェイス宣言を記述することもできます。 ただしこれはあまりいいやり方ではありま せん。別ファイルにすると見にくくなりそ 。読者のみなさ うだからこうしたので・・ んが書くときは 1 つのファイルに 1 つのク ラスとしてください。 話を戻します。インタフェイス SpeakabI e では speak() というメソッドが宣言されて います。こうすると , speak() というメソ ッドを持っているクラスを Speakable とし て扱うことができるのです。クラス Ensh ou , クラス Kosan は , クラスとしては別で すが , どちらもインタフェイス Speakable を implements しているので , Speakable 型 として取り扱えるわけです。 インタフェイスについては , 回を改めて ー修飾子とデフォルト値 後にまとめて述べます。 配列型も参照型の一種です。これは少し ー配列型 詳しく解説します。 クトのフィールドには代入できるかもしれ ことはできませんが , それが指すオプジェ nal と宣言された参照型の変数に代人する ただⅱ nal の意味には注意してください。ⅱ 意味はプリミテイプ型のときと同じです。 ansient, volatile) を付けることができます。 ublic , protected , private , static , final , 仕 参照型にも , 先に述べたような修飾子 ( p ません。 スタートアップ Java 69
Java programmingTips ひぐべん工房 第 1 1 回 スレッドとタイマで実現するアニメ - ションアプレット アニメーションはもっとも代表的なアプレットの題材です。アニメーションを実現するにはスレッドを使う のが普通ですが , Swing のタイマを使う方法もあります。また今回は , Java P 旧 g - in を利用して一般の Web ブラウザで Java の最新機能を用いたアプレットを動かす方法も解説します。 ウインドウ ( フレーム ) がふたつ出現します。 DOS プロンプト ) で以下のコマンドを入力 スレッド版アニメーション 一方がスレッド版 , 他方がタイマ版です。 します。コンパイルは , アプレット 一般の Web プラウザ (lnternet ExpIorer や javac ThreadAnim.java Netscape Navigator) で Anim. html を開いた まずはスレッドを使ったおなじみの方法 です。 AnimComponent.java は ThreadAnim. 場合 , web プラウザのバージョンにもより でアニメーションを行うアプレットです (F java の中から参照しているため , 自動的に ますが , アプレットが起動しない場合が多 ig. 1)。プログラムは List1 と List2 です。 Li コンパイルされます。実行は , いと思います。これは Java の比較的新しい st 1 は javax. swing パッケージの JComponent appletviewer Anim. html 機能を使ったアプレットによく見られる現 です。 Anim. html にはスレッド版・タイマ クラスをサプクラス化した画像描画用のコ 象です。通常の Web プラウザでこのような 版の各アニメーションアプレット用のく叩 ンポーネントです。 List2 はスレッド版アニ アプレットを動かすには JavaPIug - in を利用 plet > タグが書いてあります。スレッド版・ メーションアプレットの本体です。 List 1 します。その方法は後ほど詳しく解説しま は , List2 と後述する List4 ( タイマを用いた タイマ版の両方をコンパイルしておくと , アニメーションアプレット ) の両方から利 画像描画用のコンボーネント (AnimComponent. java, List 2 と List 4 から利用 ) 用します。 また , アプレットには HTML ファイルも ーアニメーション用のコンポーネント 必要です。 HTML ファイルは List 3 で , スレ import java. awt. *ー は mpo て・ awt ・ geom. *い ッド版・タイマ版に共通です。 import javax. swing. * ー スレッド版アニメーションアプレットを コンポーネントのクラス ゆ加 class AnirComponent extends $ComponentW53 コンパイル・実行する方法を説明します。 / / 画像 lmage xmage; / / 画像を表示する角度 doub 厄 theta=0. 使用する処理系は Java 2 SDK, Standard Ed コンストラクタ public AnimComponent(Image —image) { ition, Ver. 1.3 ( 以下 JDKI. 3 ) です。コンパイ / / 画像を設定 image=—image ー ル・実行にはコマンドプロンプト ( または 一角度の設定 public void て 0 に a セ e ( doub 厄 -theta) { / / 角度を設定 theta=—theta; アニメーションアプレット - 表示 public void paint(Graphics gra) ( / / Graphics2D オブジェクト Graphics2D g2 / / 回転用のアフィン変換行列 AffineTransform at; を (gra instanceof Graphics2D & & image!=null) ( g2d=(Graphics2D)gra;// a 山 ics を a ics2D に変換 ( キャスト ) する / / アフィン変換行列の作成 / / まず画像の中心で回転し、次に画像の中心を i 祀。 mpone 北の中心に合わせる at=new Affinefransform( at. translate(getwidth( ) / 2 , getHeight( ) / 2 リ at. rotate(theta); at ・ translate(-image. getWidth(this)/2' -image. getHeight(this)/2); 〃画像の表示 g2d. drawlmage(image, at, this)i List 新同厂 ーはつトユーを津川 m アプレットな ~ されました。 137 Java P 「 ogramming Tips
同時に各コントロールクラスのコンストラ クタが呼ばれます ( List4- ( d ) ) 。そしてべー スウィジェットを作成します (List 4- (e)) 。 List 5 ウインドウの描画処理 void MWind: :DrawSelf( ) DrawEnv de( mWmngWind->wind もう一度 , mWmngWind の子コントロー ル配列をイテレートし , 各オプジェクトに FinishCreateSeIf() によってメッセージを送 ります田 st4- ( f ) ) 。最後に , 自分自身にメ ッセージを送ります (List 4- (g)) 。 これら一連の処理が終わった後 , ウイン List 7 ブラウザシェルクラスの定義 WMNG—CNTLS WMNG—CNTLIT WMNG—CNTL cntls = mWmngWind—>cntls; cntlit; *cnt 嵭 class MBrow : public MView private : typedef MView lnherited; / / Friends friend class Ch て om / * Constructor , Dest て uctor * / public: 田 row ( WMNG—WIND *wmngwind, virtual -MBrow ( fo て ( cntlit=cntls. begin( cntlit!=cntls. end( 潺十十 cn 日土セ if( RectInRgn( &rect, mWmngWind->wind->visRgn ) Rect rect = cntl—>bounds; cnt ー * cn セー土に一 return NS—OK ー NS—IF—ADDREF(*aWidget); *aWidget ま mWindow; NS—ENSURE—ARG—POINTER ( aWidget NS—METHOD MWind: :GetWidget( nsIWidget** aWidget べースウィジェット取得 Li st 6 cn セ l->mview->DrawSe げ ( LiSt 8 MB 「 ow クラスのコンストラクタ mLoading( false ) mBrowserChrome ( NULL ) , : mWmngWind( wmngWind ) , mwmngcntl ( wmngcntl ) , MBrow: 靆田て OW ( WMNG—WIND *wmngwind, WMNG—CNTL *wmngCntl / * Attribute * / public: WMNG_WIND WMNG—CNTL *mwmngwind; *mWmngCntI; / * BrowserShell * / protected : static nsMacMessageSink protected : nsCOMPtr く ns IWebBrowser> nsCOMPtr く ns I BaseWindow> nsCOMPtr く ns I WebNavigation> / * BrowserWindow in PP Brow MChrome* / * Some Browser Status * / W>NG—CNTL *wmngCntI mMessageSink; mWebBrowser; mWebBrowserAsBaseWin• mWebBrowserAsWebNav; mBrowserChrome ー mLoading; mTitle; create( NS—IMETHODIMP 田て OW : nsresu ー / * BrowserWindow : Create ( ) Make Chrome * / mBrowserChrome = new MChrome; NS—ENSURE—SUCCESS(rv, NS—ERROR—FAILURE); mWebBrowser ま do—CreateInstance(NS—WEBBROWSER—CONTRACTID, / * Create WebBrowser * / / * BrowserShell * / mBrowserChrome->BrowserWindow( ) = mWmngWind—ymwind; NS-ADDREF(mBrowserChrome); NS—ENSURE—TRUE(mBrowserChrome, NS—ERROR—OUT—OF—MEMORY); nsCOMPtr<nsIWebNavigation> webNav(do—QueryInterface(mWebBrowser) mWebBrowserAsBaseWin = basewin ー NS_ENSURE—TRUE(baseWin, NS—ERROR—FAILURE); nsCOMPtr<ns IBaseWindow> baseWin ( do—Querylnterface ( mWebBrowser ) mwmngcntl—>mview = this; mWmngCntl—>cntlH = NULL ・ / * Set WmngWind * / mWebBrowserAsWebNav = webNav; NS—ENSURE—TRUE(webNav, NS—ERROR—FAILURE); return NS—OK; protected : B00 ー ean nsString / / ・・・ " ・て ow. cpp 内・ / * Static variable nsMacMessageSink 田て OW : :mMessageSink; ShowSe げ ( true Enab lese げ ( true / * Enable & Show * / Ki Ⅱ contentscro Ⅱ bars ( if( wmng-brow->kiIIScroIIbars ) { WMNG—BROW *wmng-brow = dynamic—cast く WMNG—BROW*>(mWmngCntl ノ * Kill scrollbars * / this ー mBrowserChrome->BrowserShell ( ) / * Tell Chrome about BrowserShell * / SetTopLeve ー window( mBrowserChrome / * Tell BrowserShell about Chrome * / AdjustFrame( rect mWebBrowserAsBaseWin—>Create ( ); nsnul して . x , て・ y , て・ width, r. height); mWebBrowserAsBaseWin->InitWindow ( aWidget—>GetNativeData ( NS—NATIVE—WIDGET ) , rect. right - rect.left, rect. bottom ー rect. top); nsRect r(rect.left, rect.topr GetBestCntIRect( mWmngCntI->lnands, rect rect ー Rect / * ln 土に BaseWindow * / if( !aWidget ) NS—ERROR( "GetWidget failuren mWmngWind->mwind->GetWidget ( getter—AddRefs ( awidget ) nsCOMPtr«ns IWidget> awidget DrawEnv de( mwmngwind->wind void て ow : : FinishCreateSe げ ( ) 全階層構築後の最終処理 List 9 LoadURL( wmng—brow->startURL, MAX—URLSTRING ); 迂 ( mng-brow->startURL[0] ! = 0 ) { / * Load URL * / SetFocus ( / * Set Focus * / 1 24 C MAGAZINE 2 1 6
C プログラマのための C + + 入門 実践 0 + + ゼミナ→レ コンストラクタとデストラクタ 吉野智興 第 3 回 前回でグローバルなオブジェクトの生成と消去に 隠された C + + の内部的な処理の話が済みました。 今回も C + + の特徴である「コンストラクタ」と「デ ストラクタ」の話を進めていきましよう。 静的なオブジェクト 前回のグローバルなオプジェクトの生成 について補足があります。 C がそうであっ たように , C + + もそのソースファイル内だ け , あるいは関数内部でだけ有効な静的な 変数を持っことができます。キーワードで ある sta ⅱ c を伴った変数宣言がそれです。 List 1 のプログラムで宣言されている G および L は , それぞれコンストラクタとデ ストラクタの呼び出しをコンパイラが生成 します。このように変数がコンストラクタ やデストラクタを持つ場合は , その変数が 定義されたときにコンパイラがそのコンス トラクタとデストラクタの呼び出しを行っ てくれます。プログラマがとくに心がけな くてもコンパイラが何らかの処理を行うと いうのは C 言語にはない C + + の特徴のひと つでもあります。 Fig. 1 がその実行結果ですが , G, L どち らの変数の生成 , 消去に伴うものかは List 1 のプログラムではわかりません。これを 明確化するには「引数を持ったコンストラ クタ」の知識が必要ですが , その前に c で の自動変数 ( auto ) に相当する変数でのコン ストラクタ , デストラクタの扱いを勉強し ましよう。 一時的な変数 C や C + + は変数の宣言を強要する言語で す。変数は宣言することで初めて使えるよ うになり , 定義することでメモリあるいは CPU のレジスタ上にその実体を持ちます。 c では前節の「静的な変数」以外の変数はす べて一時的な記憶領域に確保されます。そ の記憶領域は通常は CPU のスタックと呼 ばれるメモリ上の領域であったり , CPU の レジスタそのものであったりします ( コラ c 十十 test . cc ー 0 test Fig. 1 List 1 の実行結果 ム 1 ) 。 OK,close OK,close Hi,I am Myclass Hi , I am Myc lass . /test 宅 コンストラクタ , デストラクタを使ったプログラム例 #include く std 土 0 上 > class MyCIass public: MyCIass(void) ¯MyCIass(void) static MyCIass G; main ( ) { fprintf { fprintf (stdout, (stdout, ″日 i , I am MycIass%n" "OK,close%n" ) 引数を持ったコンストラクタを使ったプログラム例 MyClass 引 0b 引 ( ”引 0ba げ -MyClass(void) { if (mes) fprintf (stdout, "%s ended*n%mes) MyClass(char *init) { mes = init; MyCIass(void) { mes = の fprintf public: char *mes; class MyCIass #include <stdio.h> static MyClass も一 (stdout, fprintf MyCIass Auto("Auton static MyCIass BIockStatic ( ”引 OCk Static main( ) static MyCIass LocaIStatic("LocaI Static" "Hi, I am Myclass%n") ”宅 s started%n", mes) (stdout, 実践 C + + ゼミナール 61