

意外と知られていないAWTの正しい使い方?
Window や Frame は、dispose() でリソースを開放する。WindowEvent.WINDOW_CLOSEDを発行する?
×ボタンを押してから閉じるまで、いろいろ処理があります。基本的な手順はこんなかんじ?
入門書などで紹介されている windowClosing() のなかで System.exit() をしてしまう強引な作法は、なんとなく怖いですね。dispose() でリソースが破棄されると、他にスレッドがなければ勝手に終了してくれるので System.exit() などは使わない方がいいです。
WindowListener を使わなくていい方法もあります。
JFrame.setDefaultCloseOperation() です。こっちの方がお手軽かも。やってることは System.exit() みたいなものですが。
Componentなどのサイズを指定するには、3つのサイズがあります。
最小サイズ(minimumSize)、最大サイズ(maximumSize)、推奨サイズ(preferredSize)。
この内、LayoutManagerを使うときに指定しなければならないのは、推奨サイズのようです。
minimumSizeやsizeだけを指定してみても、小さくなってしまう場合があります。
アプレットやアプリケーションで画像を読み込み表示するのは、いったいどうすればいいのか?
アプレットの場合は、本を立ち読みでもすれば簡単にわかるが、アプリケーションの場合は、なかなか載っている本が無い。
よくこれでJDK1.0の頃・・・使えてたな・・・(^^;
アプレットで画像を読み込む場合は、java.applet.Applet#getImage() メソッドを使う。
このメソッドでは画像を読み込み終わる前にすぐに次の処理に移ります。表示してみると徐々に読み込まれていくのがわかるかもしれません。アプレットを待たせないための策なのですが、一般的な処理には向かないこともあるのでMediaTracker で読み終わるまで待つこともできます。
JPEG, GIF が読み込めますがPNGなどは無理かもしれません。
アプリケーションの場合は、あまり表向きのAPIが用意されていません。どうするかというと、裏方的な存在であるjava.awt.Toolkitクラスを使います。
ComponentからToolkitをgetToolkit()で取得、Toolkitクラスを使って画像を読み込む。Toolkit.getDefaultToolkit() でもいいのですが、どうなんでしょな。
あとは、Toolkit.createImage() などで画像が読み込めます。ファイルに限らずGIF、JPEGなどのバイト列からImage化することもできます。
Swingアプリケーションでただ画像を表示したいだけなら、ImageIcon クラスを使うのも手軽かもしれません。
J2SE 1.4 からは、 Java Image I/O (javax.imageio) によって画像が読み書きできるようになりました。
取得できるのは BufferedImgae です。サポートされている画像形式が他より多いかも?
Java Advanced Imaging ではさらに他の方法も?
参考
Javaで使える画像と呼ばれるものには、いくつかのクラスがあります。それぞれ微妙に役割が違ってくるかもしれません。
JDK 1.0からある、基本的な画像格納クラスです。アニメーションGIFや透過GIFにも対応していたり、ときどき変なやつです。
データの保存にはBufferedImage の方が適していますが、それでも使いにくいところは多々あります。
こちらは表示のための画像保持をするところです。表示のためのものなので、アプリケーションから中身を読んでみたり、別のImageやCanvasへコピーしたりという用途には向かないかもしれません。画面に依存してビット深度なども変わるかもしれない。
Swingの部品として利用できるものです。あまり使ったことはありませんが、止め絵には最適でしょうか。Canvas の後継みたいなものですかね。
ちらつき防止は、update(Graphics) メソッドを変えますが、このとき、paint(Graphics)を呼び出していませんか?
Image im; // imは、updateの先頭で毎回作るか、あらかじめ準備する
public void update(Graphics g) {
Graphics g2 = im.getGraphics();
super.update(g2);
g.drawImage(im);
}
これだけでいいのです。Swingでは最初からちらつき防止処理がされているようです。
また、複数のAWT/Swing部品を組み合わせて画面を構成している場合には、更新が必要な部品だけrepaint()メソッドを使用することをおすすめします。
マウスの座標やボタンの状態を取得することができます。どのようにすればよいのでしょうか。
ここでは、JDK1.1以降で使われている形式を扱います。もう1.0使っているところもないでしょう・・・。
マウスの動きの受け取り方にはいくつかの方法があります。
これらは、だいたい同じようにして実現できます。大抵はjava.awt.event パッケージのイベント処理という形で処理されます。
各動作はイベンとという形でプログラムに通知されます。各種のイベントを受け取るには、イベントリスナーというインターフェースを継承して、対象となるAWT/Swingパーツにその継承したオブジェクトを登録します。リスナーとなるクラスとAWT/Swingのパーツは全く別のものでかまいません。イベントの処理だけなら、AWT/Swingクラスを継承しないで、イベントインターフェースを使うだけにするほうがよいです。
1.マウスの動きを知りたい場合。java.awt.event.MouseListenerと、MouseMotionListener かな。
mouseMoved() mouseClicked() などのメソッドで、MouseEvent を取得して、そこから座標やボタンの状態を得ることができます。作ったオブジェクトは、 AWT/Swing部品に、addMouseListener() などのメソッドがあるので、それを使って登録します。
2.と3,AWTボタンやメニューなどのAWT/Swing部品の場合は、java.awt.event.ActionListener を使います。
actionPerformed(ActionEvent e) を継承し、イベントを処理します。
java.awt.dnd になにやらあるようです。なかなか仕様は日本語になってくれませんね。
どちらかというと、Drop(受け側)の方から作ってみるのが簡単そうです。
Drag側のプログラム
Drop側のプログラム
import java.awt.*;
import javax.swing.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
public class TestApplocation implements DropTargetListener {
JFrame frame;
DropTarget dt; // Drop処理をしてくれるjava.awt.dnd.DropTargetクラス
TestApplication() {
frame = new JFrame("Test");
frame.getContentPane().add(new JPanel()); // this でも new JPanelでもなんでもいい dropしたいコンポーネント
frame.setSize(640,340);
frame.setVisible(true);
frame.setDropTarget(dt = new DropTarget()); // frame か JPanelどっちでもDropしたい方のsetDropTarget()を使う
try {
dt.addDropTargetListener(this); // 受け取るリスナー
} catch (java.util.TooManyListenersException e) {
}
// dt = new DropTarget(frame, this): の方が楽かも
}
public void drop(DropTargetDropEvent dtde) {
// 受け取れる型の一覧を出してみる
java.awt.datatransfer.DataFlavor[] dfs;
dfs = dtde.getCurrentDataFlavors();
for (int i = 0; i < dfs.length; i++) {
System.out.println(dfs[i].getMimeType());
}
// 受け取る方法を指定
dtde.acceptDrop(java.awt.dnd.DnDConstants.ACTION_COPY);
// 受け取る
型Object obj = (型変換)dtde.getTransferable().getTransferData(dfs[何番目か]);
}
public static void main(String[] argv) {
new TestApplication();
}
}
こんな感じ。MouseListenerとあまり変わりませんが、いろいろな型のなかからどの型で受け取るのかの指定が大変かもしれません。
drop() 以外に dragEnter() などでも同じような処理でドラッグ中にデータを受け取ってしまうことができます。そのときには acceptDrop() の指定はいらないようです。
参考
しいしせねっと