java.applet.AudioClip

目的
Javaアプリケーションで、様々な種類のメディアファイルを再生する。

関連クラス

今回のソース
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.FlowLayout;
import java.awt.event.*;
import java.io.File;
import java.net.MalformedURLException;
import javax.swing.*;

class SoundDemo
{
	public static void main(String args[])
	{
		new MainWindow();
	}
}

class MainWindow extends JFrame
{
	AudioClip audio;

	// 再生中を示すフラグ
	boolean is_playing = false;

	// ロードされたことを示すフラグ
	boolean is_loaded  = false;

	// 許容される拡張子
	final String[] ext_list = {"au", "mid", "wav", "aiff", "rmi"};

	public MainWindow()
	{
		super("Sound Test");

		// ルックアンドフィールの変更(Motif)
		try
		{
			UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
		}
		catch(Exception e)
		{
			System.err.println(e);
		}

		// ウインドウリスナの追加
		WindowListener listener = new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				System.exit(0);
			}
		};
		addWindowListener(listener);

		// ファイルを開くボタンの定義
		JButton open_file = new JButton("Open...");

		ActionListener listener_open_file = new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				// 再生中にオープンが出来ないようにする
				if(is_playing)
				{
					ShowErrorMessage("Please stop music.", "Playing!");
					return;
				}

				try
				{
					// ファイルを開くダイアログの表示
					JFileChooser chooser = new JFileChooser();
					if(chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION)
					{
						// サウンドファイルの取得
						File file = chooser.getSelectedFile();	
						if(!CheckFileExt(file.getName()))
						{
							ShowErrorMessage("This file is invalid type", "Invalid File!");
						}
						audio = Applet.newAudioClip(file.toURL());
						is_loaded = true;
					}
				}
				catch(MalformedURLException me)
				{
					System.err.println(me);
				}
			}
		};
		open_file.addActionListener(listener_open_file);

		// プレイボタンの定義
		JButton play = new JButton("Play");
		ActionListener listener_play = new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				if(!is_loaded)
				{
					ShowErrorMessage("Please open media file.", "Not Loaded.");
					return;
				}

				is_playing = true;
				audio.play();
			}
		};
		play.addActionListener(listener_play);

		// ストップボタンの定義
		JButton stop = new JButton("Stop");
		ActionListener listener_stop = new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				is_playing = false;
				audio.stop();
			}
		};
		stop.addActionListener(listener_stop);

		// ボタンの追加
		getContentPane().setLayout(new FlowLayout());
		getContentPane().add(open_file);
		getContentPane().add(play);
		getContentPane().add(stop);

		// フレームの表示
		pack();
		setVisible(true);
	}

	// 拡張子のチェック
	public boolean CheckFileExt(String file_name)
	{
		int index = file_name.lastIndexOf('.');
		String ext = file_name.substring(index + 1, file_name.length());

		for(int i=0;i<ext_list.length;i++)
		{
			if(ext.toLowerCase().compareTo(ext_list[i]) == 0)
			{
				return(true);
			}
		}

		return(false);
	}

	// エラーダイアログ
	public void ShowErrorMessage(String message, String title)
	{
		JOptionPane.showMessageDialog(this, message, title, JOptionPane.INFORMATION_MESSAGE);
	}
}
Source is here. (ZIP Format,1560Byte,Shift-JIS)

コンパイル&実行
javac SoundDemo.java
java SoundDemo

説明
(概略)

基本は、JDK1.2から追加された、Applet.newAudioClipメソッドにあります。
このメソッドを使えば、従来はAppletContextが無ければ、
AudioClipの取得(Applet.getAudioClip)が行えなかったものが、出来るようになります。
後は単純な話で、再生はAudioClip.play()、停止はAudioClip.stop()で可能です。

本当は、再生ボタンを>、停止ボタンを□のようなアイコンにしようと思って、
Swingベースのアプリケーションにしたのですが、
アイコンの大きさと、ボタンの大きさが合わないし、
アイコンも良いのが描けそうに無いので止めました(笑)。

本格的にサウンド関連のアプリケーションを作るなら、
Java Media APIの、Java Sound APIを使うと良いでしょうね。
(私は使い方知りませんし、マニュアルはすべて英語ですが。)

(サンプルプログラムの説明)

許容される拡張子
これは説明も要らないほどですが(笑)、
一応、Sunのドキュメントに書いてあったものを列挙しています。
(参照:jdk1.2/docs/ja/guide/sound.html)
ルックアンドフィールの変更(Motif)
Swingのデフォルトルックアンドフィールは、Metalらしいのですが、
ちょっと飽きてきたので(^-^)、Motifのものに変えてみました。
Java2で使えるルックアンドフィールは、以下のものです。
Metal
javax.swing.plaf.metal.MetalLookAndFeel
CDE/Motif
com.sun.java.swing.plaf.motif.MotifLookAndFeel
Windows(Windowsプラットフォーム以外では使用禁止らしい(笑))
com.sun.java.swing.plaf.windows.WindowsLookAndFeel
再生中にオープンが出来ないようにする
これは、作成中に気づいたのですが、
サウンド再生中に新しくオープンして、再生させると、
なんか重なって聞こえたりするんですね。
で、これはマズいと思って、二重オープンのチェックをするようにしました。
is_playingフラグ。
file.toURL()
JDK1.2から追加された、最高に便利なメソッドです。
ファイル名から、file:///c:/windows/...などという、
ファイルプロトコル準拠(?)のURLを作り出してくれるんです。
なんとも便利な世の中に...ぢゃなくて(笑)。
いちいち、file:/// + ...とかやらなくて済むのは、本当に良いですね。
エラーダイアログ
JOptionPaneクラスのshowMessageDialogをラップしてみました。
ひょっとしたら、一つのメソッドをメソッド化するのは
意味ないって思う人もいるかもしれませんが、
将来どんな変更があるとも限らないので、
(このプログラムに関しては、これが最後だと思うけど...)
一応こうしてメソッド化しておくことで、
仕様変更に強いプログラムとなっています。

建前はそんなところで、本当は、
渡す引数をちょっと減らしたかっただけなんですね(笑)。