連載
» 2006年10月18日 10時00分 UPDATE

JavaTips 〜Javaプログラミング編:Swingアプリで「import java.awt.*」の使用は要注意

[平野正喜,@IT]

 AWTの改良版であるSwingは、プラットホームを選ばず、かつユーザーインターフェイスの手軽な開発を実現する技術として利用されています。しかし、Swingだけでは実現できない機能もあり、この場合はAWTのパッケージである「java.awt」をインポートする必要があります。

 多くの書籍やサイトに掲載されているサンプルリストでは「import java.awt.*;」を宣言していますが、これは避けましょう。「import java.awt.BorderLayout;」というように、用いるクラスを個別に宣言しましょう。

 例として、下記のプログラムを作成しました。Swingの基本であるフレームを生成して、メニューおよびレイアウトを設定し、パネルを貼り付けるという簡単で基本的なサンプルです。

トラブル要因を含んでいるプログラム トラブル要因を含んでいるプログラム

 ところがこのプログラムを実行すると不思議な現象が起こります。メニューをクリックしてもメニュー項目が表示されないのです。しかも、コンパイルエラーはもちろんのこと、例外も一切発生しません。

プログラムの実行結果(メニュー項目が表示されない) プログラムの実行結果(メニュー項目が表示されない)

 実は、このトラブルは、たった1文字のタイプミスにより発生しました。「f.getContentPane().add(new Panel()); // パネルを生成し追加」の「Panel」の前に「J」を打ち忘れただけなのです。

 javax.swingパッケージに含まれるJPanelクラスに対して、java.awtパッケージに含まれるPanelクラスは、継承関係や動作が近いため、間違って用いても、この構文ではコンパイルエラーになりません。それどころか、実行すると動作してしまい、SwingとAWTの実装の違いがあるにも関わらず例外を起こしません。

 そして、実行してメニューをクリックしてもアイテムが表示されないため、パネルの記述ミスとは気づかず、メニュー関連の記述に間違えがあると考えてしまいやすいのです。もし、これが長いプログラムの場合、ミスをした場所を探すのは「至難の業」かもしれません。

「import java.awt.*」を避けるとミスは防げる

 この問題が発生した遠因は、AWTパッケージに含まれているBorderLayoutクラスに対応するクラスがSwingにないことにあります。そのため、安易に「import java.awt.*」と宣言してしまったのですが、ここで、呼び出し時にjava.awt.BorderLayoutと指定するか「import java.awt.BorderLayout;」としてあれば、Panelクラスはインポートされないため、トラブルは回避できたわけです。

 具体的には下記に示すように、プログラミングまたはコンパイルの時点でエラーになり、タイプミスに気づくことができます。

Eclipseであれば、コンパイル前にミスに気づくことができる Eclipseであれば、コンパイル前にミスに気づくことができる

 import文での「*」指定を禁止するような厳しいコーディングルールを定めたり、推奨している方もいますが、そこまではしなくても、Swingアプリケーションにおいては「import java.awt.*;」を避けることがミス防止とトラブル解消に効果的だといえるでしょう。

Profile

RunDog.org

平野正喜


Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。