2011年6月アーカイブ

2011年6月19日

メディア技術基礎(ネットワーク・画像処理) 第1回課題


メディア技術基礎(ネットワーク・画像処理)の第1回課題について、こちらに提出させていただきます。

▼目次

  1. プログラム一覧
  2. プログラムの解説
  3. 実行画面
  4. クラス・インスタンス、イベントとイベントリスナーの概念解説
  5. おわりに

プログラム一覧

※PDFデータでも見ることが出来ます。
////////////////////////////////////////////////////////////////////////////////////////////////
//
//		▽インポートデータ
//
////////////////////////////////////////////////////////////////////////////////////////////////
import java.awt.*;
import java.awt.event.*;// ActionListenerのインポート
import javax.swing.*;//JFrameのインポート
import javax.swing.event.*;//HyperlinkListenerのインポート
import javax.swing.JButton;//JButtonのインポート
////////////////////////////////////////////////////////////////////////////////////////////////
//
//		▽HTMLViewerクラス
//
////////////////////////////////////////////////////////////////////////////////////////////////
public class HTMLViewer implements ActionListener, HyperlinkListener{
	
	JTextField addrField;//URLを入力してもらう部品
	JEditorPane htmlPane;//HTMLを表示してもらう部品
	JButton homeButton;//ホームボタン部品
	JButton sfcButton;//SFCボタン部品
	
	public HTMLViewer(){
		//部品としてのウィンドウを作成:newする JFrameという部品のコンストラクタを呼び出す。
		JFrame frame = new JFrame("Simple HTML Viewer");//JFrameのオブジェクトを作成する
			frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			frame.addWindowListener(
					new WindowAdapter() {
						public void windowClosed(WindowEvent e){
							System.exit(0);
						}
					}
			);
		////////////////////////////////////////////////////////////////////////////////////////
		//
		//		▽URL入力フォームについて
		//
		////////////////////////////////////////////////////////////////////////////////////////
			
		addrField = new JTextField("http://");//テキストフィールドオブジェクトの作成。
			addrField.addActionListener(this);
			
		////////////////////////////////////////////////////////////////////////////////////////
		//
		//		▽Webページ表示画面について
		//	
		////////////////////////////////////////////////////////////////////////////////////////
			
		htmlPane = new JEditorPane();//JEditorPaneオブジェクトの作成
			htmlPane.setEditable(false);
			htmlPane.setContentType("text/html");
			htmlPane.addHyperlinkListener(this);//クリックされたら知らせるよう設定
		
		////////////////////////////////////////////////////////////////////////////////////////
		//
		//		▽ホームボタンとSFCボタンの作成と、ボタンを押した時に呼び出す仕事の設定
		//	
		////////////////////////////////////////////////////////////////////////////////////////
			
		homeButton = new JButton("HOME");//JButtonオブジェクトの作成
			homeButton.addActionListener(new HomeActionListener());
		sfcButton = new JButton("SFC");//JButtonオブジェクトの作成
			sfcButton.addActionListener(new sfcActionListener());
		
		////////////////////////////////////////////////////////////////////////////////////////
		//
		//		▽オブジェクトの描画、レイアウトなどについて
		//	
		////////////////////////////////////////////////////////////////////////////////////////
			
		
		JPanel topContainer = new JPanel();
			topContainer.setLayout(new GridLayout(1,2));
			topContainer.add(homeButton);
			topContainer.add(sfcButton);
		
		JPanel bottomContainer = new JPanel();
			bottomContainer.setLayout(new BorderLayout());
			bottomContainer.add(addrField, BorderLayout.NORTH);
			bottomContainer.add(new JScrollPane(htmlPane), BorderLayout.CENTER);
		
		frame.getContentPane().add(topContainer, BorderLayout.NORTH );
		frame.getContentPane().add(bottomContainer, BorderLayout.CENTER );
		
		frame.setSize(640,480);
		frame.setVisible(true);//ウィンドウが見えるようにセットする
	}
	
	////////////////////////////////////////////////////////////////////////////////////////
	//
	//		▽URLを入力し、エンターキーが押されたら実行する仕事について
	//	
	////////////////////////////////////////////////////////////////////////////////////////
	
	public void actionPerformed(ActionEvent e){
		String url = addrField.getText();
		System.out.println(url);
		try{
			htmlPane.setPage(url);
		}catch(Exception err){
			System.out.println("無効なURLを指定していませんか?");
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////
	//
	//		▽ホームボタン、SFCボタンそれぞれが押されたら実行される仕事について
	//	
	////////////////////////////////////////////////////////////////////////////////////////
	
	public class HomeActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
        	String url = "http://yahoo.co.jp/";
        	System.out.println(url);
        	try{
    			htmlPane.setPage(url);
    		}catch(Exception err){
    			System.out.println("ページジャンプに失敗しました。");
    		}
        }
    }

	public class sfcActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
        	String url = "http://www.sfc.keio.ac.jp/";
        	System.out.println(url);
        	try{
    			htmlPane.setPage(url);
    		}catch(Exception err){
    			System.out.println("ページジャンプに失敗しました。");
    		}
        }
    }

	////////////////////////////////////////////////////////////////////////////////////////
	//
	//		▽Webページ内のリンクについて
	//	
	////////////////////////////////////////////////////////////////////////////////////////
	
	public void hyperlinkUpdate(HyperlinkEvent e){
		if(e.getEventType() != HyperlinkEvent.EventType.ACTIVATED){
			return;
		}
			String url = e.getURL().toString();//どのリンクがクリックされたかを取得
			addrField.setText(url);//取得した文字列をurl変数に格納する
			try{
				htmlPane.setPage(url);
			}catch(Exception err){
				
			}
		
	}
	
	////////////////////////////////////////////////////////////////////////////////////////
	//
	//		▽プログラムの実行処理
	//	
	////////////////////////////////////////////////////////////////////////////////////////
	
	public static void main(String[] args){//全てのプログラムが始まる所ところ
		HTMLViewer my_viewer = new HTMLViewer();//自分で設計した部品を1つ生成:newする
	}
}

プログラムの解説

▽ホームボタンとSFCボタンの作成
まず、ソース上部でJButtonクラスをインポートします。
import javax.swing.JButton;
そして、HTMLViewerクラスのはじめに、新たにつくるホームボタンと、SFCボタンの宣言を行います。
public class HTMLViewer implements ActionListener, HyperlinkListener{
        JButton homeButton;//ホームボタン部品
        JButton sfcButton;//SFCボタン部品
宣言を行ったら、JButtonをnewして、二つのボタンを作成します。
青字の部分に、文字列を指定することで、その文字列をボタンに描画することができます。
homeButton = new JButton("HOME");//JButtonオブジェクトの作成
sfcButton = new JButton("SFC");//JButtonオブジェクトの作成

▽ボタンをクリックしたときのイベントの設定
ボタンを押したら、指定したURLにアクセスしてページが表示されるように設定をします。
先ほど設定したhomeButton,sfcButtonに、addActionListenerメソッド追加し、ボタンがActionEventを受け取ることができるようにします。
homeButton.addActionListener(new HomeActionListener());
sfcButton.addActionListener(new sfcActionListener());
これで、ホームボタンを押した時には、HomeActionListener()を、SFCボタンを押した時には、sfcActionListener()を呼び出すことが出来るようになったので、呼び出すクラスをそれぞれ定義しておきます。
public class HomeActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
        	String url = "http://yahoo.co.jp/";
        	System.out.println(url);
        	try{
    			htmlPane.setPage(url);
    		}catch(Exception err){
    			System.out.println("ページジャンプに失敗しました。");
    		}
        }
}
同様に、SFCボタンには、urlをSFCのホームページのURLを渡して表示させるようにしました。

▽オブジェクトの描画、レイアウトなどについて
次に、ボタンの描画、レイアウトについてのプログラムについて解説します。
JPanelオブジェクトを2つ作成し、
1つはボタンをグリッドレイアウトで横並びに2つ配置するコンテナ、
もう1つは、URL入力フォームとページを描画するフレームを配置するコンテナです。
配置の概念図(これで伝わるかは微妙ですが。。。)は以下のようになります。

lauout.jpg
JPanel topContainer = new JPanel();
	topContainer.setLayout(new GridLayout(1,2));
	topContainer.add(homeButton);
	topContainer.add(sfcButton);
		
JPanel bottomContainer = new JPanel();
	bottomContainer.setLayout(new BorderLayout());
	bottomContainer.add(addrField, BorderLayout.NORTH);
	bottomContainer.add(new JScrollPane(htmlPane), BorderLayout.CENTER);
topContainerではGridLayoutを用いました。1行2列のレイアウトで、2つのボタンを配置しました。
bottomContainerではBorderLayoutを用いました。NORTHにURL入力フォームを、CENTERにページ表示フレームを配置しました。

最後に、topContainerと、bottomContainerをContentPaneオブジェクトに配置します。
frame.getContentPane().add(topContainer, BorderLayout.NORTH );
frame.getContentPane().add(bottomContainer, BorderLayout.CENTER );
これで、ボタン、URL入力フォーム、ページ表示画面の描画、レイアウトを設定しました。

実行画面

スクリーンショット(2011-06-19 17.18.48).png
▲初期実行画面
スクリーンショット(2011-06-19 17.20.53).png
▲ホームボタン実行画面
スクリーンショット(2011-06-19 17.20.57).png
▲SFCボタン実行画面
スクリーンショット(2011-06-19 17.21.08).png
▲URL入力&エンターキー実行画面

クラス・インスタンス、イベントとイベントリスナーの概念解説

▼クラス・インスタンスの概念解説
クラスは、部品の設計図、インスタンスは、その設計図を基に作られた実際の部品を指します。インスタンスを作成する際には、引数を設定することが出来、それによって同じクラスから作成したインスタンスでも、中身のデータを異なるものにすることができます。
※本プログラムでは、ボタンを押された際の実行イベントについてクラスをボタンの数だけ作成しました。しかし、これを一つにして、インスタンス生成時に引数を渡すことで異なるURLを指定することが出来たと思います。

▼イベントとイベントリスナーの概念解説
イベントは、
  • ボタンが押された
  • エンターキーが押された
  • 文字列が入力された
  • etc...
何かが起きることを言います。

イベントリスナーは、あるイベントが起こった時にその内容を受け取るオブジェクトです。
※まだ、マウスイベントやテキストイベントについては、どのように動作するのかイメージがつかめていません。

おわりに

特に骨が折れたのは、作成したオブジェクトをどのように描画、レイアウトをするかでした。
JPanelオブジェクトを使うことになったのですが、JPanelとcontentPaneの概念を理解するのにまず苦戦しました。borderLayoutだけで、描画しようとするとどうしてもレイアウトが微妙なものになってしまうので、JPanelを使いました。borderLayout以外にもgridLayoutを用いたり組み合わせることで、なんとか自分の中で納得のいく描画、レイアウトを実現できました。
イベント部分の実装については、これがベストのプログラムだとは思っていません。クラスに引数をうまく渡すことでもっとシンプルにボタンを押した際のイベントを実装できたと思います。

2011年6月12日

PHPを用いた入力データのエラーチェック処理


お問い合わせページなどで、再三行ってきた入力されたデータに対するエラー処理についてメモします。
先日AJAXを勉強したこともあって、現在は、非同期通信でのお問い合わせフォームをそそくさと作っている所です。
phpでのエラーチェックについてこれまで自分が用いてきたものとは違う方法を、書籍で見つけたのでまとめていきたいと思います。

エラー内容はまとめて配列変数に格納する

ここでは、$error_listという変数を用います。
複数の項目のエラーをまとめて返せるように、以下のように、配列変数をはじめにセットし、初期化します。
$error_list = array();
各項目でエラーがあった場合は、その判定ごとにスクリプトを生成し、この配列に入れていくこととします。

submitボタン後の処理

submitボタンが押されたことを確認したら、実行するスクリプトは以下のようになります。
if (isset($_POST["submit"])){
    $_SESSION["name"] = isset($_POST["name"]) ? $_POST["name"] : " ";
    $_SESSION["age"] = isset($_POST["age"]) ? $_POST["age"] : " ";
    $_SESSION["comment"] = isset($_POST["comment"]) ? $_POST["comment"] : " ";

    //他で定義したerror_check()関数を実行する。
    //引数は、上記の$_SESSION配列変数
    $error_list = error_check($_SESSION);
}

error_check()関数

上記で登場したerror_check()関数は、実際には別のphpファイルに書いて、require_onceで読み込みます。
function error_check($check_data){
    $error_list = array();
    
    if (isset($check_data["name"]) && trim($check_data["name"]) === ""){
        $error_list[] = "名前を入力してください。";
    }elseif (mb_strlen($check_data["name"]) > 100){
        $error_list[] = "名前は100文字以内で入力してください。";
    }
    return $error_list;
}
入力された名前のエラーの有無を調べる上のスクリプトでは、若干複雑な条件分岐を作っています。
まずisset関数を用いて、$check_data["name"]変数があるかを調べ
かつtrim関数を用いた空白文字の削除後に、名前が空っぽになっていないかを調べています。
さらに、mb_strlen関数で、きちんとマルチバイト文字の文字数をカウントして、許容量以上の文字数でないかを調べています。

はじめにisset関数を変数の存在を確認するのは、定義されていない変数を判定に掛けるとNOTICEエラーが生じてしまうからだそうです。(いまいち理解できていない・・・汗)

Smartyスクリプト使用上の注意点


Smartyのスクリプトを格納するサーバー上のフォルダは、Smartyのデフォルトの設定では、危険とのことです。スクリプトが漏洩してしまいます。
アクセスされては困るフォルダは、サーバのドキュメントルートより上の階層に置くことにします。
ここでは、「templates」と「templates_c」フォルダをドキュメントルートより上の階層に置くこととします。

Smartyクラスを継承した独自のクラスを作成して、上記のタスクを達成します。
<?php
	//ROOT_DIRの定義。サーバのドキュメントルートとする。
	define("ROOT_DIR", $_SERVER['DOCUMENT_ROOT']."/..");
	//Smartyクラスの呼び出し
	require_once("Smarty.class.php");
	
//Smartyクラスを継承した新しいクラスを定義 class MySmarty extends Smarty{ //コンストラクタの記述 function MySmarty(){ $this -> template_dir = ROOT_DIR . "/templates"; $this -> compile_dir = ROOT_DIR . "/templates_c"; $this -> left_delimiter = "{{"; $this -> right_delimiter = "}}"; $this -> default_modifiers = array('escape'); $this -> Smarty(); } } ?>
▲独自に作成するMySmarty.class.php
これにより、作成するphpスクリプトで
require_once("../../lib/MySmarty.class.php");
〜省略〜
$smarty -> display("hakashun.tpl");
とすれば、自分で作成したテンプレートファイルを呼び出すことが出来る。

include関数、スーパーグローバル変数の呼び出し|Smartyメモ002


    インクルード関数

別ファイルに記述されたテンプレートをインクルードするためのSmaty関数です。
<html>
<head>
    <title>include関数</title>
</head>
<body>
    {include file="読み込みたいテンプレートのパス"}
</body>
</html>
movabletypeを使っているので、ヘッダーはヘッダー、フッターはフッターで管理することがSmartyで実現できます。

PHP側で定義されたスーパーグローバル変数をSmartyで呼び出す

//$_SERVER["HTTP_HOST"]
    {$smarty.server.HTTP_HOST}

//$_GET["key"]
    {$smarty.get.key}

//$_POST["key"]
    {$smarty.post.key}

//$_COOKIE["key"]
    {$smarty.cookie.key}

//$_SESSION["key"]
    {$smarty.session.key}
すごい直感的に書けるね!

if文とforeach文|Smartyメモ001


Smartyでのif文

{if $hakashun == "inStarbucks"}
    スターバックスにいます。
{elseif $hakashun == "inSFC"}
    学校にいます。
{else}
    自宅にいます。
{/if}

Smartyでのforeach文

基本形はこんな感じです。
{foreach from=ループする配列 key=キー値取得変数名 item=要素取得変数名}
    {foreachelse}
{/foreach}

phpと組み合わせる例です。
<?php
require_once("../../lib/Smarty.class.php");

$star[] = "浜松";
$star[] = "鎌倉";
$star[] = "みなとみらい";
$star[] = "渋谷";
$star[] = "原宿";
$star[] = "ザザ";
$smarty = new Smarty();
$smarty -> assign("star", $star);
$smarty -> display("template.tpl");
?>
▲phpコード
<select name="star">
    {foreach from=$star key=num item=star_name}
        <option value="{$num}">{$star_name}</option>
        {foreachelse}
        <option value="">選択できません。</option>
    {/foreach}
</select>

ENT_QUOTES|最近使ったPHPメモ002


シングルクオテーションもちゃんとエスケープするには?

htmlspecialchars を使うときは、第2引数にENT_QUOTESをつけないと、シングルクオテーションをエスケープしてくれない。
htmlspecialchars($str, ENT_QUOTES); 

2011年6月11日

count()関数、rand()関数|最近使ったPHPのメモ001


count()関数

count関数は、配列の数を取得する関数です。
$hakashun[] = "は"
$hakashun[] = "か"
$hakashun[] = "し"
$hakashun[] = "ゅ"
$hakashun[] = "ん"

$hakashunLength = count($hakashun);

echo $hakashunLength;
上記のような場合は、をエコーします。

rand()関数

randというだけあって、randomで値を取得するための関数です。
上記のプログラムに加えて、
$randHakashun = rand(1,$hakashunLength);
echo $randHakashun;
とすると、1から5のどれかをランダムでエコーすることになります。

DOM関連のメモ|Head Rush Ajax003


DOM.png
Web村のツリー牧場という面白い表現で説明されていたDocument Object Model。
DOMってhtmlばかりを書き書きしてると、直感的に理解した気になってしまうのですが、改めてメモしておきます。

DOMツリーへのアクセス

1. 「id」属性でエレメントを特定する
<div id="hakashun">
    <p>Starbucks Coffee</p>
</div><!--/#hakashun-->
例えば、上記のようなhtml(もちろんタグ内です。)がある場合で考えます。
ある特定のid属性がついたエレメントは、
var hakashun = document.getElementById("hakashun");
で取得します。

2. タグ名でエレメントを特定する
<div id="hakashun">
    <p>Starbucks Coffee</p>
</div><!--/#hakashun-->
特定のタグ名のエレメントを取得したい場合は、
var pTag = document.getElementsByTagName("p");
で取得する。

3. <html>タグを取得する
HTMLドキュメントのルートエレメント(<html>)を取得したい場合は、
var htmlElement = document.documentElement;
を用いる。これはあんまり使わなそう(と思うのは未熟だからでしょうか・・・)

4.新しいノードを作成する
<p>Starbucks Coffee</p>
例えば、上記のようなエレメントを作成するときは、
//<p>タグを作る(中身はからっぽ)
var pDiv = document.createElement("p"));
//<p>タグに入るテキストを作る
var starbucks = document.createTextNode("Starbucks Coffee"));
//<p>タグに作成したテキストを入れる
pDiv.appendChild(starbucks);

こうして、色々勉強している訳だが、本当に知らなかったことばかり。
Ageの活動が終わって、体系的にやっと勉強できているんだけど、こうした時間も大事にしなくてはと思います。

最後にDOMツリーの移動について図を貼り付けておきます。
DOM操作はjQueryもあることですし、現実的にこれらを使う機会が多いとは限りませんが、何事も知っているにこしたことはないでしょう。

  DOMtes.png 日々精進ですね!

2011年6月 5日

部屋の大掃除をしました。


blog.png ここ半年、大掛かりな掃除をしてこなかったのですが、家族が我が家にやってきたこともあり部屋の整理をしてみました。
大学生活も今年で最後。4年間住んできた部屋とも来年の春にはお別れします。
交通費と書籍代にほとんどのお金を費やしてきたこともあり、部屋には大量の本が・・・。

これを引っ越しの時に一気に片付けるのは面倒だし、もう読まないであろう本を新たな部屋に持ち込むのも気が進みません。さらには中古本として買い取ってもらうにも車などの移動手段がありませんし、おそらくそれほどの収入は見込めないでしょう・・・

ということで、1年間を通じてもう読むことのないであろう本たちを、知り合いの方に譲れることが出来たらと思い、ブログ上部に譲れる本一覧ボタンを作成しました。

カバーがなかったり、線が引いてある本も中にはありますが、もし読みたい本がある友人の皆様はご連絡ください☆

2011年6月 4日

requestオブジェクトを利用した接続URLの指定|Head Rush Ajax002


ajaxによる接続

function 関数名(){
	createRequest();
	var url = "接続先URL";
	request.open("GET", url, true);
	request.onreadystatechange = 実行したい関数名;
	request.send(null);
}

先日のブログで作成したrequestオブジェクトを呼び出し、接続先URLを[url]という名前の変数に格納します。

request.open("GET", url, true);

「request.open()」は、接続を初期化します。()内には3つの要素が指定されています。

  • "GET" :サーバーへのデータ送信方法を指定します。"POST"が他にもあります。
  • url:Webサーバ上で、実行させたいPHPなどのURLを指定します。
  • true:trueが非同期を、falseが同期通信を指定します。

request.onreadystatechange = 実行したい関数名;

onreadystatechageメソッドで、実行したい関数を指定するときは、関数名の後ろに()をつけません。
onreadystatechageは、リクエストの状態が変更された時にブラウザにそのことを伝え、関数を実行します。

キャッシュ問題を回避するちょっとした小技

IEやOperaでリクエストURLをキャッシュされる際の回避技
function getHakashun(){
    createRequest();
    var url = "リクエストURL";
    url = url + "?dummy" + new Date().getTime();
    request.open("GET", url, true);
    request.onreadystatechange = updatePage;
    request.send(null);
}
こうすることで、urlにダミーの引数として時刻が付与されるので、毎回違ったURLをリクエストすることが出来ます。
初歩的なことですが、こんなやり方もあるようです。

リクエスト処理が問題なく完了したときは、「readyState == 200」

サーバのリクエスト処理が問題なく完了したときは、サーバから、ステータスコード200が返されます。
function updatePage(){
    if(request.readyState == 4){
        if(request.status == 200){
            /*実行する関数*/
        }else{
               alert ("エラーが起きました!");
        }
    }
}
上記のようなコードにすれば、リクエスト処理でエラーが起きているかを警告の有無でしることができる。

2011年6月 2日

requestオブジェクト|Head Rush Ajax001


Ajaxの基礎知識を学ぶべく、Head Rushシリーズを初めて手にしたのですが、面白い!

ただし、若干の改訂等あるようで、書籍に記載されたサンプルコードに間違い!?があるので、後でリソースとして活用もするために、ブログに記していきたいと思います。

サーバへのリクエスト発行時に用いるオブジェクトを作成するための関数

   var request = null;

   function createRequest() {
     try {
       request = new XMLHttpRequest();
     } catch (trymicrosoft) {
       try {
         request = new ActiveXObject("Msxml2.XMLHTTP");
       } catch (othermicrosoft) {
         try {
           request = new ActiveXObject("Microsoft.XMLHTTP");
         } catch (failed) {
           request = null;
         }
       }
     }

     if (request == null)
       alert("Error creating request object!");
   }

クロスブラウザ対応のために、try&catchを繰り返したコードを書籍では紹介していました。最近はもっとシンプルな記述が一般的かもしれません。
OpenID対応しています OpenIDについて

このアーカイブについて

このページには、2011年6月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2011年5月です。

次のアーカイブは2011年7月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。