こんにちは。「Javaを復習する初心者」です。
JavaでGUIプログラミングをする場合、画像を描画することがあると思います。今回はフレーム内に画像を表示するということをしてみました。
全体像
フレームを表示し、領域内をクリックされたら、画像を表示するということをしてみました。
マウスポインタの位置を左上として、花丸を表示するプログラムです。
ソース
public class MyJFrame extends JFrame {
private final static int WIDTH = 600;
private final static int HEIGHT = 600;
private int x = 0;
private int y = 0;
private BufferedImage image = null;
boolean clicked = false;
public static void main(String[] args) {
new MyJFrame();
}
public MyJFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(WIDTH, HEIGHT);
// リスナー
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
addMouseListener(myMouseAdapter);
// 素材読み込み
try (InputStream inputStream = getClass().getResourceAsStream("hanamaru.png");) {
image = ImageIO.read(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
// 表示
setVisible(true);
}
public void paint(Graphics g) {
// 画面を塗りつぶす
g.setColor(Color.white);
g.fillRect(0, 0, WIDTH, HEIGHT);
if (clicked) {
// 花丸を描画
g.drawImage(image, x, y, this);
// クリックした点を描画
g.setColor(Color.black);
g.drawRect(x, y, 1, 1);
}
}
private class MyMouseAdapter extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent e) {
// クリック時の処理
x = e.getX();
y = e.getY();
// フラグ設定
clicked = true;
repaint();
}
}
}
細かい動作は以下の通りです。
-
マウスがクリックされた場合、以下を実行する。
- マウスポインタの位置を左上にして、画像を表示
- マウスポインタの位置を左上にして、〇を表示
- そうでない場合、何もしない
画像を読み込む方法
画像を読み込む方法は色々あるようなのですが、今回はクラスファイルと同じフォルダに配置された画像を読み取るということをしました。「getResourceAsStream」の箇所です。getResourceAsStream()メソッドはClassに定義されています。引数はStringです。ファイル名を指定すればよいようです。メソッドのリターンはInputStreamクラスです。
getResourceAsStream()メソッドを使う箇所では、try-catch-resource構文を使っています。取得したInputStreamクラスのインスタンはクローズ処理が必要だからです。
javaのバージョンが古い場合は以下のように記述すればよいでしょう。
ソース
InputStream inputStream = getClass().getResourceAsStream("hanamaru.png");
try {
image = ImageIO.read(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
InputStreamのcloseメソッドはIOExceptionをスローしますなので、close()メソッドの箇所もtry-catch構文を使う必要があります。Java SE 7以降ではtry-catch-resource構文を使うことでソースを簡略化できます。
ImageIOクラスにread()メソッドがあります。このメソッドでBufferedImageを取得することができます。
マウスクリック時の処理
マウスがクリックされたときに何か処理をしたい場合は、addMouseListener()メソッドを使う必要があります。このメソッドはComponentクラスで定義されています。引数はMouseListenerインターフェースです。実際にはそのの実装クラスのインスタンスを指定します。今回はその実装クラスであるMouseAdapterを拡張したクラスMyMouseAdapterを定義して、そのインスタンスを引数に指定しています。
マウスがクリックされたとき、MyMouseAdapterクラスのmouseClicked()メソッドが実行されます。今回はx,y座標を取得して、フィールドに保存しています。また、フラグをtrueに変更しています。このフラグの初期値はfalseに設定しています。実際の描画メソッドがフレーム側で定義されいて、フレーム初期表示のときに、画像を描画しないためのフラグです。
描画処理
描画はMyJFrameのpaint()メソッドで行います。このメソッドはContainerクラスで定義されています。repaint()メソッドを呼び出すことで、paint()メソッドが呼び出されます。そして、このメソッドの仮引数Graphicsのメソッドを呼び出すことで描画することができます。
図形を描画するにはdrawImage()メソッドを使います。いくつか用意されてますが、今回使ったのは引数が以下のものです。
- 第1引数Image img
- 描画する画像。今回は読み込んだ画像を指定。
- 第2、第3引数int x, int y
- 描画する領域左上のx座標とy座標。今回はマウスポインタの位置を指定。
- 第4引数 ImageObserver observer
- これはよくわかりませんでした。基本的にthisを指定すればよいらしいです。
これで、画像が描画できます。x座標y座標がマウスポインタの位置なので、そこを左上にして、画像が表示されます。今回はdrawRectでクリックされたポイントも描画してみました。
もしマウスポインタの位置を画像の中心にしたい場合、次のように記述すればよいでしょう。
ソース
int cx = x - image.getWidth() / 2;
int cy = y - image.getHeight() / 2;
g.drawImage(image, cx, cy, this);
画像の高さと長さの半分ずらすということをしています。