JCheckBoxの画像(Icon)を変更するには

   2012/12/07

swingは色々と自由度が高いので、コンポーネント自体(の見た目)を
カスタマイズすることができます。

毎度、管理人イガジーです。

「JCheckBoxのチェックアイコンを変更するにはどうすれば良いですか?
もっと大きくしたいのです」というご相談を頂きました。
例として、次のようなチェックボックスを作ってみました。

上段がON, 下段がoffの絵です。
左端はデフォルトのJCheckBoxで、それに比べて大きくカラフル(^^)に
してみました。

JCheckBoxは、new する時に(つまりインスタンスを作る際に)
Iconを与えることができます。
Icon はインタフェースなので implements するクラスを作ります。
すなわち
class クラス名 implements Icon {と書いて、その中に決められたメソッドを実装します。
Iconで決められているメソッドは、getIconHeight() , getIconWidth() ,
paintIcon(Component c, Graphics g, int x, int y) の3つです。
3つ目のpaintIcon()では、引数に Graphics g が与えられるので、
それを使って好きなように描画すればよいわけです。

Graphics というのは、例えるなら「筆」みたいなものです。
筆を渡されて「この筆を使って描きなさい」と言われたとしましょう。
例えば、赤色の「絵の具」をつけて=g.setColor(Color.RED)、
塗りつぶしの四角を描く=g.fillRect(2,2,20,20);
という感じで筆を使いますよね。Graphics も同じです。

Component c は Iconを格納している親元で、例えば
JCheckBox cb=new JCheckBox(new MyIcon());
と、JCheckBoxに格納した場合は、c は JCheckBox になります。

Icon自体は JCheckBox以外にも使えるので、汎用的に
Component になっていますが、JCheckBoxで使うときには
c を JCheckBoxにキャストしてやればOKです。

そういう訳で、使用例を書いておきます。

import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.ImageProducer;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.JCheckBox;
import javax.swing.JFrame;


public class ChangeJCheckBoxIcon extends JFrame {
	private static final long serialVersionUID = 1L;

	JCheckBox cb1,cb2,cb3;
	
	ChangeJCheckBoxIcon(){ // constructor
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLayout(new FlowLayout());
		cb1=new JCheckBox(new myCheckIcon1());
		cb2=new JCheckBox(new myCheckIcon2());
		cb2.setBackground(Color.WHITE);

		URL u1=this.getClass().getResource("check32.jpg");
		URL u2=this.getClass().getResource("noncheck32.jpg");
		Image onIcon=null,offIcon=null;
        try {
            onIcon=this.createImage((ImageProducer) u1.getContent());
            offIcon=this.createImage((ImageProducer) u2.getContent());
        }catch(Exception ex){
            System.out.println("Resource Error!");
        }
		cb3=new JCheckBox(new myCheckIcon(onIcon,offIcon));
		this.add(cb1);
		this.add(cb2);
		this.add(cb3);
		this.setSize(200,100);
		this.setVisible(true);
	}
	public static void main(String[] args) {
		new ChangeJCheckBoxIcon();
	}

	class myCheckIcon1 implements Icon {
		int mysize=32;
		public int getIconWidth() { return mysize; }
		public int getIconHeight() { return mysize; }

		public void paintIcon(Component c, Graphics g, int x, int y) {
			JCheckBox b = (JCheckBox)c;

		    Color bg=c.getBackground();
			Color fg=c.getForeground();
			g.setColor(bg);
			g.fillRect(x, y, mysize, mysize);
			g.setColor(fg);
			g.fillOval(x+2, y+2, mysize-4, mysize-4);
			if (b.isSelected()) g.setColor(Color.YELLOW);
			else g.setColor(Color.GRAY);
			g.fillOval(x+6, y+6, mysize-12, mysize-12);
		}
	}
	class myCheckIcon2 implements Icon {
		int sizew=64;
		int sizeh=32;
		public int getIconWidth() { return sizew; }
		public int getIconHeight() { return sizeh; }

		public void paintIcon(Component c, Graphics g, int x, int y) {
			JCheckBox b = (JCheckBox)c;

		    Color bg=c.getBackground();
			Color fg=c.getForeground();
			String stat;
			g.setFont(new Font(Font.DIALOG,Font.BOLD,12));
			g.setColor(bg);
			g.fillRect(x, y, sizew, sizeh);
			g.setColor(fg);
			g.fillRect(x+4, y+4, 24, 24);
			if (b.isSelected()) {
				stat="ON";
				g.setColor(Color.RED);
			}else {
				stat="off";
				g.setColor(Color.GREEN);
			}
			g.fillRect(x+8,y+8,16,16);
			g.setColor(fg);
			g.drawString(stat, x+36, x+22); // 修正
		}
	}
	class myCheckIcon implements Icon {
		int mysize=32;
		Image on,off;
		myCheckIcon(Image onIcon,Image offIcon){
			on=onIcon;
			off=offIcon;
		}
		public int getIconHeight() { return mysize; }
		public int getIconWidth() { return mysize; }

		public void paintIcon(Component c, Graphics g, int x, int y) {
			JCheckBox b = (JCheckBox)c;

			if (b.isSelected()) g.drawImage(on,x,y,null);
			else g.drawImage(off,x,y,null);
			repaint();
		}
	}
}

3種類の Icon を作ってみました。
JCheckBoxで使うIconは、ONとoffで異なる形状にするのが普通です。
ONかoffかは、isSelected()で判別して、

JCheckBox b = (JCheckBox)c;
if (b.isSelected()) {ONの時の絵}
else {offの時の絵}

という感じで処理します。

myCheckIcon1 と myCheckIcon2 は、描画コマンドを使ってIconを
生成していますが、myCheckIcon は、画像データを持っておいてそれを
描画するようにしています。
使ったのは、次のような画像です。

初心者の方で、プログラミングに関してお悩みのことがあれば、
お気軽にメールしてください。
こちらから→メールフォーム
何でも答えられるわけではありませんが、お役に立てることがあるかも
しれませんよ。(初回の相談は無料です。)

この記事へのコメントはこちら

メールアドレスは公開されませんのでご安心ください。
また、* が付いている欄は必須項目となりますので、必ずご記入をお願いします。

内容に問題なければ、下記の「コメント送信」ボタンを押してください。