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 | コメントする

rubyで体育を予約したい

中西研の北原です。前々回は、rubyで体育の予約状況を取得しました。予約状況が取得できるようになると今度は体育の予約を自動で取ってほしくなります。ではやってみましょう。 続きを読む

カテゴリー: diary | コメントする

ニーチェの言う三段の変化とクリエイティブシンキング

中西研の関口です。中西研では、日々、クリエイティブシンキングのために様々なトピックについて議論をしています。

今日は、その中でニーチェの三段の変化とクリエイティブシンキングを、クリエイティブシンキングによって頑張って結びつけて見たいと思います。ニーチェに関する考察は、間違ってる所が多数あるかもしれないのですが、その点はご勘弁を…。

三段の変化とは、ニーチェが『ツァラストラはかく語りき』の中で語っている話で、簡単に言うと「精神が駱駝となり、駱駝から獅子となり、獅子から幼子になること」を言います。

続きを読む

カテゴリー: diary | ニーチェの言う三段の変化とクリエイティブシンキング はコメントを受け付けていません

rubyによるマルコフ連鎖とvimのデバッグ操作

中西研の北原です。前回はrubyのライブラリであるnokogiri, mechanize, ruby-growlを使いました。今回はnokogiriを使いさらに形態素解析エンジンであるMeCabを利用して簡単なマルコフ連鎖による文章の再構築を行ってみることにします。また僕はvimを使っているのでそのあたりにも触れる予定です。
続きを読む

カテゴリー: diary, programming | コメントする

RubyとTwitter

大森です。さんざん出ている小ネタです。

rubyを使ってTwitterコメントを送るというものです。
どうやら ruby twitter gem を使えば簡単にできそうです。

インストールも
$ sudo gem install twitter
で簡単です。

ソースはこんな感じです

require 'rubygems'
gem 'twitter'
require 'twitter'

message = "hoge"
httpauth = Twitter::HTTPAuth.new('username', 'Passward')
base = Twitter::Base.new(httpauth)
base.update(message)

こうなりました

Flexとあわせてイタズラすることを考えています。しかしSFCサーバとrubyは相性悪い…
また報告します

カテゴリー: diary, programming | タグ: | コメントする

人間の五感と可変抵抗

中西研の関口です。小ネタです。

可変抵抗(ボリューム/スライダ)などには一般的にA・B・Cという3つの特性があります。(Dもあるらしいのですが、未だに見たことがありません。)

一般的に良く使われるのがBカーブで、例えば、ボリュームやスライダの変化量に比例した抵抗値になります。それに対して、AカーブとCカーブは、対数的、逆対数的な抵抗の変化をします。

これは、人間の感覚(明るさだったり、音の大きさだったり)は、感じ方が対数的になってるらしく(そういえば、デジベルだったり、星の等級なんかは対数的に変わる単位ですね。)、例えば、ボリュームを回すと音量が変わるような仕組みを作るとき、BカーブよりAカーブの可変抵抗を使った方が人間の聴覚的には直線的に変化しているように感じるようになります。

ということで、人間の感じ方を変化させるような時は、A特性の可変抵抗を使おうという話でした。

カテゴリー: diary | コメントする

体育状況をrubyで取得する

中西研の北原です。SFCでは体育を30回もとらないと卒業出来ません。しかし体育は予約制なので運がわるいと抽選から漏れてしまいます。しかし、予約を解除する人は毎回でるので、うまく予約したいものです。そこで前々から興味があったrubyで作られているパーサのnokogiriを使ってgrowlに体育の状況を通知させてみました。
続きを読む

カテゴリー: diary, programming | コメントする

『人を動かす』を読んだ

D.カーネギ著『人を動かす』を読みました。

その感想を書きます。
続きを読む

カテゴリー: diary | タグ: , , , | コメントする

Pervasive 2009 に参加しました

中西研の関口です。

5月11日から5月14日まで奈良で開催されましたPervasive2009に中西先生と関口がCityCompilerデモ発表の為に参加してきました。

多くの反応を得ることができたので、今後の研究に役立てたいと思います。

カテゴリー: news | タグ: | コメントする

eclipseのinstall

北原です。今回は授業でeclipseを使うのでインストール方法について書きたいと思います。

http://www.eclipse.org/downloads/index.php

ダウンロードページは上記です。幾つか種類がありますが、Eclipse IDE for Java Developersを選んでダウンロードして下さい。
macの場合はダウンロードをしたものを解凍しアプリケーションフォルダにいれれば大丈夫です。

30A230D5309A30EA30B130FC30B730E730F3
Uploaded with plasq‘s Skitch!

次にwindowsの方の場合です。windowsの場合はこちらのサイトを参考にするとよいようです。

http://www.site-cooler.com/java/eclipse/

カテゴリー: diary, programming | コメントする