Javaで自作のボタンを作る

メディア技術基礎最終課題の参考にしていただきたいと思い…

まずは、簡単な自作ボタンの作成例です。JPanelを拡張し、MouseListenerを実装することで作ることにします。
JavaSwingには、すでにJButtonという部品が用意されていますが、自分の作りたいモノのイメージに合ったボタンを自作した cheap bounce house for saleいと思う人も多いのではないでしょうか。ボタンを自作したところで機能的にはなんら変わりはなく、そのため本質的な部分ではないのかもしれませんが…。

ソースコードは以下の2つです。

[java]
/************************************************************************************
* MainFrame.java
* JFrameの設定をして、自作したOriginalIconクラスをその上に配置する。
* JFrameに配置する際、直接レイアウトするとうまくいかないため、土台となるJPanelを用意しその上に配置。
* 詳しくは、http://www.javadrive.jp/tutorial/jpanel/index5.html
************************************************************************************/

import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainFrame {

private JFrame frame;

MainFrame(){

//JFrameのインスタンス作成
frame = new JFrame(“OriginalIcon”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200, 200);

//お決まりのウインドウ設定
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter(){
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});

//自作したOriginalIconクラスをインスタンス化
OriginalIcon iconImg = new OriginalIcon();
//OriginalIconのインスタンスをのせるJPanelを用意する
JPanel base = new JPanel();
base.add(iconImg);
frame.getContentPane().add(base, BorderLayout.SOUTH);
frame.setVisible(true);

}

public static void main(String[] args){
MainFrame frame = new MainFrame();
}

}    end of MainFrame
[/java]

[java]
/************************************************************************************
* OriginalIcon.java
* JPanelを拡張し、MouseListenerを実装する。
* 用意した2枚の画像を読み込み、マウスに反応させる。
************************************************************************************/

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class OriginalIcon extends JPanel implements MouseListener{

private BufferedImage icon1;
private BufferedImage icon2;
private boolean mouse_enter;

public OriginalIcon() {
this.setPreferredSize(new Dimension(75, 75));
this.addMouseListener(this);
mouse_enter = false;

////////////////////////////////////////////////////////////////////////
// 画像読み込み関連処理
////////////////////////////////////////////////////////////////////////
File imgfile1 = new File(“img/naka-lab_a.gif”);
File imgfile2 = new File(“img/naka-lab_b.gif”);
try {
icon1 = ImageIO.read(imgfile1);
icon2 = ImageIO.read(imgfile2);
} catch (IOException e) { e.printStackTrace(); }

}

////////////////////////////////////////////////////////////////////////
// paintメソッドをオーバーライド
////////////////////////////////////////////////////////////////////////
public void paint(Graphics g) {
g.clearRect(0, 0, this.getWidth(), this.getHeight());
g.drawImage(icon1, 0, 0, this);
if(mouse_enter == true)    g.drawImage(icon2, 0, 0, this);
g.dispose();
}

////////////////////////////////////////////////////////////////////////
// マウスリスナー関連
////////////////////////////////////////////////////////////////////////
public void mouseClicked(MouseEvent e) {
System.out.println(“Click!”);
}
public void mouseEntered(MouseEvent e) {
mouse_enter = true;
System.out.println(“Enter!”);
System.out.println(“mouse_enter: ” + mouse_enter);
repaint();
}
public void mouseExited(MouseEvent e) {
mouse_enter = false;
System.out.println(“Exit!”);
System.out.println(“mouse_enter: ” + mouse_enter);
repaint();
}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}

}    end of OriginalIcon
[/java]

eclispeの画像、実行画面を2つ

次は、簡単な画像ビューワーの例です。Flickrの画像を使いますが、URLを決め打ちしています。アイコン部分と画像表示部分の関係性がその方が分かりやすいと思うからです。ですが、この方法(URL決め打ち)では最終課題で良い評価はいただけないでしょう。
ソースコードは以下の3つです。

[java]
/************************************************************************************
* SimplePhotoViewerMain.java
* JFrameの設定をして、自作したIconPanelクラスとPhotoPanelクラスをその上に配置する。
* PhotoPanelクラスは特殊な方法でインスタンスを生成(シングルトンパターン)する。
* JFrameに配置する際、直接レイアウトするとうまくいかないため、土台となるJPanelを用意しその上に配置。
* 詳しくは→http://www.javadrive.jp/tutorial/jpanel/index5.html
* Flickrの画像はURLを決め打ちでIconPanelインスタンスに渡す( ※※※ 最終課題ではこの方法は不可! ※※※ )。
************************************************************************************/

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class SimplePhotoViewerMain {

private JFrame frame;

SimplePhotoViewerMain(){

//JFrameのインスタンス作成
frame = new JFrame(“SimplePhotoViewer”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(640, 480);

//お決まりのウインドウ設定
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter(){
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});

//自分で定義したメソッドを呼ぶ
this.setIconImage();
//PhotoPanelクラスのインスタンスを配置
frame.getContentPane().add(PhotoPanel.getInstance(), BorderLayout.CENTER);    //※シングルトンパターン
frame.setVisible(true);

}

////////////////////////////////////////////////////////////////////////
// 自作したIconPanelクラスのインスタンスを8コ作り、画面下部に配置。
// 個々のインスタンスにはIconPanelクラスで定義してあるsetURLメソッド用い、
// 画像のURL(Flickr)を渡す。
// レイアウトはGridLayoutで設定
//(参考:http://www.javadrive.jp/tutorial/gridlayout/index.html)
////////////////////////////////////////////////////////////////////////
private void setIconImage() {
IconPanel[] iconImg = new IconPanel[8];
JPanel bar = new JPanel();
JPanel barComp = new JPanel();
bar.setLayout(new GridLayout(1, 8, 3, 0));
for(int i = 0; i  < iconImg.length; i++) {
iconImg[i] = new IconPanel();
bar.add(iconImg[i]);
}
barComp.add(bar);
iconImg[0].setURL(“http://farm4.static.flickr.com/3502/3728985417_b60ec4c584”);
iconImg[1].setURL(“http://farm3.static.flickr.com/2626/3729767622_6d5f06d694”);
iconImg[2].setURL(“http://farm4.static.flickr.com/3246/3731935380_2fef26490b”);
iconImg[3].setURL(“http://farm3.static.flickr.com/2548/3730278390_e789b31cfe”);
iconImg[4].setURL(“http://farm3.static.flickr.com/2482/3730292862_fafea11f70”);
iconImg[5].setURL(“http://farm3.static.flickr.com/2629/3728938115_c1315e5c86”);
iconImg[6].setURL(“http://farm3.static.flickr.com/2430/3728941305_ef2be9ae69”);
iconImg[7].setURL(“http://farm3.static.flickr.com/2602/3728939335_4601509898”);
frame.getContentPane().add(barComp, BorderLayout.SOUTH);
}

public static void main(String[] args){
SimplePhotoViewerMain frame = new SimplePhotoViewerMain();
}

}    end of SimplePhotoViewerMain
[/java]

[java]
/************************************************************************************
* IconPanel.java
* JPanelを拡張し、MouseListenerを実装する。
* マウスカーソルによって、画像の色を変える。
* またクリックされたらPhotoPanelインスタンスに画像のURL(文字列)を渡す。
************************************************************************************/

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageProducer;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.GrayFilter;
import javax.swing.JPanel;

public class IconPanel extends JPanel implements MouseListener{

private BufferedImage img;
private String imgURL;
private boolean color;

public IconPanel() {
this.setPreferredSize(new Dimension(75, 75));
this.addMouseListener(this);
color = false;
}

////////////////////////////////////////////////////////////////////////
// paintメソッドをオーバーライド
////////////////////////////////////////////////////////////////////////
public void paint(Graphics g) {
//画像のグレイスケール化処理
GrayFilter grayFilter = new GrayFilter(true, 15);
ImageProducer ipG = new FilteredImageSource(img.getSource(), grayFilter);
Image grayImg = createImage(ipG);
g.drawImage(grayImg, 0, 0, this);
//このクラスのインスタンス(画像)の上にマウスカーソルが入ったら、カラー画像を表示
if(color == true)    g.drawImage(img, 0, 0, this);
g.dispose();
}

////////////////////////////////////////////////////////////////////////
// Mainクラスから画像のURL(文字列)を引数として受け取り、その文字列に”_s.jpg”を
// 追加した上でURLとして読み込み、画像をとってくる。
////////////////////////////////////////////////////////////////////////
public void setURL(String str) {
imgURL = str;
URL url = null;
try {
url = new URL(imgURL + “_s.jpg”);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
img = ImageIO.read(url);
} catch (IOException e) { e.printStackTrace(); }
}

////////////////////////////////////////////////////////////////////////
// マウスリスナー関連
////////////////////////////////////////////////////////////////////////
public void mouseClicked(MouseEvent e) {
System.out.println(“Click!”);
PhotoPanel.getInstance().setImage(imgURL);        //※シングルトンパターン
}
public void mouseEntered(MouseEvent e) {
color = true;
}
public void mouseExited(MouseEvent e) {
color = false;
}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}

}    end of IconPanel
[/java]

[java]
/************************************************************************************
* PhotoPanel.java
* JPanelを拡張。
* シングルトンパターンにならい、自身のインスタンスをprivate/staticで宣言し、
* 他のクラスからはgetInstance()メソッドによって、インスタンスを取得させるようにする。
* IconPanelから画像のURL(文字列)を受け取り、画像を読み込み表示する。
************************************************************************************/

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class PhotoPanel extends JPanel{

//自身のインスタンスをprivate/staticで生成。
private static PhotoPanel instance = new PhotoPanel();

private URL url;
private BufferedImage img;

private PhotoPanel(){
url = null;
}

////////////////////////////////////////////////////////////////////////
// paintメソッドをオーバーライド
////////////////////////////////////////////////////////////////////////
public void paint(Graphics g) {
g.clearRect(0, 0, this.getWidth(), this.getHeight());
if( url != null) {
g.drawImage(img, this.getWidth()/2 – img.getWidth()/2, this.getHeight()/2 – img.getHeight()/2, this);
}
g.dispose();
}

////////////////////////////////////////////////////////////////////////
// IconPanelクラスから画像のURL(文字列)を引数として受け取り、その文字列に”_m.jpg”を
// 追加した上でURLとして読み込み、画像をとってくる。
////////////////////////////////////////////////////////////////////////
public void setImage(String str) {
try {
url = new URL(str + “_m.jpg”);
} catch (MalformedURLException e) { e.printStackTrace(); }
try {
img = ImageIO.read(url);
} catch (IOException e) { e.printStackTrace(); }
this.repaint();
}

//このクラスのインスタンスはメソッドで生成させるようにする。
public static PhotoPanel getInstance() {
return instance;
}

}    end of PhotoPanel
[/java]
IconPanelクラスは基本的に自作ボタンのOriginalIconクラスと同じです。
(ということは、OriginalIconクラスを継承してIconPanelクラスを作った方が良かったかも…。)
主な変更点は、
・画像の場所がローカルでなくなったことに対する対処、
・画像を表示するPhotoPanelクラスとの連携、
・マウスカーソルによるアイコンの画像変化を2枚ではなく1枚の画像に画像処理フィルターを用いることで表現するようにした
です。
はじめに簡単なソースコードを記述してから、目的の機能を付け加えていくとプログラミングの見通しが良くなるかもしれません。

カテゴリー: diary, programming パーマリンク

コメントを残す