Java

JavaTM 2 SDK, v1.4 での AWT の拡張

ドキュメントの目次
バージョン 1.4 の Java 2 SDK では、次の AWT の機能が追加されています。
新しいフォーカスサブシステム
推奨されない Focus メソッド
タイムスタンプを必要とする ActionEvent (およびその他のイベント)
ヘッドレスサポート
マルチスクリーンのサポートに必要なウィンドウの中央配置 API
新しい全画面排他モード API
Windows NT でのビデオドライバの Sync Out of Range エラー
非装飾フレーム
マウスホイールのサポート
Frame のプログラミングズーム
サイズ変更時の動的なレイアウト
コンポーネントリスナリストへのアクセス
ドラッグ&ドロップの変更点
現在のウィンドウマネージャを明確にする
64 ビット対応の Solaris
一貫性のない DLL 警告
DrawingSurface API の削除
新しい InputEvent キー修飾子
Choice メニューのドロップダウン動作の変更点

新しいフォーカスサブシステム

この変更に関連するバグ追跡レポート: 4290675.

これまでのフォーカスアーキテクチャは、フォーカスサブシステムに新しく置き換わりました。新しいフォーカスサブシステムは、プラットフォームが異なるために生じるフォーカス関連のバグや、AWT と Swing コンポーネントとの非互換性に対応しています。 詳細については、「フォーカスモデル仕様」を参照してください。

ここから javadoc を参照してください。

ヘッドレスサポート

この変更に関連するバグ追跡レポート: 4281163.

メインフレームや専用サーバのような環境では、多くの場合、ディスプレイ、キーボード、マウスをサポートしていません。 GraphicsEnvironment の新規メソッド isHeadless および isHeadlessInstance により、ヘッドレスサポートが可能になっています。 これらのメソッドでは、ディスプレイ、キーボード、マウスがグラフィック環境でサポートされるかどうかを示します。

ヘッドレスには次のような API の変更があります。

(*)AppletButtonCheckboxChoiceFileDialogLabelListMenuMenuBarMenuComponentMenuItemPopupMenuRobotScrollbarScrollPaneTextAreaTextComponentFrameWindowDialogJAppletJFrameJWindowJDialog、およびTextFieldCanvasおよびPanelは、空のピアを割り当てて軽量コンポーネントとして扱うことができるので、このような例外をスローする必要がありません。

ヘッドレスを実装した環境を実行するには、java コマンド行に次のプロパティを指定します。

  -Djava.awt.headless=true
例外が正しくキャッチされるように、ソースコードでヘッドレスをチェックする必要があります。 たとえば、ヘッドレスを実装する以前の Foo クラスの実装は次のとおりです。
class Foo {
  static Choice c = new Choice();  // could throw HeadlessException
}
ヘッドレス実装後の新しい Foo の実装は、static ブロックに次のように記述します。
class Foo {
  static Choice c;
  static {
    try {
      c = new Choice();
    catch (HeadlessException e) {
        ...
    }
  }
}

新しい全画面排他モード API

この変更に関連するバグ追跡レポート: 4189326.

新しい全画面排他モードの API は、ウィンドウシステムを一時停止して画面に直接描画できる高性能グラフィックスをサポートします。 全画面モードとは、AWT フレームウィンドウダイアログを画面にあわせて広げるだけの機能とはまったく異なり、ビデオメモリの内容をアプリケーションで完全に制御するグラフィックモードです。 アプリケーション側でグラフィックカードに描画内容、描画方法、描画タイミングを指示します。 このモードはいつも利用できるわけではありません。 オペレーティングシステムによっては、まったく実装できないこともあります。 また、オペレーティングシステムの中には、グラフィックカードがこの機能をサポートしている場合にのみ利用できるものもあります。ただし、このモードは性能に大きな影響を与えるので、Windows ではハードウェアの page-flipping 機能を有効にしておく必要があります。

全画面排他 API モードの使い方とコード例については、ここを参照してください。

API の変更

Windows NT でのビデオドライバの Sync Out of Range エラー

この変更に関連するバグ追跡レポート: 4452207.

Intel 810 グラフィックコントローラ搭載の Dell Optiplex GX110 で Windows NT を使用している場合に、表示モードを高解像度にして複数回変更すると、ビデオドライバから「sync out of range」というメッセージが表示されることがあります。 これは、(DirectX) ビデオドライバのバグが原因です。 この問題に対しては、次のようないくつかの回避方法があります。

非装飾フレーム

この変更に関連するバグ追跡レポート: 4038769.

アプリケーションによっては、ネイティブフレーム装飾のない方がよい場合があります。 たとえば、さまざまなプラットフォームで実行されるアプリケーションで同じ Look&Feel が必要な場合や、ネイティブのオペレーティングシステム機能を使ってエンドユーザがアプリケーションに介入することをプログラマが望まない場合です。

このリリースでは、Java アプリケーションを使ってフレーム装飾の作成機能を無効にすることができます。非装飾フレームモードをオンにすると、ネイティブなタイトルバー、システムメニュー、ボーダ、またはオペレーティングシステムに依存するその他のネイティブな画面コンポーネントは表示されません。 AWT と Swing コンポーネントは透過的に機能します。

java.awt.Frame の変更点:

    public void setUndecorated(boolean undecorated)

    public boolean isUndecorated()

java.awt.Dialog の変更点:

    public void setUndecorated(boolean undecorated)

    public boolean isUndecorated()

マウスホイールのサポート

この変更に関連するバグ追跡レポート: 4289845.

マウスホイールとは中央のボタンの代わりにホイールがあるもので、マウスホイールによるスクロール機能が Java の組み込みサポートに新しく加わりました。 java.awt.event.MouseWheelEvent クラスは、Java アプリケーションでマウスホイールのスクロールをシームレスにサポートすることを可能にします。このとき、再コンパイルは必要ありません。 また、新しいインタフェース java.awt.event.MouseWheelListener を使ってマウスホイールの動作をカスタマイズすることもできます。

Linux でマウスホイールを使用する場合は、ここを参照してください。

Frame のプログラミングズーム

この変更に関連するバグ追跡レポート: 4071554.

これまでは、Frame をプログラム上でズーム (最大化) する方法はありませんでした。 このリリースでは、この機能が追加されました。

新規インタフェース java.awt.event.WindowStateListener が導入されています。

java.awt.Frame の変更点:

    public static final int MAXIMIZED_HORIZ = 2;

    public static final int MAXIMIZED_VERT = 4;

    public static final int MAXIMIZED_BOTH = MAXIMIZED_VERT | MAXIMIZED_HORIZ;

    public synchronized void setMaximizedBounds(Rectangle bounds)

    public Rectangle getMaximizedBounds()

    public synchronized void setExtendedState(int state)

    public synchronized int getExtendedState()

java.awt.event.WindowEvent の変更点:

    public static final int WINDOW_STATE_CHANGED = 9 + WINDOW_FIRST;

    public WindowEvent(Window source, int id, Window opposite, int oldState, int newState)

    public WindowEvent(Window source, int id, int oldState, int newState)

    public int getOldState()

    public int getNewState()

java.awt.AWTEvent の変更点:

    public final static long WINDOW_STATE_EVENT_MASK = 0x40000;

java.awt.Toolkit の変更点:

    public boolean isFrameStateSupported(int state) throws HeadlessException

java.awt.Window の変更点:

    public synchronized void addWindowStateListener(WindowStateListener l)

    public synchronized void removeWindowStateListener(WindowStateListener l)

    public synchronized WindowStateListener[] getWindowStateListeners()

    protected void processItemEvent(ItemEvent e)

java.awt.event.WindowAdapter の変更点:

    public void windowStateChanged(WindowEvent e)

java.awt.AWTEventMulticaster の変更点:

    public static WindowStateListener add(WindowStateListener a, WindowStateListener b)

    public static WindowStateListener remove(WindowStateListener l, WindowStateListener oldl)

サイズ変更時の動的なレイアウト

この変更に関連するバグ追跡レポート: 4077991

これまでは、どのプラットフォームでもウィンドウの大きさの動的な変更はサポートされていませんでした。 たとえば Windows NT では大きさの静的な変更を「オン」にすると、ドラッグが終了したときにだけレイアウトが再計算されて、ウィンドウの大きさが変更されました。 このリリースでは、この機能が修正されて新規デスクトッププロパティ awt.dynamicLayoutSupported が追加されました。 動的レイアウトが有効なときは、Container は大きさの変更に伴ってコンポーネントを連続的に配置します。 無効なときは、大きさの変更が終了した後でレイアウトが検証されます。

java.awt.Toolkit の API の変更点:

    public void setDynamicLayout(boolean dynamic)

    protected boolean isDynamicLayoutSet()

    public boolean isDynamicLayoutActive()

コンポーネントリスナリストへのアクセス

この変更に関連するバグ追跡レポート: 4290704.

これまでは、書き込み可能なすべての AWT コンポーネントは読み取ることもできました。 たとえば、コンポーネント API には書き込み専用のプロパティはありません。 イベントリスナはまったくの例外でした。 AWT イベントリスナには次のような 1 組のメソッドがあり、JavaBeansTM の規則に従って管理されています。 XXXEventListener インタフェースを実装するリスナの addXXXListener メソッドと removeXXXListener メソッド。

リスナリストそのものへのアクセス機能は提供されませんでした。 リスナリストを含むフィールドは package private で、リスナリストの内容を戻すメソッドは提供されませんでした。 これは Swing や他の AWT クライアントにおける問題の原因になっていました。

バージョン 1.3 の Java 2 SDK の問題を軽くするために、ComponentgetListeners メソッドを追加し、リスナリストを定義した Swing クラスにも追加しました。 getListeners メソッドは、クラスを使って特定のリスナリストを指定します。 たとえば、addFocusListener により追加されたすべてのリスナを得るためには、次のように記述します。 getListeners(FocusListener.class)

リスナリストを公開するこの特定のアプローチにより、AWT/Swing public API 全体の変更を最小限にすることができました。 これはすべての JavaBeans の規則にするためのものではなく、addPropertyChangeListener("myProperty", myListener) のような単独のプロパティに追加できる PropertyChangeListener は扱いませんでした。 このリリースでは、イベントリスナにアクセスできる、より完成度の高いソリューションが設計されています。 概念上は、次の 2 点が変更されています。

新規クラス java.awt.event.AWTEventListenerProxy があります。

java.awt.Toolkit の API の変更点:

    public PropertyChangeListener[] getPropertyChangeListeners()

    public synchronized PropertyChangeListener[] getPropertyChangeListeners(String propertyName)

    public AWTEventListener[] getAWTEventListeners()

    public AWTEventListener[] getAWTEventListeners(long eventMask)

ドラッグ&ドロップの変更点

この変更に関連するバグ追跡レポート: 4407057 および 4426750.

Solaris および Linux 版の Java 2 Standard Edition, SDK 1.3 では、アプリケーションが java.awt.dnd API を使って AWT 重量 ComponentsDragSource として識別しない場合でも、マウスのアジャストボタンでデフォルトのドラッグ動作を示す Component がいくつかありました。 このような Component は Motif ピアを使って実装され、Motif はマウスのアジャストボタンのドラッグ動作をデフォルトでこれらのピアに提供します。

AWT の設計上の問題と Motif ライブラリのバグのために、このデフォルトの動作は安定性に関するさまざまな問題の原因になっています。 今後も AWT とドラッグ&ドロップの安定性を危険にさらし続けるよりは、この機能を実装せずに明確に無効にする方がいいと判断しました。

それでも java.awt.dnd API を使えば、開発者はアプリケーションの ComponentDragSource と見なすことができます。 これは機能的でもあり、サポートの対象でもあります。 このアプローチは、デフォルトの Motif 動作に依存するよりも、常に優れています。Solaris と Linux だけではなく、すべてのプラットフォームで Component のドラッグをサポートできるからです。

現在のウィンドウマネージャを明確にする

この変更に関連するバグ追跡レポート: 4384023.

AWT は現在どのウィンドウマネージャが実行されているのかを判断するヒントを検索し、この情報を使って特定のウィンドウマネージャに合わせたコードを実行します。 ただし、以前のバージョンでは、この情報が無効になるとバグレポートにあるような非常に奇妙な効果を生じるバグが発生しました。

このバグは今回のリリースで修正されましたが、難しい副作用が生じる可能性もあるので注意が必要です。

古いコードでは、特定のアトムがインターン (X Window システムにおける、Intern Atom の呼び出し) されているかどうかを確認して、現在のウィンドウマネージャを単純に検出していました。これは、特定のウィンドウマネージャがそうしたアトムをインターンするという前提に基づいているためです。 新しい実装ではより洗練された確認方式を採用しています。確認の一部として、古いコードが検索するのと同じアトムをインターンします。 その結果、この訂正された JDK を実行すると、古いビルドの JDK に混乱が生じます。 たとえば、古いコードがテストする最初のウィンドウマネージャは Enlightenment (アトム ENLIGHTENMENT_COMMS) です。 新しいコードによってこのアトムが保持されると、古いコードは新しいコードが Enlightenment の下で実行されていると見なします。現在のウィンドウマネージャが Enlightenment ではない場合、Enlightenment 用のコードが間違った結果を作成するたびに、好ましくない影響が発生します。

残念ながらこのような副作用は避けることができません。 修正されたビルドを実行した後で、他の古いビルドを実行する必要がある場合、X サーバをリセットして、古いコードを混乱させる余分なアトムをすべて取り除く必要があります。

X サーバの再起動Unix で X サーバを再起動するには、X セッションを終了する必要があります。 Win 32 では、通常、X サーバのメニューには「リセット」という項目があります。

64 ビット対応の Solaris マシン

この変更に関連するバグ追跡レポート: 4295833

64 ビットの Solaris アプリケーションは、32 ビットではなく 64 ビットを使ってメモリにアクセスします。これにより、仮想メモリの容量を増やして大容量のアプリケーションが使用できるようなります。 このリリースの AWT は 64 ビットまで対応しています。 詳細は、ここ を参照してください。

一貫性のない DLL 警告

この変更に関連するバグ追跡レポート: 4414004.

アジア系言語版の Windows NT もインストールされているマシンに英語版の VC++ 6.0 をインストールした場合、TextArea コンポーネントにアジア系言語版のテキストを使用すると、文字化けが発生します。 この問題は、2 バイト対応の Windows NT が動作しているマシンに Microsoft Exchange または Microsoft Office 97 をインストールしても発生します。 この問題は日本語版の Windows NT で報告されましたが、中国語や韓国語版といった非ラテン系言語版でも発生すると思われます。

この問題は、プログラムのインストール時に アジア系言語版 Riched32.dll が英語版に置き換わったために生じました。 Riched32.dll をアジア系言語版に置き換えると、問題は解決します。

描画面 API の削除

この変更に関連するバグ追跡レポート: 4293646.

sun.awt.DrawingSurface API が削除されました。 これまで公表されたことはありませんが、使用している開発者もいます。 この API の機能は JAWT に置き換えられています。 詳細は、AWT 1.3 リリースノートの AWT Native Interface にある説明を参照してください。

マルチスクリーンのサポートに必要なウィンドウの中央配置 API

この変更に関連するバグ追跡レポート: 4463949.

マルチヘッドシステムで動作する Xinerama 対応のアプリケーションでさまざまな問題が発生し、バグレポートが作成されています。 マルチヘッド環境でボーダーの小さいモニタを使用している場合は、モニタどうしが接触し合い、その結果 1 つの巨大なディスプレイのような効果が得られます。 この場合は、「適切に」中央配置されたウィンドウが複数の画面にまたがって表示されます。 マルチヘッド環境で通常の CRT モニタを使用している場合は、実際の表示領域どうしの間に数インチの差が生じます。 この場合、ウィンドウをドラッグできないモニタ (Solaris のログイン画面など) がある場合は特に、複数の画面にまたがるウィンドウに奇妙な効果が発生します。 つまり、Xinerama 環境のどこを中心にウィンドウを配置するかを指示する方法がなかったのです。

この問題に対処するため、X グループに API が追加されました。この API を使って、Xinerama のユーザはウィンドウ配置の中心を指定でき、Xinerama 対応アプリケーションの開発者は適切にコーディングできるようになりました。

このリリース以前は、次のようにデフォルトの GraphicsDevice の境界内でウィンドウを中央配置していました。

    bounds = getDefaultScreenDevice().getDefaultConfiguration().getBounds();
    frame.setLocation(bounds / 2 - ウィンドウサイズ / 2);
このコードによって、Xinerama システムのウィンドウが Xinerama 全体の座標空間に正しく中央配置されていました。

このリリース以降の 4356756 修正済み JDK では、Xinerama システムのウィンドウは、プライマリディスプレイの中に正しく中央配置されるようになります。

これを実現するために、getCenterPoint メソッドが GraphicsEnvironment に追加されました。

このメソッドは、各種プラットフォームで次のように動作します。

JDK 1.4 から、中央配置のための正しいコードは次のようになります。

    frame.setLocation(getCenterPoint() - ウィンドウサイズ / 2);

GraphicsEnvironment に追加されたもう 1 つのメソッドは getMaximumWindowBounds です。 getCenterPointgetMaximumWindowBounds はどちらも、ヘッドレスモードのときに HeadlessException をスローします。

新しい InputEvent キー修飾子

この変更に関連するバグ追跡レポート: 4387938 および 4421515

これまで、 InputEvent 修飾子は、キーボードとマウスボタンに対して同じ値を持っていました。 状況によっては、どのキーやボタンが押されたのかを区別できないことや、同時に複数押されたときに判別できないことがありました。 このような状況としては、同時に複数のマウスボタンが押されたときや、マウスイベントが修飾子によって変更されたときなどがあります。

この欠陥を解決するために、次の定数が InputEvent に追加されました。

次のメソッドが InputEvent に追加されました。

MouseEvent のクラス仕様が更新されました。 次の定数も MouseEvent に追加されました。

次のメソッドが MouseEvent に追加されました。

DragSourceDragEvent に新しい getGestureModifiersEx メソッドが追加されました。

Choice メニューのドロップダウン動作の変更点

この変更に関連するバグ追跡レポート: 4462677.

Choice ドロップダウンメニューの動作が、JDK 1.3.1 から 1.4 の間で変更されました。 1.3.1 では、Choice バーのどこをクリックしてもドロップダウンメニューが表示されました。 1.4 では、Choice バーの右にある矢印をクリックする必要があります。 Choice バーの他の部分をクリックしても何も起きません。 Choice バーの記号も、バーから矢印とバーを組み合わせたものに変更されました。 最後に、ドロップダウンメニューが展開されたとき、親の外に出ている部分をクリックすると、その下にあるアプリケーションが前面に表示されます。 ただし、これは Solaris での動作であり、Windows では異なります。

推奨されない Focus メソッド

この変更に関連するバグ追跡レポート: 4476300.

このリリースで導入された新しいフォーカスサブシステムでは、AWT および Swing の高度なアプリケーションでキーボードフォーカスを扱うために、新しいアーキテクチャと用語が導入されました。 このプロジェクト以前は、フォーカス関連の API の多くで使用法と用語に整合性がなく、ドキュメントにも不備があったために、不完全な設計の UI につながっていました。 新しいアーキテクチャが導入された現在では、これらの API のうち特に使用を避けるべきものがあります。

次の定数とメソッドは推奨されなくなりました。

タイムスタンプを必要とする ActionEvent (およびその他のイベント)

この変更に関連するバグ追跡レポート: 4434193.

新しいフォーカスアーキテクチャには、先打ち機構も含まれています。この機構では、ある KeyEvent でフォーカス移動が開始されると、移動が完了するまで、後続の KeyEvent は配信されなくなります。 この機能の設計は、各種イベントの UTC タイムスタンプに基づいています。 移動を開始したイベントより後のタイムスタンプを持つイベントは移動の待ち行列に入れられますが、それより前のタイムスタンプを持つイベントは入れられません。

この機能を実現するために、フォーカスコードでは、現在処理中のイベントのタイムスタンプを常に監視しています。 この処理中にフォーカス移動が開始された場合は、そのタイムスタンプを使用できます。 ただし、現在処理中のイベントにタイムスタンプがない場合は、システムの現在時刻が使用されます。 現在時刻を使用する場合、通常イベントが実際に発生した時刻よりもかなり進んでいるため、実際には役立ちません。 結果として、先打ち機構は失敗し、フォーカス移動が完了する前に KeyEvent が配信されます。

この問題は ActionEvent で最も多く発生していました。 ActionEvent は、基となるInputEvent に対応して生成される、高レベルのセマンティックイベントです。 InputEvent にはタイムスタンプが関連付けられていましたが、ActionEvent はタイムスタンプを持っていませんでした。 したがって、タイムスタンプを格納できるように ActionEvent API が拡張されました。また、実装も更新され、ActionEvent のタイムスタンプと、基盤となる InputEvent のタイムスタンプとが一致するようになりました。

次のメソッドが ActionEvent に追加されました。

次の ActionEvent メソッドが変更されました。

getWhen メソッドが InvocationEvent に追加されました。

InvocationEvent InvocationEvent(Object, Runnable) コンストラクタと InvocationEvent(Object, Runnable, Object, boolean) コンストラクタが変更されました。

新しい InputMethodEvent(Component, int, long, AttributedCharacterIterator, int, TextHitInfo, TextHitInfo) コンストラクタが InputMethodEvent に追加されました。 getWhen メソッドも追加されています。

次の InputMethodEvent コンストラクタが変更されました。

最後に、次のメソッドが EventQueue に追加されました。


Copyright © 2001 Sun Microsystems, Inc. All Rights Reserved.


コメントの送付先: java-awt@java.sun.com
Sun