本文へジャンプ

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む


お客様が developerWorks に初めてサインインすると、プロフィールが作成されます。プロフィールで選択した情報は公開されますが、いつでもその情報を編集できます。お客様の姓名(非表示設定にしていない限り)とディスプレイ・ネームは、投稿するコンテンツと一緒に表示されます。

送信されたすべての情報は安全です。

  • 閉じる [x]

developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む


送信されたすべての情報は安全です。

  • 閉じる [x]

Merlinの魔術: AWTの概要

サイジング、カラー、マウス・ホイール、および入力イベントの変更に関する詳細

John Zukowski (jaz@zukowski.net), President, JZ Ventures, Inc.
Author photo
John Zukowskiは、JZ Ventures, Inc.の戦略的Javaコンサルティングを推進し、数多くのjGuruのコミュニティー主導のJava FAQsで常任指導者として活躍しています。最新の著書には、Apressから出版された「 Java Collections」および「 Definitive Guide to Swing for Java 2」 (第2版) があります。彼のメール・アドレスはjaz@zukowski.net です。

概要: デスクトップ・ツールバーのような画面アクセサリーに使用されているスペースを検出する機能、カラー定数の大文字化、マウス・ホイールのサポート、マウスとキーボードのキーおよび配置をより適切に識別する機能など、Merlinはいくつかの機能をAWTライブラリーに追加しています。John Zukowskiがこうした変更点を解説し、読者のみなさんが時間をかけずに使ってみることができるように、重要な詳細を提供します。

日付:  2001年 11月 01日
レベル:  初級 この記事の原文:  英語
アクティビティー: 1635 ビュー
お気軽にご意見・ご感想をお寄せください: 


Abstract Window Toolkit (AWT) は、Merlinの新規リリースによってアップグレードされました。変更点の多くは小規模なものですが、解説しておくだけの重要性はあります。今月は次の4つの新機能に注目しましょう。

  • 画面アクセサリーが使用するスペースを検出する機能
  • Color クラスにおける定数の大文字化
  • マウス・ホイールのイベントへの反応をサポート
  • マウス・ボタン、キーパッド・キー、シフト・キーをより適切に識別する機能

はじめに

AWTの新機能を説明するために、画面のサイズをフル・サイズ(からツールバーのようなデスクトップ・アクセサリーを引いた部分)まで拡大し、新しいカラー定数を使用して背景を設定するプログラムを作成します。このプログラムでは、マウス・ホイールを回すか、または左右のシフト・キーを使用して、背景色を変更することができます。

リスト1では、プログラムの基本的な外枠を紹介します。残念ながら、利用するマウス・ホイールのサポート機能にはまだバグがあります(詳細については参考文献を参照)。これを機能させるために、ここではJButtonJScrollPane のフレームに追加しています。このバグのため、この外枠は必要以上に複雑になっています。


リスト1. クローズ可能なフレームを作成するシェル
                
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class AwtTest {
  // See bug 4475240
  static JButton button = new JButton();
  static JScrollPane pane = new JScrollPane(button);
  public static void main(String args[]) {
    JFrame frame = new JFrame("AwtTest");
    // See bug 4475240
    frame.getContentPane().add(button, BorderLayout.CENTER);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.show();
  }
}


ツールキット・インセット

以前のコラムでは、 setExtendedState() を使ってFrame を最大化する機能について述べました。状態をFrame.MAXIMIZED_BOTH に設定すれば、フレームは最大化されます。ただし、フレームを最大化したくはないが、デスクトップ・アクセサリーを除いたユーザーのデスクトップ領域いっぱいにサイズを変更したい場合は、アクセサリーが使用するInsetsが必要です(リスト2を参照)。この情報については、ツールキットgetScreenInsets() メソッドによって提供されます。画面サイズからインセットを差し引くと、ウィンドウはあるべきサイズになります。適切に配置するには、上部インセットと左インセットも使用する必要があります。


リスト2. 画面のサイズ変更
                
private static void sizeScreen(JFrame frame) {
    Toolkit kit = Toolkit.getDefaultToolkit();
    Dimension screenSize = kit.getScreenSize();
    GraphicsConfiguration config = frame.getGraphicsConfiguration();
    Insets insets = kit.getScreenInsets(config);
    screenSize.width -= (insets.left + insets.right);
    screenSize.height -= (insets.top + insets.bottom);
    frame.setSize(screenSize);
    frame.setLocation(insets.left, insets.top);
  }

main() メソッドにsizeScreen() の呼び出しを追加してください。


色指定定数の大文字化

Java言語仕様のセクション6.8には、パッケージ、メソッド、フィールド、定数などのアイテムの命名規則が記載されています。定数名に関するサブセクション (6.8.5) では、定数に小文字を使ってはならないと記載されていますが、redgreenblue のようなColor クラスのカラー定数はすべて最初から全文字が小文字で指定されています。Merlinではレコードを訂正して、同じ定数をすべて大文字でも提供するようになりました。まだ前の名前を使えないようにしていませんが、Java Standard Edition 1.4プログラムでは新規の名前を使用することができます。

このテスト・プログラムでは、カラー定数の配列とそれらをループするカウンターを作成し、2つの方向のうちいずれかにその配列をループするchangeBackground() メソッドを用意します(リスト3を参照)。


リスト3. 背景色の変更
                
private static final Color colors[] = {
    Color.BLACK,
    Color.BLUE,
    Color.CYAN,
    Color.DARK_GRAY,
    Color.GRAY,
    Color.GREEN,
    Color.LIGHT_GRAY,
    Color.MAGENTA,
    Color.ORANGE,
    Color.PINK,
    Color.RED,
    Color.WHITE,
    Color.YELLOW
  };
  static int colorCounter;
  private static final int UP = 1;
  private static final int DOWN = 2;
  private static void changeBackground(JFrame frame, int direction) {
    // See bug 4475240
    // w/o bug, change background of getContentPane()
    button.setBackground(colors[colorCounter]);
    // Update counter based on direction
    if (direction == UP) {
      colorCounter++;
    } else {
      --colorCounter;
    }
    // Wrap colors
    if (colorCounter == colors.length) {
      colorCounter = 0;
    } else if (colorCounter < 0) {
      colorCounter = colors.length-1;
    }
  }

main() ルーチンにchangeBackground() メソッドへの呼び出しを追加してください。

命名規則はGridBagLayout などのクラスでも更新されました。そのようなクラスには、AdjustForGravity() のようなプロテクトされたメソッドが、小文字から始まるように変更されています。


マウス・ホイールの動きの検出

Java開発者が前世紀から強く求めていた1つの機能は、マウス・ホイールの回転のサポートです。Merlinのリリースにより、MouseWheelListener をどんなComponent にも付加して、うまく反応できるようになりました。先に述べたバグを別にすれば、これは問題なく機能します。JScrollPane コンポーネントには事前登録済みのリスナーも付属しています。そのため、フォーカスがあるときにユーザーがホイールを動かすと、ペインがスクロールします。

リスナーには、その唯一つのメソッドとしてmouseWheelMoved() があり、これはMouseWheelEvent を引数にとります。このイベントから、getScrollType() がユニット・スクロールであろうとブロック・スクロールであろうとgetScrollAmount() によってスクロール量を、getWheelRotation によってホイール回転の方向と数を、そして便宜的なものとしてgetUnitsToScroll() によってスクロール単位を確認することができます。

このテスト・プログラムでは、リスト4で示すような方向に基づいて背景色にカラー配列をループさせるホイール・リスナーを付加します。ドキュメンテーションには、マウス・ホイールのイベントはコンテナーの階層をさかのぼると記載されていますが、バグがあるためこのようにならないので、ボタンにリスナーを付加する必要があります。このリスナーを必ずmain() メソッドで付加してください。


リスト4. ホイール・リスナーの付加
                
  private static void attachMouseWheelListener(final JFrame frame) {
    MouseWheelListener listener = new MouseWheelListener() {
      public void mouseWheelMoved(MouseWheelEvent e) {
        int count = e.getWheelRotation();
        int direction = (Math.abs(count) > 0) ? UP : DOWN;
        changeBackground(frame, direction);
      }
    };
    button.addMouseWheelListener(listener);
  }


入力イベント

このテスト・プログラムでは付加された機能のほんの一部しか利用しないのですが、この最後の機能は、当初の想像よりも広範囲にわたります。基本的に、Merlinは 同じキー (キーパッドおよび標準) の様々なバージョンと、キーボード・キーおよびマウス・ボタンの様々なシーケンスを識別する機能を付加します。たとえば以前には、シフト・クリックと、異なるボタンのクリックとの違いを伝える方法がありませんでした。両方とも同じマウス・イベントを引き起こしていました。InputEvent クラスで次の新規の定数を用いると、すべてが変わります。

  • ALT_DOWN_MASK
  • CTRL_DOWN_MASK
  • META_DOWN_MASK
  • SHIFT_DOWN_MASK
  • BUTTON1_DOWN_MASK
  • BUTTON2_DOWN_MASK
  • BUTTON3_DOWN_MASK
  • BUTTON1_CHANGED_MASK
  • BUTTON2_CHANGED_MASK
  • BUTTON3_CHANGED_MASK

どのボタンを押しているのかだけを調べたい場合は、次のメソッドがより役立ちます。

  • isButton1Down()
  • isButton2Down()
  • isButton3Down()

MouseEvent は、状態を変更したボタンを発見するgetButton() メソッドも提供します。

こうしたすべてのメソッドと定数によって、ボタン・イベントへの反応はより容易になるはずです。

同じキーの様々なバージョンを識別するには、KeyEvent クラスの変更が必要です。getKeyLocation() によってそのイベントにキー配置を求めることができます。次の定数のうちいずれかを戻します。

  • KEY_LOCATION_LEFT
  • KEY_LOCATION_NUMPAD
  • KEY_LOCATION_RIGHT
  • KEY_LOCATION_STANDARD
  • KEY_LOCATION_UNKNOWN

キーの配置場所を求めることによって、キーパッドと標準キー、および左右のシフト・キーを識別することができます。

このテスト・プログラムでは、リスト5で示すように、左と右のどちらのシフト・キーが押されているかに基づいて、キー・リスナーにループ・アップやループ・ダウンを実行させるだけです。必ず最初に、押されているキーをチェックし、それから配置をチェックする必要があります。そしてもちろん、ルーチンへの呼び出しはmain() メソッドに追加します。


リスト5. キー・リスナーの付加
                
  private static void attachKeyListener(final JFrame frame) {
    KeyListener listener = new KeyAdapter() {
      public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
          int location = e.getKeyLocation();
          int direction = (location == KeyEvent.KEY_LOCATION_LEFT) ? UP : DOWN;
          changeBackground(frame, direction);
        }
      }
    };
    button.addKeyListener(listener);
  }


完全な例

リスト6では、以上の新機能を試用するための完全な例を紹介します。マウス・ホイール・リスナーのバグが修正されると、ボタンを使用しなくても、ペインをスクロールすることができます。


リスト6. 完全な例
                
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class AwtTest {
  private static final Color colors[] = {
    Color.BLACK,
    Color.BLUE,
    Color.CYAN,
    Color.DARK_GRAY,
    Color.GRAY,
    Color.GREEN,
    Color.LIGHT_GRAY,
    Color.MAGENTA,
    Color.ORANGE,
    Color.PINK,
    Color.RED,
    Color.WHITE,
    Color.YELLOW
  };
  static int colorCounter;
  private static final int UP = 1;
  private static final int DOWN = 2;
  // See bug 4475240
  static JButton button = new JButton();
  static JScrollPane pane = new JScrollPane(button);
  private static void sizeScreen(JFrame frame) {
    Toolkit kit = Toolkit.getDefaultToolkit();
    Dimension screenSize = kit.getScreenSize();
    GraphicsConfiguration config = frame.getGraphicsConfiguration();
    Insets insets = kit.getScreenInsets(config);
    screenSize.width -= (insets.left + insets.right);
    screenSize.height -= (insets.top + insets.bottom);
    frame.setSize(screenSize);
    frame.setLocation(insets.left, insets.top);
  }
  private static void changeBackground(JFrame frame, int direction) {
    // See bug 4475240
    // w/o bug, change background of getContentPane()
    button.setBackground(colors[colorCounter]);
    // Update counter based on direction
    if (direction == UP) {
      colorCounter++;
    } else {
      --colorCounter;
    }
    // Wrap colors
    if (colorCounter == colors.length) {
      colorCounter = 0;
    } else if (colorCounter < 0) {
      colorCounter = colors.length-1;
    }
  }
  private static void attachMouseWheelListener(final JFrame frame) {
    MouseWheelListener listener = new MouseWheelListener() {
      public void mouseWheelMoved(MouseWheelEvent e) {
        int count = e.getWheelRotation();
        int direction = (Math.abs(count) > 0) ? UP : DOWN;
        changeBackground(frame, direction);
      }
    };
    // See bug 4475240
    // w/o bug, add to frame
    button.addMouseWheelListener(listener);
  }
  private static void attachKeyListener(final JFrame frame) {
    KeyListener listener = new KeyAdapter() {
      public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
          int location = e.getKeyLocation();
          int direction = (location == KeyEvent.KEY_LOCATION_LEFT) ? UP : DOWN;
          changeBackground(frame, direction);
        }
      }
    };
    // See bug 4475240
    // w/o bug, add to frame
    button.addKeyListener(listener);
  }
  public static void main(String args[]) {
    JFrame frame = new JFrame("AwtTest");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // See bug 4475240
    frame.getContentPane().add(button, BorderLayout.CENTER);
    sizeScreen(frame);
    changeBackground(frame, UP);
    attachMouseWheelListener(frame);
    attachKeyListener(frame);
    frame.show();
  }
}


参考文献

著者について

Author photo

John Zukowskiは、JZ Ventures, Inc.の戦略的Javaコンサルティングを推進し、数多くのjGuruのコミュニティー主導のJava FAQsで常任指導者として活躍しています。最新の著書には、Apressから出版された「 Java Collections」および「 Definitive Guide to Swing for Java 2」 (第2版) があります。彼のメール・アドレスはjaz@zukowski.net です。

不正使用の報告のヘルプ

不正使用の報告

ありがとうございます。 このエントリーは、モデレーターの注目フラグが設定されました。


不正使用の報告のヘルプ

不正使用の報告

不正使用の報告の送信に失敗しました。


developerWorks: サイン・イン


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 利用条件

 


お客様が developerWorks に初めてサインインすると、プロフィールが作成されます。 プロフィールで選択した情報は公開されますが、いつでもその情報を編集できます。 お客様の姓名(非表示設定にしていない限り)とディスプレイ・ネームは、投稿するコンテンツと一緒に表示されます。

表示名をお選びください

developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

(半角英数字で3文字以上31文字以下にする必要があります)


「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 利用条件

 


この記事を評価する

コメント

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Java technology
ArticleID=218849
ArticleTitle=Merlinの魔術: AWTの概要
publish-date=11012001
author1-email=jaz@zukowski.net
author1-email-cc=jaloi@us.ibm.com

タグ

Help
このタグで、My developerWorks のすべてのタイプのコンテンツを見つけるために検索フィールドを使用します。

スライダーバーを使用することで、より多く(少なく)タグを表示します。

人気のタグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するトップのタグを表示します。

マイ・タグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するお客様ご自身のタグを表示します。

このタグで、My developerWorks のすべてのタイプのコンテンツを見つけるために検索フィールドを使用します。人気のタグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するトップのタグを表示します。マイ・タグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するお客様ご自身のタグを表示します。