2009年6月15日月曜日

Java スレッドの一時停止、再開、終了

スレッドの終了方法


runメソッドを終了すると、そのスレッドは解放されなくなります。
ですのでrunメソッドを停止するフラグ変数を用意して、その変数を変更することによって、runメソッドが終了するようにします。

class MyThread extends Thread {
boolean end = false;

public void run() {
while(!end){
//end変数がfalseの間処理を繰り返す。
}
}
}


スレッドの休止方法


スレッドを一時停止するにはwaitメソッドを使用します。
※wait、notify、notifyAllはsynchronized指定がされたメソッド・ブロックでのみ使用できます。

スレッドの再開方法


一時停止したスレッドを再開するにはnotifyメソッドを使用します。
※wait、notify、notifyAllはsynchronized指定がされたメソッド・ブロックでのみ使用できます。

synchrnonizedメソッド・synchrnonized構文


synchronized 修飾されたメソッド/ブロックは、1つのスレッドからしか実行されません。他のスレッドがアクセスしようとすると先に実行しているスレッドの処理が終了するまで待機します。
つまり、複数のスレッドが同じ変数にアクセスすると不整合が発生する可能性がありますが、synchronized 修飾されたメソッド/ブロックはマルチスレッドによる同時アクセスを行わない為、不整合の発生を防ぐことができます。

synchronized 修飾されたメソッド
メソッドの処理を行っている間、そのメソッドに外部からアクセスできないようにします。


synchronized 構文
ブロック内の処理を行っている間、引数に指定したインスタンスに外部からアクセスできないようにします。
synchronized(ブロックするインスタンス){
//実行する処理
}




以下のサンプルはRunボタンでスレッドを開始し、Waitボタンでスレッドの一時停止/再開、Endボタンでスレッドを終了します。
package multiThreadSample;

import java.awt.Button;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ThreadSample03 extends Frame implements ActionListener{

private static final long serialVersionUID = 1L;

public static void main(String[] args){
new ThreadSample03();
}

Label lbl1;
Button btnRun1;
Button btnWait1;
Button btnEnd1;

MyThread3 t1 = null;

public ThreadSample03(){ 
this.setTitle("ThreadSample01");
this.setSize(300,300);
this.setLayout(new GridLayout(2,1));

lbl1 = new Label();
this.add(lbl1);
Panel p1 = new Panel();
btnRun1 = new Button("Run");
btnRun1.addActionListener(this);
btnWait1 = new Button("Wait");
btnWait1.addActionListener(this);
btnEnd1 = new Button("End");
btnEnd1.addActionListener(this);
p1.add(btnRun1);
p1.add(btnWait1);
p1.add(btnEnd1);
this.add(p1);

this.setVisible(true);
}

public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnRun1){
t1 = new MyThread3(lbl1,500);
t1.start();
}else if (e.getSource() == btnWait1){
t1.setStop();
}else if (e.getSource() == btnEnd1){
t1.stopRun();
}
} 
}

class MyThread3 extends Thread {
boolean end = false; 
boolean stop = false;
Label lbl;
int time;  


public MyThread3(Label lbl, int time){
this.lbl = lbl;
this.time = time;   
}

public void run() {
int i = 0;
while(!end){
lbl.setText("Count:" + i);
i++;
try {
Thread.sleep(time);
synchronized(this){
if (stop) wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public void stopRun(){
stop = true;
}

public synchronized void setStop() {
stop = !stop;
if (!stop) {
notify();
}

}


}

2009年6月14日日曜日

Java マルチスレッド

スレッドとはプログラムの処理単位のことです
マルチスレッドとは同時に複数の処理を並行して行うことを言います。
マルチスレッドを実現するにはjava.lang.Threadクラスを継承する方法と、java.lang.Runnableインターフェースを実装する方法があります。


java.lang.Threadクラスを継承する方法


Threadを継承するクラスはrunメソッドをオーバーライドします。
package multiThreadSample;

import java.awt.Button;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ThreadSample01 extends Frame implements ActionListener{

private static final long serialVersionUID = 1L;

public static void main(String[] args){
new ThreadSample01();
}

Label lbl1;
Label lbl2;
Button btnRun;

public ThreadSample01(){
this.setTitle("ThreadSample01");
this.setSize(300,300);
this.setLayout(new GridLayout(4,1));

lbl1 = new Label();
this.add(lbl1);
lbl2 = new Label();
this.add(lbl2);

Panel p1 = new Panel();

btnRun = new Button("Run");
btnRun.addActionListener(this);
p1.add(btnRun);

this.add(p1);

this.setVisible(true);
}

public void actionPerformed(ActionEvent arg0) {
MyThread t1 = new MyThread(lbl1,500);
t1.start();

MyThread t2 = new MyThread(lbl2,1000);
t2.start();

}
}


class MyThread extends Thread{
Label lbl;
int time;

public MyThread(Label lbl, int time){
this.lbl = lbl;
this.time = time;
}

public void run() {
for (int i = 0; i < 100; i++){
lbl.setText("Count:" + i);
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}


}

java.lang.Runnableインターフェースを実装する方法

Runnableインターフェースをを実装するクラスもrunメソッドをオーバーライドします。
class MyClass implements Runnable {
public void run(){
//マルチスレッドで実行する処理を記述します。
}
}
ThreadクラスのインスタンスするコンストラクタにRunnableインターフェースをを実装するクラスのインスタンスを指定し、 Threadクラスのstartメソッドを実行することによって、Runnableインターフェースをを実装するクラスのrunメソッドが呼び出されスレッドが起動します。
Thread t = new Thread(new MyClass());
t.start();
以下の例では1つめのスレッドでラベル1に500ミリ秒間隔で数字をカウントアップした値を表示し、2つめのスレッドでラベル2に1000ミリ秒間隔で数字をカウントアップした値を表示します。
package multiThreadSample;

import java.awt.Button;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ThreadSample02 extends Frame implements ActionListener{

private static final long serialVersionUID = 1L;

public static void main(String[] args){
new ThreadSample02();
}

Label lbl1;
Label lbl2;
Button btnRun;

public ThreadSample02(){
this.setTitle("ThreadSample02");
this.setSize(300,300);
this.setLayout(new GridLayout(3,1));

lbl1 = new Label();
this.add(lbl1);
lbl2 = new Label();
this.add(lbl2);

Panel p1 = new Panel();
btnRun = new Button("Run");
btnRun.addActionListener(this);
p1.add(btnRun);
this.add(p1);

this.setVisible(true);
}

public void actionPerformed(ActionEvent arg0) {
Thread t1 = new Thread(new MyThread(lbl1,500));
t1.start();

Thread t2 = new Thread(new MyThread(lbl2,1000));
t2.start();

} 
}

class MyThread implements Runnable{
Label lbl;
int time;

public MyThread(Label lbl, int time){
this.lbl = lbl;
this.time = time;
}

public void run() {
for (int i = 0; i < 100; i++){
lbl.setText("Count:" + i);
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}

2009年6月10日水曜日

Java XMLEncoder、XMLDecoderを使用したオブジェクトの保存(シリアライズ/デシリアライズ)その1

オブジェクトの状態をXMLファイルに保存(シリアライズ)したり、XMLファイルかデータを読み込みオブジェクトを復元(デシリアライズ)したりするには
java.beans.XMLEncoderクラスとjava.beans.XMLDecorderクラスを使用します。
※Javaではシリアライズ/デシリアライズを行うためにjava.io.ObjectOutputStream とjava.io.ObjectInputStreamを使用してバイナリファイルに読み書きを行っていたらしいのですが、色々問題があったようでJDK 1.4からシリアライズの新たな機能としてXMLファイルにオブジェクトの状態を読み書きするjava.beans.XMLEncoder、java.beans.XMLDecoderクラスが追加されたそうです。



まずはFrameに配置したTextAreaの状態(入力内容や色、フォントなど)をXMLファイルに読み書きします。

package FileAccess;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class SerializableSample01 extends Frame implements ActionListener{

private static final long serialVersionUID = 1L;

public static void main(String args[]){
new SerializableSample01();
}

Button btnSave;
Button btnLoad;
TextArea ta;

public SerializableSample01(){
this.setTitle("SerializableSample01");
this.setSize(300, 300);

ta = new TextArea();
this.add(ta,BorderLayout.CENTER);

Panel p1 = new Panel();
btnSave = new Button("Save");
btnSave.addActionListener(this);
btnLoad = new Button("Load");
btnLoad.addActionListener(this);
p1.add(btnSave);
p1.add(btnLoad);
this.add(p1,BorderLayout.SOUTH);

this.setVisible(true);
}


public void actionPerformed(ActionEvent arg0) {
if (arg0.getSource() == btnSave){
save();
}else if (arg0.getSource() == btnLoad){
load();
}
}

/*
* テキストエリアの状態をXMLファイルに書き込みます。
*/
private void save(){
FileOutputStream fos = null;
BufferedOutputStream bos = null;
XMLEncoder encoder = null;

try {
fos = new FileOutputStream("D:/SerializableSample01.xml");
bos = new BufferedOutputStream(fos);
encoder = new XMLEncoder(bos);

encoder.writeObject(ta);

} catch (FileNotFoundException e) {
e.printStackTrace();
} finally { 
if (encoder != null){
encoder.close();
}
}

//テキストエリアを削除します。
this.remove(ta);
ta = null;
this.validate();   
}

/*
* テキストエリアの状態をXMLファイルから読み取ります。
*/
private void load(){
FileInputStream fis = null;
BufferedInputStream bis = null;
XMLDecoder decoder = null;

try {
fis = new FileInputStream("D:/SerializableSample01.xml");
bis = new BufferedInputStream(fis);
decoder = new XMLDecoder(bis);

ta = (TextArea)decoder.readObject();

} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (decoder != null){ 
decoder.close();
}
}

//テキストエリアを追加します。
this.add(ta,BorderLayout.CENTER);
this.validate();
}

}


まずテキストエリアに書き込みます。


saveボタンでテキストエリアの状態をシリアライズして、フレームからテキストエリアを削除します。


loadボタンでテキストエリアの状態を復元し、フレームに追加します。



テキストエリアの状態を保存したXMLファイルの内容です。
 
 
 
 
 
255 
255 
255 
255 
 
 
 
28 
 
 
text0 
 
 
28 
 
 
28 
 
 
シリアライズ

デシリアライズ

サンプルです。 
 
 
 


XMLEncoderクラス、XMLDecoderクラスで読み書きできるオブジェクト



XMLEncoderクラス、XMLDecoderクラスで読み書きできるオブジェクトは
デフォルトコントラスタが必ずあること。
インスタンス変数にアクセスするためのアクセッサが定義されていること。
アクセッサの名前はset変数名、get変数名(booleanを返す場合is変数名でもOK)であること。



簡単なクラスを作成し、そのオブジェクトをXMLEncoderクラス、XMLDecoderクラスで読み書きしてみます。


名前と年齢をフィールドに持つEmployeeクラス
package FileAccess;

public class Employee {
private String _name;
private int _age;

public Employee(){
_name = "No Name";
_age = 0;
}

public Employee(String name, int age){
_name = name;
_age = age;
}

public void setName(String value){ _name = value; }
public String getName(){ return _name; }

public void setAge(int value){ _age = value; }
public int getAge(){ return _age; }

}


EmployeeクラスをXMLに書き込み、再度そのXMLを読み込みEmployeeクラスを復元して名前と年齢をコンソールに出力します。
package FileAccess;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class SerializableSample02 {

public static void main(String args[]){

Employee emp = new Employee("yan",25);

FileOutputStream fos = null;
BufferedOutputStream bos = null;
XMLEncoder enc = null;
try {
fos = new FileOutputStream("D:/Employee.xml");
bos = new BufferedOutputStream(fos);
enc = new XMLEncoder(bos);

enc.writeObject(emp);
enc.flush();

} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (enc != null){
enc.close();
}
}

FileInputStream fis = null;
BufferedInputStream bis = null;
XMLDecoder dec = null;

try {
fis = new FileInputStream("D:/Employee.xml");
bis = new BufferedInputStream(fis);
dec = new XMLDecoder(bis);

Employee newEmp = (Employee)dec.readObject();

System.out.println(newEmp.getName());
System.out.println(newEmp.getAge());

} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (dec != null){
dec.close();
}
}
}
}

Java DataInputStreamクラス、DataOutputStreamクラスを使用してバイナリファイルの読み書きを行う

DataInputStreamクラス、DataOutputStreamクラスを使用してバイナリファイルの読み書きを行います。

DataInputStreamはint型やboolean型といったプリミティブ型およびString型の値としてバイナリファイルのバイトデータを読み込みます。

boolean readBoolean()
1 バイトの入力データを読み込んで、そのバイトがゼロ以外の場合は true、そのバイトがゼロの場合は false を返します。
byte readByte()
1 バイトの入力データを読み込んで返します。
char readChar()
入力データの char を読み込んで、char 値を返します。
double readDouble()
8 バイトの入力データを読み込んで、double 値を返します。
float readFloat()
4 バイトの入力データを読み込んで、float 値を返します。
void readFully(byte[] b)
入力ストリームから数バイトを読み込み、それをバッファー配列 b に格納します。
void readFully(byte[] b, int off, int len)
入力ストリームから len バイトを読み込みます。
int readInt()
4 バイトの入力データを読み込んで、int 値を返します。
String readLine()
入力ストリームから、次の行のテキストを読み込みます。
long readLong()
8 バイトの入力データを読み込んで、long 値を返します。
short readShort()
2 バイトの入力データを読み込んで、short 値を返します。
int readUnsignedByte()
1 バイトの入力データを読み込んで、int 型にゼロ拡張して結果を返します。
int readUnsignedShort()
2 バイトの入力データを読み込んで、0 0 65535 の範囲の int 値を返します。
String readUTF()
修正 UTF-8 形式でエンコードされた文字列を読み込みます。





DataOutputStreamクラスも同じくint型やboolean型といったプリミティブ型およびString型の値をバイナリファイルのバイトデータとして書き込みます。

void write(byte[] b)
出力ストリームに配列 b のすべてのバイトを書き込みます。
void write(byte[] b, int off, int len)
配列 b から len バイトを順番に出力ストリームに書き込みます。
void write(int b)
引数 b の下位 8 ビットを出力ストリームに書き込みます。
void writeBoolean(boolean v)
1 つの boolean 値を出力ストリームに書き込みます。
void writeByte(int v)
引数 v の下位 8 ビットを出力ストリームに書き込みます。
void writeBytes(String s)
文字列を出力ストリームに書き込みます。
void writeChar(int v)
2 バイトから構成される char 値を出力ストリームに書き込みます。
void writeChars(String s)
文字列 s 内の各文字を、1 文字ごとに 2 バイトずつ出力ストリームに順番に書き込みます。
void writeDouble(double v)
8 バイトから構成される double 値を出力ストリームに書き込みます。
void writeFloat(float v)
4 バイトから構成される float 値を出力ストリームに書き込みます。
void writeInt(int v)
4 バイトから構成される int 値を出力ストリームに書き込みます。
void writeLong(long v)
8 バイトから構成される long 値を出力ストリームに書き込みます。
void writeShort(int v)
引数の値を表す 2 バイトを出力ストリームに書き込みます。
void writeUTF(String str)
長さ情報の 2 バイトを出力ストリームに書き込みます。


DataInputStreamクラスで読み取れるバイナリファイルはDataOutputStreamクラスを使用して作成したファイルだけです。
そのためアプリケーション独自で読み書きするバイナリファイルに限られます。

package FileAccess;

import java.awt.Button;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class BinaryFileSample03 extends Frame implements ActionListener{

private static final long serialVersionUID = 1L;

public static void main(String args[]){ 
new BinaryFileSample03();
}


Button btnWrite;
Button btnRead;

public BinaryFileSample03(){
this.setTitle("BinaryFileSample03");
this.setSize(300,100);

btnWrite = new Button("Write");
btnWrite.addActionListener(this);
btnRead = new Button("Read");
btnRead.addActionListener(this);
Panel p1 = new Panel();
p1.add(btnWrite);
p1.add(btnRead);
this.add(p1);

this.setVisible(true);
}

public void actionPerformed(ActionEvent arg0) {
if (arg0.getSource() == btnWrite){
write();
}else if (arg0.getSource() == btnRead){
read();
}
}

/*
* 書込み
*/
private void write(){
FileOutputStream fos = null;
BufferedOutputStream bos = null;
DataOutputStream dos = null;

try {
fos = new FileOutputStream("D:/BinaryFileSample03.txt");
bos = new BufferedOutputStream(fos);
dos = new DataOutputStream(bos);

dos.writeBoolean(false);
dos.writeInt(50);
dos.writeBoolean(true);
dos.writeUTF("文字列1");
dos.writeInt(100);
dos.writeUTF("文字列2");

dos.flush();

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (dos != null){
dos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}  
}

/*
* 読込み
*/
private void read(){
FileInputStream fis = null;
BufferedInputStream bis = null;
DataInputStream dis = null;

try {
fis = new FileInputStream("D:/BinaryFileSample03.txt");
bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);

boolean b1 = dis.readBoolean();
int i1 = dis.readInt();
boolean b2 = dis.readBoolean();
String s1 = dis.readUTF();
int i2 = dis.readInt(); 
String s2 = dis.readUTF();

System.out.println(b1);
System.out.println(b2);
System.out.println(i1);
System.out.println(i2);
System.out.println(s1);
System.out.println(s2);

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (dis != null){
dis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

Java バイナリファイルを効率的に読み書きする

BufferedInputStreamとBufferedOutputStreamを使用してバイナリファイルより効率的にデータを読み書きします。

BufferdInputStreamは使用方法はFileInputStreamと同じですが、FileInputStreamはreadメソッドが呼ばれるたびにファイルアクセスするのに対し
BufferedInputStreamは1回のreadメソッドで数バイトをあらかじめ取得しバッファに保存します。そのバッファから値を取り出し返します。

BufferdOutputStreamのwriteメソッドはバッファに対し書き込みを行い、flushメソッドでファイルに書き込みます。


バイナリファイルから1バイトづつ読み込み、1バイトづつ書き込みますで使用したコードを
BufferedInputStreamとBufferedOutputStreamを使用して書き換えます。

下記のコードはBufferedInputStreamとBufferedOutputStreamを使用して「D:/Sample1.jpg」より1バイト読み込み、「D:/CopySample1.jpg」に1バイト書き込みます。
package FileAccess;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class BinaryFileSample02 {
public static void main(String args[]){
new BinaryFileSample01();
}

public BinaryFileSample02(){
FileInputStream fip = null;
BufferedInputStream bis = null;

FileOutputStream fos = null;
BufferedOutputStream bos = null;

try {
fip = new FileInputStream("D:/Sample1.jpg");
bis = new BufferedInputStream(fip);

fos = new FileOutputStream("D:/CopySample1.jpg");
bos = new BufferedOutputStream(fos);

int data;
while ((data = bis.read()) != -1){
bos.write(data);
}
bos.flush();

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{

try {
if (bis != null){
bis.close();
}
} catch (IOException e) {
e.printStackTrace();
}

try {
if (bos != null){
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}

}

}
}

Java バイナリファイルから1バイトづつ読み込み、1バイトづつ書き込みます。

バイナリファイルから1バイトづつ読み込むには
FilreInputStreamクラスのreadメソッドを使用します。
readメソッドはファイルの最後に達すると-1を返します。

int read()
入力ストリームから 1 バイトを読み込みます。
int read(byte[] b)
入力ストリームから最大 b.length バイトをバイト配列に読み込みます。
int read(byte[] b, int off, int len)
入力ストリームからバイト配列へ最大 len バイトのデータを読み込みます。



1バイトづつバイナリファイルへ書き込むにはFileOutputStreamクラスのwriteメソッド使用します。

void write(int b)
指定されたバイトデータをファイル出力ストリームに書き込みます。
void write(byte[] b)
指定されたバイト配列の b.length バイトをこのファイル出力ストリームに書き込みます。
void write(byte[] b, int off, int len)
指定されたバイト配列からのオフセット位置 off から始まる len バイトをこのファイル出力ストリームに書き込みます。


参考:テキストファイルの場合とほとんど同じです。
テキストファイルから1文字づつ文字を読み込む
テキストファイルに文字を書き込む

下記のコードは「D:/Sample1.jpg」より1バイト読み込み、「D:/CopySample1.jpg」に1バイト書き込みます。
package FileAccess;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;


public class BinaryFileSample01{

public static void main(String args[]){
new BinaryFileSample01();
}

public BinaryFileSample01(){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("D:/Sample1.jpg");
fos = new FileOutputStream("D:/CopySample1.jpg");
int data;
while ((data = fis.read()) != -1){
fos.write(data);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{

try {
if (fis != null){
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}

try {
if (fos != null){
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}

}

}
}

2009年6月9日火曜日

Java テキストファイルに文字をまとめて書き込む

バッファに文字を書き込み、書き込んだ文字をまとめてファイルに書き込みます。
ますFileWriterクラスのコンストラクタに書き込むファイルのパスを指定し、FileWriterインスタンスを作成します。
つぎにBufferedWriterクラスのコンストラクタにFileWriterインスタンスを指定し、BufferedWriterインスタンスを作成します。
BufferedWriterクラスのwriteメソッドを使用し、バッファに文字列を書き込んでいきます。
BufferedWriterクラスのflushメソッドを使用し、ファイルに書き込みを行います。
最後に使い終わったBufferedWriterはcloseメソッドを使用して、ファイルを閉じます。
closeメソッドでもflushメソッドが呼ばれます。

またBufferedWriterクラスのnewlineメソッドはOSの標準改行文字を出力します。

package FileAccess;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class FileWriteSample02 extends Frame implements ActionListener{
private static final long serialVersionUID = 1L;

public static void main(String args[]){
new FileWriteSample02();
}

Frame frm = this;
TextArea txtBody;
Button btnSave;

public FileWriteSample02(){
this.setTitle("FileWriteSample02");
this.setSize(300,300);


txtBody = new TextArea();
this.add(txtBody,BorderLayout.CENTER);

btnSave = new Button("Save");
btnSave.addActionListener(this);

Panel pnl = new Panel();
pnl.add(btnSave);  
this.add(pnl,BorderLayout.SOUTH);

this.setVisible(true);
}

public void actionPerformed(ActionEvent ev){
SaveFile();
}

/*
* ファイルを保存します。
*/
private void SaveFile(){
//名前を付けて保存ダイアログを表示します。
String path = null;
FileDialog fd = new FileDialog(this , "名前を付けて保存" , FileDialog.SAVE);
try{
fd.setVisible(true);
if (fd.getFile() != null){
path = fd.getDirectory() + fd.getFile();
}
}finally{
fd.dispose();
}
//ファイルパスがnullの場合は処理を中止します。
if (path == null){
return; 
}
//テキストエリアの内容をファイルに書き込みます。
FileWriter fw = null;
BufferedWriter bw = null;
try {
fw = new FileWriter(path);
bw = new BufferedWriter(fw);
bw.write(txtBody.getText());
bw.newLine();
bw.append("追加書き込み");
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (bw != null){
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}



PrintWriterクラスを使用する


PrintWriterクラスのprintメソッドやprintlnメソッドを使用してファイルへの書き込みを行います。
BufferedWriterクラスのwriteメソッドは、引数として文字列しか受け取れませんが
PrintWriterクラスのprintメソッドや、printlnメソッドは引数として文字列以外にもint型やboolean型などのプリミティブ型を受け取ることができ、それをそのまま文字列として出力します。
printlnメソッドの場合は最後に改行を行います。
また、PrintWriterクラスのcloseメソッドは例外をスローしません。

package FileAccess;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class FileWriteSample03 extends Frame implements ActionListener{
private static final long serialVersionUID = 1L;

public static void main(String args[]){
new FileWriteSample03();
}

Frame frm = this;
TextArea txtBody;
Button btnSave;

public FileWriteSample03(){
this.setTitle("FileWriteSample03");
this.setSize(300,300);


txtBody = new TextArea();
this.add(txtBody,BorderLayout.CENTER);

btnSave = new Button("Save");
btnSave.addActionListener(this);

Panel pnl = new Panel();
pnl.add(btnSave);  
this.add(pnl,BorderLayout.SOUTH);

this.setVisible(true);
}

public void actionPerformed(ActionEvent ev){
SaveFile();
}

/*
* ファイルを保存します。
*/
private void SaveFile(){
//名前を付けて保存ダイアログを表示します。
String path = null;
FileDialog fd = new FileDialog(this , "名前を付けて保存" , FileDialog.SAVE);
try{
fd.setVisible(true);
if (fd.getFile() != null){
path = fd.getDirectory() + fd.getFile();
}
}finally{
fd.dispose();
}
//ファイルパスがnullの場合は処理を中止します。
if (path == null){
return; 
}
//テキストエリアの内容をファイルに書き込みます。
FileWriter fw = null;
BufferedWriter bw = null;
PrintWriter pw = null;
try {
fw = new FileWriter(path);
bw = new BufferedWriter(fw);
pw = new PrintWriter(bw);

pw.println(txtBody.getText());
pw.println(10);
pw.println(true);
pw.println("文字列");
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
if (pw != null){
pw.close();
}
}
}
}

Java テキストファイルに文字を書き込む

FileWriterクラスのwriteメソッドを使用してファイルに文字を書き込みます。
FileWriterクラスのコンストラクタには書き込むファイルのパスを指定します。
コンストラクタの第2引数にtrueを指定すると、ファイルへの追加書き込みを行います。

package FileAccess;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileWriter;
import java.io.IOException;


public class FileWriteSample01 extends Frame implements ActionListener{
private static final long serialVersionUID = 1L;

public static void main(String args[]){
new FileWriteSample01();
}

Frame frm = this;
TextArea txtBody;
Button btnSave;

public FileWriteSample01(){
this.setTitle("FileWriteSample01");
this.setSize(300,300);


txtBody = new TextArea();
this.add(txtBody,BorderLayout.CENTER);

btnSave = new Button("Save");
btnSave.addActionListener(this);

Panel pnl = new Panel();
pnl.add(btnSave);  
this.add(pnl,BorderLayout.SOUTH);

this.setVisible(true);
}

public void actionPerformed(ActionEvent ev){
SaveFile();
}

/*
* ファイルを保存します。
*/
private void SaveFile(){
//名前を付けて保存ダイアログを表示します。
String path = null;
FileDialog fd = new FileDialog(this , "名前を付けて保存" , FileDialog.SAVE);
try{
fd.setVisible(true);
if (fd.getFile() != null){
path = fd.getDirectory() + fd.getFile();
}
}finally{
fd.dispose();
}
//ファイルパスがnullの場合は処理を中止します。
if (path == null){
return; 
}
//テキストエリアの内容をファイルに書き込みます。
FileWriter fw =null;
try {
//fw = new FileWriter(path);
//追加書き込みする場合は、第2引数にtrueを指定します。
fw = new FileWriter(path,true);
fw.write(txtBody.getText());
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (fw != null){
fw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}






ファイルへ追加書き込みを行います。


Java テキストファイルから1行づつ文字を読み込む

ファイルから1行づつ文字を読み込むにはFileReaderクラスとBufferedReaderクラスを使用します。
FileReaderクラスのコンストラクタに読み込むファイルのパスを指定し、FileReaderクラスのインスタンスを作成します。
BufferedReaderクラスのコンストラクタにFileReaderクラスのインスタンスを指定し、BufferedReaderクラスのインスタンスを作成します。
BufferedReaderクラスのreadLineメソッドを使用してファイルから1行づつ文字を読み込みます。
readメソッドはファイルの終わりに達するとnullを返します。

package FileAccess;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class FileReadSample04 extends Frame implements ActionListener{
private static final long serialVersionUID = 1L;

public static void main(String args[]){
new FileReadSample04();
}

Frame frm = this;
TextArea txtBody;
Button btnOpen;

public FileReadSample04(){
this.setTitle("FileReadSample04");
this.setSize(300,300);


txtBody = new TextArea();
this.add(txtBody,BorderLayout.CENTER);

btnOpen = new Button("Load");
btnOpen.addActionListener(this);

Panel pnl = new Panel();
pnl.add(btnOpen);  
this.add(pnl,BorderLayout.SOUTH);

this.setVisible(true);
}

public void actionPerformed(ActionEvent ev){
OpenFile();
}

/*
* ファイルを開きます。
*/
private void OpenFile(){
//ファイルを開くダイアログを表示します。
String path = null;
FileDialog fd = new FileDialog(this , "ファイルを開く" , FileDialog.LOAD);
try{
fd.setVisible(true);
if (fd.getFile() != null){
path = fd.getDirectory() + fd.getFile();
}
}finally{
fd.dispose();
}
//ファイルパスがnullの場合は処理を中止します。
if (path == null){
return; 
}
//ファイルから1行づつ読み込みます。
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader(path);
br = new BufferedReader(fr);

StringBuilder sb = new StringBuilder();
String str;
while((str = br.readLine()) != null){
sb.append(str +"\r\n");
}

txtBody.setText(sb.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}finally{
try {
if (br != null){
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

2009年6月8日月曜日

Java テキストファイルから1文字づつ文字を読み込む

FileReaderクラスのreadメソッドを使用してファイルから1文字づつ文字を読み込みます。
readメソッドを使用して読み込んだ値は文字コードを表すint型の値として取得でき、char型にキャストすることで文字に変換します。
readメソッドはファイルの終わりに達すると-1を返します。

package FileAccess;

import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class FileReadSample01 extends Frame implements ActionListener{



private static final long serialVersionUID = 1L;

public static void main(String args[]){
new FileReadSample01();
}

Frame frm = this;
TextArea txtBody;
Button btnOpen;

public FileReadSample01(){
this.setTitle("FileReadSample01");
this.setSize(300,300);

txtBody = new TextArea();
this.add(txtBody,BorderLayout.CENTER);

btnOpen = new Button("Load");
btnOpen.addActionListener(this);

Panel pnl = new Panel();
pnl.add(btnOpen);  
this.add(pnl,BorderLayout.SOUTH);

this.setVisible(true);
}

public void actionPerformed(ActionEvent ev){
OpenFile();
}

/*
* ファイルを開きます。
*/
private void OpenFile(){
//ファイルを開くダイアログを表示します。
String path = null;
FileDialog fd = new FileDialog(this , "ファイルを開く" , FileDialog.LOAD);
try{
fd.setVisible(true);
if (fd.getFile() != null){
path = fd.getDirectory() + fd.getFile();
}
}finally{
fd.dispose();
}
//ファイルパスがnullの場合は処理を中止します。
if (path == null){
return; 
}
//ファイルから1文字づつ読み込みます。
FileReader fr = null;
StringBuffer sb = null;
try {
fr = new FileReader(path);
sb = new StringBuffer();
int ch;
while ((ch = fr.read()) != -1){
sb.append((char)ch);
}
txtBody.setText(sb.toString()); 
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}finally{
try {
if (fr != null){
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


readメソッドは他にもいくつかのオーバーロードがあります。
int read()単一文字を読み込みます。
int read(char[] cbuf)引数に指定した配列に文字を読み込みます。
abstract int read(char[] cbuf,int off,int len)文字を読み込んでcbufのoffに指定したオフセット位置からlenバイト分を格納します。


ファイルの最初から10バイト分のデータを取得するするには、int read(char[] cbuf)を使用します。
FileReader fr = null;
char[] buff = new char[10];
try {
fr = new FileReader(path);
fr.read(buff);
txtBody.setText(new String(buff));
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}finally{
try {
if (fr != null){
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}


read(char[] cbuf,int off,int len)はファイルの先頭から文字を読み込んでcbufのoffに指定したオフセット位置からlenバイト分を格納します。
ファイルの先頭から文字を読み込み、buff配列のオフセットが3の位置から7バイト分を読み込みます。
FileReader fr = null;
char[] buff = new char[10];
try {
fr = new FileReader(path);
fr.read(buff,3,7);

System.out.println(new String(buff));
txtBody.setText(new String(buff,3,7));
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}finally{
try {
if (fr != null){
fr.close(); 
}
} catch (IOException e) {
e.printStackTrace();
}
}

Java AWT ファイルを開くダイアログ/名前を付けて保存ダイアログ

ファイルを開くダイアログを表示するにはFileDialogクラスを使用します。
同じく名前を付けて保存ダイアログもFileDialogクラスを使用します。

FileDialogクラスのコンストラクタ

FileDialog(Frame parent)
FileDialog(Frame parent, String title)
FileDialog(Frame parent, String title, int mode)

引数 parent
オーナーとなるフレームを指定します。
引数 title
ダイアログタイトルを指定します。
引数 mode
ファイル開くダイアログの場合は FileDialog.LOAD を指定します。
ファイルを保存ダイアログの場合は FileDialog.SAVE を指定します。


package FileAccess;

import java.awt.*;
import java.awt.event.*;

public class FileDialogSample extends Frame implements ActionListener{

private static final long serialVersionUID = 1L;

public static void main(String args[]){
new FileDialogSample();
}

Label lblPath;
Button btnOpen;
Button btnSave;

public FileDialogSample(){
this.setTitle("FileDialogSample");
this.setSize(300,300);
this.setLayout(new GridLayout(2,1));

lblPath = new Label();
this.add(lblPath);

btnOpen = new Button();
btnOpen.setLabel("ファイルを開くダイアログを表示");
btnOpen.addActionListener(this);

btnSave = new Button();
btnSave.setLabel("名前を付けて保存ダイアログを表示");
btnSave.addActionListener(this);

Panel pnl1 = new Panel();
pnl1.add(btnOpen);
pnl1.add(btnSave);
this.add(pnl1);

this.setVisible(true);
}

public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnOpen){
FileOpenDialog();
}else if (e.getSource() == btnSave){
FileSaveDialog();
}
}

private void FileOpenDialog(){
String path = null;
FileDialog fd = new FileDialog(this , "ファイルを開く" , FileDialog.LOAD);
try{
fd.setVisible(true);
if (fd.getFile() != null) {
path = fd.getDirectory() + fd.getFile();
}
}finally{
fd.dispose();
}
if (path != null){
lblPath.setText(path);
}else{
lblPath.setText("");
}  
}

private void FileSaveDialog(){
String path = null;
FileDialog fd = new FileDialog(this , "名前を付けて保存" , FileDialog.SAVE);
try{
fd.setVisible(true);
if (fd.getFile() != null) {
path = fd.getDirectory() + fd.getFile();
}
}finally{
fd.dispose();
}
if (path != null){
lblPath.setText(path);
}else{
lblPath.setText("");
} 
}
}

2009年6月6日土曜日

Java AWT 描画処理 まとめ

paintメソッド以外からの描画


ボタンクリックやマウスクリックなどpaintメソッド以外からの描画処理を行います。

下記のコードはマウスクリックした座標に円を描画します。
GraphicsインスタンスはコンポーネントのgetGraphicsメソッドで取得します。
getGraphicsメソッドで取得したGraphicsインスタンスは、使用後disposeします。

package graphicsSample;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class GraphicSample03 extends Frame{

private static final long serialVersionUID = 1L;

public static void main(String args[]){
new GraphicSample03();
}

public GraphicSample03(){
this.setTitle("GraphicSample03");
this.setSize(300,300);
this.addMouseListener(new MyMouseAdapter());
this.setVisible(true);
}

private class MyMouseAdapter extends MouseAdapter{

public void mouseClicked(MouseEvent arg0) {
Graphics g = getGraphics();
try{
g.setColor(Color.darkGray);
g.drawOval(arg0.getX(), arg0.getY(), 50, 50);
}finally{
g.dispose();
}

}
} 

}






しかし、画面をリサイズすると描画が消えてしまいます。

ダブルバッファリングを利用して画面をリサイズしても描画が消えないようにする


対応策としてよく用いられているのが「ダブルバッファリング」です。
これは描画処理用のイメージ領域を別に作成し、まず必要な描画を全てそのイメージ領域に行っておいてから、最後にイメージ領域をフレームにまとめて描画します。

まずイメージ領域をインスタンスフィールドに用意します。
マウスクリックではこのイメージ領域に描画を行います。
paintメソッドでそのイメージ領域を描画します。

リサイズされるとpaintメソッドが実行されイメージ領域から再描画されます。
package graphicsSample;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class GraphicSample04 extends Frame{

private static final long serialVersionUID = 1L;

public static void main(String args[]){
new GraphicSample04();
}

//バッファ用イメージ
Image Img = null;

public GraphicSample04(){
this.setTitle("GraphicSample04");
this.setSize(300,300);
this.addMouseListener(new MyMouseAdapter());  
this.setVisible(true);
}

public void paint(Graphics g) {
//バッファ用イメージとグラフィックを作成します。
//コンストラクタではcreateImageインスタンスを作成できないのでココで初期化する。
if (Img == null){
Img = this.createImage(this.getWidth(),this.getHeight());
}
//イメージを描画します。
g.drawImage(Img,0,0,this);
}

private class MyMouseAdapter extends MouseAdapter{
public void mouseClicked(MouseEvent arg0) {
//バッファ用イメージに描画
Img.getGraphics().setColor(Color.darkGray);
Img.getGraphics().drawOval(arg0.getX(), arg0.getY(), 50, 50);
//paintを呼び出します。
repaint();
}
}
}



これで画面をリサイズしても描画は消えません。

しかし、画面を大きくしても描画領域は大きくならないため、大きくなった部分をマウスクリックしても円が描画されません。

画面のサイズに合わせて描画領域を変更する


componentResizedイベントで画面サイズに合わせて描画領域を変更します。
package graphicsSample;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;


public class GraphicSample05 extends Frame{

private static final long serialVersionUID = 1L;

public static void main(String args[]){
new GraphicSample05();
}

//バッファ用イメージ
Image backImg = null;
//バッファ用グラフィック
//Graphics backGraphic =null;

public GraphicSample05(){
this.setTitle("GraphicSample05");
this.setSize(300,300);
this.addMouseListener(new MyMouseAdapter());
this.addComponentListener(new MyComponentListener());
this.setVisible(true);
}

public void paint(Graphics g) {
//バッファ用イメージとグラフィックを作成します。
//コンストラクタではcreateImage、getGraphicsインスタンスを作成できないのでココで初期化する。
if (backImg == null){
backImg = this.createImage(this.getWidth(),this.getHeight());
//backGraphic = backImg.getGraphics();
}
//ブッファイメージを描画します。
g.drawImage(backImg,0,0,this);
}

private class MyMouseAdapter extends MouseAdapter{
public void mouseClicked(MouseEvent arg0) {
//ブッファ用イメージに描画
//backGraphic.setColor(Color.darkGray);
//backGraphic.drawOval(arg0.getX(), arg0.getY(), 50, 50);
backImg.getGraphics().setColor(Color.darkGray);
backImg.getGraphics().drawOval(arg0.getX(), arg0.getY(), 50, 50);
//paintを呼び出します。
repaint();
}
}

private class MyComponentListener extends ComponentAdapter{
public void componentResized(ComponentEvent arg0) {
//リサイズ後の現在サイズを取得します
Rectangle rec = getBounds(); 
//イメージのサイズより現在のサイズが大きい場合
if ((backImg.getWidth(null) <= rec.width ) | (backImg.getHeight(null) <= rec.height)){
//新たなイメージを作ります。
Image newImg = createImage(rec.width, rec.height);
//新たなイメージに古いイメージを描画します。
newImg.getGraphics().drawImage(backImg, 0, 0, null);
//新たなイメージをインスタンス変数に保存します。
backImg = newImg;
}
}
}
}

2009年6月5日金曜日

Java クラス名を変更するには

名前を変えたいクラスを選択し
eclipseの「りファクタリング」メニューの「名前の変更」を選択します。


やっとクラス名を変える方法がわかった・・・

javaよりeclipseの使い方を習得する方がしんどいよ~。・゚・(ノД`)・゚・。

Java AWT 実行ファイルに埋めこれたリソースファイルから画像を表示する

画像やテキストファイルを実行ファイルに埋め込むにはで埋め込んだ画像ファイルを表示します。


ClassクラスのgetResouceメソッドを使用しリソースファイルのURLインスタンスを取得します。
ComponentクラスのcreateImageメソッドを使用し、URLインスタンスからImageインスタンスを作成します。

そしてFrameクラスのpaintメソッドで作成したImageインスタンスを描画します。

package graphicsSample;

import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.ImageProducer;
import java.net.URL;

public class GraphicSample02 extends Frame{

private static final long serialVersionUID = 1L;

public static void main(String args[]){
new GraphicSample02();
}

Image img = null;

public GraphicSample02(){
this.setTitle("GraphicSample02");
this.setSize(500,500);

//リソースよりイメージ画像を取得します。
URL url = this.getClass().getResource("Sample1.jpg");
try{
img = this.createImage((ImageProducer)url.getContent());
}catch(Exception ex){}


this.setVisible(true);
}

public void paint(Graphics g) {
//イメージ画像を描画します。
g.drawImage(img,50,50,this);
}

}

Java 画像やテキストファイルを実行ファイルに埋め込むには

画像やテキストファイル(リソースファイル)を実行ファイルに埋め込むには
パッケージエクスプローラでパッケージを選択し、「ファイル」メニューの「インポート」を選択します。
起動した画面で「一般」ノードの「ファイルシステム」を選択して次へをクリックします。



参照ボタンをクリックし、画像ファイルのあるフォルダを選択します。
フォルダ内のファイルの一覧が表示されるので、埋め込むファイルを選択します。



パッケージエクスプローラでファイルが追加されていることを確認します。

雑記 ツレがリストラにあいまして

うちのツレ(夫)が3月末で会社をリストラされました。
ツレは39歳。IT系で組み込み一筋です。
高スキルも高学歴もありませんw

この大不況でIT業界でも組み込み系は特に厳しいようです。
転職活動も厳しく社員数15名の会社で1名の採用枠に対し応募者は50名を超えるそうです。
履歴書を送り求人に応募するも、予想外の応募者に処理しきれず書類選考に1か月かかった会社もありました。
転職サイトに公開されたらすぐに応募しないと、後半は書類すら見てもらえない可能性もあります。

ツレの転職活動は3か月間。7月から就職先が決まりました。
転職サイトから応募した会社は20社。
うち2社の面接をし、そのうち1社に採用していただきました。
あとはいつもお世話になっている知り合いの社長からの紹介で2社の面接をしました。
採用して頂いた会社からはスキルや経歴より、何かビビビと感じるものがあったから採用したと言われたそうです(*´∀`*)アッタカーイ

本当の所は20社程度の応募で決まるとは思わなかったです。
100社ぐらい応募しないとダメなんじゃないかと。
実際ツレにも100社まであきらめずに応募しろと言ってましたし。

しかし、今回リストラされて本当にラッキーでした。
不況で厳しい組み込み業界の中、3次受け、4次受けで偽装請負や多重派遣だけで成り立っているような会社は、採用を控えているでしょう。
今求人を出している会社は不況でフィルタされ優良企業である可能性が高いです。
ツレも給料こそ下がったものの、久しぶりに底辺から抜け出せたようです。

その上、ツレも私も今回のリストラは自分自身を見直す良い機会になりました。
最近モチベーションが下がり気味だった私も、新たな目標を設定しモチベーションが復活しましたし、
ツレも色々反省しなければいけない点に気づいてくれたようです。

ここまでは新しい就職先が決まったから言えるキレイ言ですが。
実際の転職活動はやはり精神的にしんどかったです。




今回はそんなツレが吐いた名言集をご紹介。



俺の人格を全否定する気か!!


( ̄д ̄) つまんない。想定の範囲内。













本を読むのは嫌いなんだよ!!



Σ(´∀`;) おまえは小学生か!!











おまえは俺を鬱にさせる気か!!



.∵・(゚ε゚ )ブッ!!
「親父にもブタレタ事ないのにぃ!」と被って面白かった。
プロポーズの言葉はわすれたけれど、これは一生覚えてると思うwww







ツレより優秀な人たちはたくさんいると思います。
転職活動は「あせらず、あわてず、あきらめず!」

2009年6月4日木曜日

.NET(Mobile) SIPパネルを切り替えるには

Touch Diamond (X04HT)のSIPはデフォルトで以下の5種類があります。
・10キー
・ひらがな/カタカナ
・ローマ字/かな
・手書き入力
・手書き検索

このSIPパネルを切り替えます。
方法は2つあります。

Microsoft.WindowsCE.Forms.InputMethodクラスを使用する方法です。
フォームにInputPanelを配置し、以下のコードを実行する。
Public Class Form1

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim im As Microsoft.WindowsCE.Forms.InputMethod
For Each im In Me.InputPanel1.InputMethods
Me.ListBox1.Items.Add(im.Name)
Next im

End Sub

Private Sub ListBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles ListBox1.SelectedIndexChanged
Dim strIM As String
strIM = ListBox1.SelectedItem.ToString()

Dim im As Microsoft.WindowsCE.Forms.InputMethod
For Each im In Me.InputPanel1.InputMethods
If im.Name = strIM Then
InputPanel1.CurrentInputMethod = im
End If
Next im
End Sub

End Class


こちらはAPI「SipSetCurrentIM」を使用します。
フォームにInputPanelを配置する必要はありません。
Imports System.Runtime.InteropServices

Public Class Form1

Private _InputMethod As New Dictionary(Of String, Guid)

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
For Each im As Microsoft.WindowsCE.Forms.InputMethod In Me.InputPanel1.InputMethods
_InputMethod.Add(im.Name, im.Clsid)
Me.ListBox1.Items.Add(im.Name)
Next im
End Sub

Private Sub ListBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles ListBox1.SelectedIndexChanged
Dim strIM As String = ListBox1.SelectedItem.ToString()
Dim guid As Guid = Me._InputMethod(strIM)

SipSetCurrentIM(guid.ToByteArray)
End Sub

 _
Private Shared Function SipSetCurrentIM(ByVal clsid As Byte()) As Boolean
End Function

End Class

.NET(Mobile) Touch Diamond (X04HT)のデフォルト10キーSIPの入力モードを切り替える

Touch Diamond (X04HT)のデフォルト10キーSIPの入力モードを切り替えるには
レジストリ「HKEY_CURRENT_USER\Software\Keytouch\Multiplay」の値を操作します。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
SetKey10InputMode(CType(Me.ComboBox1.SelectedIndex, Key10ModeType))
End Sub

Public Enum Key10ModeType
NumHalf = 0
NumFull = 1
AlphaHalf = 2
AlphaFull = 3
Hiragana = 4
KatakanaHalf = 5
KatakanaFull = 6
End Enum

Private Sub SetKey10InputMode(ByVal mode As Key10ModeType)
Dim sReg As String = "HKEY_CURRENT_USER\Software\Keytouch\Multiplay"

Select Case mode
Case Key10ModeType.NumHalf
Microsoft.Win32.Registry.SetValue(sReg, "ShiftModeEx", 9)
Microsoft.Win32.Registry.SetValue(sReg, "ShiftMode", 8)
Microsoft.Win32.Registry.SetValue(sReg, "ActiveIME", 1)
Microsoft.Win32.Registry.SetValue(sReg, "NumericMode", 0)
Microsoft.Win32.Registry.SetValue(sReg, "PasswordMode", 0)

Case Key10ModeType.NumFull
Microsoft.Win32.Registry.SetValue(sReg, "ShiftModeEx", 8)
Microsoft.Win32.Registry.SetValue(sReg, "ShiftMode", 7)
Microsoft.Win32.Registry.SetValue(sReg, "ActiveIME", 1)
Microsoft.Win32.Registry.SetValue(sReg, "NumericMode", 0)
Microsoft.Win32.Registry.SetValue(sReg, "PasswordMode", 0)

Case Key10ModeType.AlphaHalf
Microsoft.Win32.Registry.SetValue(sReg, "ShiftModeEx", 7)
Microsoft.Win32.Registry.SetValue(sReg, "ShiftMode", 6)
Microsoft.Win32.Registry.SetValue(sReg, "ActiveIME", 1)
Microsoft.Win32.Registry.SetValue(sReg, "NumericMode", 0)
Microsoft.Win32.Registry.SetValue(sReg, "PasswordMode", 0)


Case Key10ModeType.AlphaFull
Microsoft.Win32.Registry.SetValue(sReg, "ShiftModeEx", 6)
Microsoft.Win32.Registry.SetValue(sReg, "ShiftMode", 5)
Microsoft.Win32.Registry.SetValue(sReg, "ActiveIME", 1)
Microsoft.Win32.Registry.SetValue(sReg, "NumericMode", 0)
Microsoft.Win32.Registry.SetValue(sReg, "PasswordMode", 0)

Case Key10ModeType.Hiragana
Microsoft.Win32.Registry.SetValue(sReg, "ShiftModeEx", 0)
Microsoft.Win32.Registry.SetValue(sReg, "ShiftMode", 0)
Microsoft.Win32.Registry.SetValue(sReg, "ActiveIME", 202)
Microsoft.Win32.Registry.SetValue(sReg, "NumericMode", 0)
Microsoft.Win32.Registry.SetValue(sReg, "PasswordMode", 0)

Case Key10ModeType.KatakanaHalf
Microsoft.Win32.Registry.SetValue(sReg, "ShiftModeEx", 3)
Microsoft.Win32.Registry.SetValue(sReg, "ShiftMode", 2)
Microsoft.Win32.Registry.SetValue(sReg, "ActiveIME", 202)
Microsoft.Win32.Registry.SetValue(sReg, "NumericMode", 0)
Microsoft.Win32.Registry.SetValue(sReg, "PasswordMode", 0)

Case Key10ModeType.KatakanaFull
Microsoft.Win32.Registry.SetValue(sReg, "ShiftModeEx", 2)
Microsoft.Win32.Registry.SetValue(sReg, "ShiftMode", 1)
Microsoft.Win32.Registry.SetValue(sReg, "ActiveIME", 202)
Microsoft.Win32.Registry.SetValue(sReg, "NumericMode", 0)
Microsoft.Win32.Registry.SetValue(sReg, "PasswordMode", 0)

End Select
End Sub



ちなみに

W-ZERO3[es]本体表面の10キーを制御するのは
レジストリ「HKEY_CURRENT_USER\Software\Sharp\PhoneStatus」を操作します。

DT5200は本体表面の10キーを制御するのは
カシオのAPI「Calib.SystemLibNet.Api.SysSetInputMode」を使用します。
CASIOシステムライブラリマニュアル

モバイルのレジストリはVisualStudioの付属ツール「リモートレジストリエディタ」で見ることができます。

.NET(Mobile) コントロールのIMEモードを設定する

WindowsアプリであればテキストボックスのImeModeプロパティがありますが
CompactFrameworkのテキストボックスにはImeModeプロパティがありません。

CompactFrameworkのテキストボックスのImeModeを設定するにはAPIを使用します。
Imports System.Runtime.InteropServices

Public Class Form1

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Call SetImeMode(Me.TextBox1, ImeMode.HIRAGANA)
End Sub

Public Enum ImeMode
NOCONTROL = 0
OFF = 1
[ON] = 2
DISABLE = 3
HIRAGANA = 4
KATAKANA = 5
KATAKANAHALF = 6
ALPHAFULL = 7
ALPHA = 8
End Enum

Private Const ALPHANUMERIC As Int32 = &H0   '半角英数
Private Const NATIVE As Int32 = &H1         '直接入力
Private Const KATAKANA As Int32 = &H2       'カタカナ
Private Const FULLSHAPE As Int32 = &H8      '全角
Private Const ROMAN As Int32 = &H10

 _
Private Shared Function ImmGetContext(ByVal hWnd As IntPtr) As IntPtr
End Function

 _
Private Shared Function ImmReleaseContext(ByVal hWnd As IntPtr) As Boolean
End Function

 _
Private Shared Function ImmSetConversionStatus(ByVal hIMC As IntPtr, ByVal fdwConversion As Int32, ByVal fdwSentence As Int32) As Boolean
End Function

 _
Private Shared Function ImmSetOpenStatus(ByVal hIMC As IntPtr, ByVal fOpen As Int32) As Boolean
End Function

 _
Private Shared Function ImmAssociateContext(ByVal hWnd As IntPtr, ByVal hIMC As Int32) As Int32
End Function


Private Sub SetImeMode(ByVal ctrl As Control, ByVal mode As ImeMode)
Dim himc As IntPtr = ImmGetContext(ctrl.Handle)

Try
Select Case mode
Case ImeMode.DISABLE
ImmAssociateContext(himc, 0)

Case ImeMode.OFF
ImmAssociateContext(himc, 1)
ImmSetOpenStatus(himc, 0)

Case ImeMode.ON
ImmAssociateContext(himc, 1)
ImmSetOpenStatus(himc, 1)

Case Else

ImmAssociateContext(himc, 1)
ImmSetOpenStatus(himc, 1)

Dim dwConversion As Int32

Select Case mode
Case ImeMode.HIRAGANA
dwConversion = NATIVE Or FULLSHAPE Or ROMAN
Case ImeMode.KATAKANA
dwConversion = NATIVE Or FULLSHAPE Or KATAKANA Or ROMAN
Case ImeMode.KATAKANAHALF
dwConversion = NATIVE Or KATAKANA Or ROMAN
Case ImeMode.ALPHAFULL
dwConversion = FULLSHAPE Or ALPHANUMERIC
Case ImeMode.ALPHA
dwConversion = ALPHANUMERIC
End Select
ImmSetConversionStatus(himc, dwConversion, 0)



End Select
Finally
ImmReleaseContext(ctrl.Handle)
End Try

End Sub


End Class

.NET(Mobile) アプリのメモリ使用量について

CompactFrameworkアプリでフォームを開いたり閉じたりしていると、メモリ使用量がどんどん増えていきます。

Microsofrフィードバックによると
Inherits Componentしているコントロール(Timer、ToolTipなど)を使用する際に.Netが自動生成するコードが
CompactFrameworkでは自動生成されないためフォームの参照が解放されず、ガーベッジに収集されないらしいのです。

具体的にはCompactFrameworkのMainMenuコントロールはInherits Componentされているにもかかわらず、Desiner.vbでcomponentsに追加されずfinalizaで解放されないということです。
このコードの★部分が本来ならmainMenu1 = New System.Windows.Forms.Mainmenu(components)となる。
 _
Partial Public Class Form1
Inherits System.Windows.Forms.Form

'フォームがコンポーネントの一覧をクリーンアップするために dispose をオーバーライドします。
 _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
MyBase.Dispose(disposing)
End Sub

'Windows フォーム デザイナで必要です。
Private components As System.ComponentModel.IContainer
Private mainMenu1 As System.Windows.Forms.MainMenu

'メモ: 以下のプロシージャは Windows フォーム デザイナで必要です。
'Windows フォーム デザイナを使用して変更できます。  
'コード エディタを使って変更しないでください。
 _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container
'★本来ならmainMenu1 = New System.Windows.Forms.Mainmenu(components)
mainMenu1 = New System.Windows.Forms.Mainmenu()
Me.Menu = mainMenu1
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi
Me.Text = "Form1"
Me.AutoScroll = True
End Sub
End Class



しかし、それでもメモリは増え続けていきます・・・・


ダイアログフォームを起動し、ダイアログフォームを閉じる処理を1000回行い100回ごとにメモリ使用量を計測する処理を
以下の7種類のコードで試してみました。

コード1
Form2を起動し、Form2のActivatedでForm2を閉じます。
Form2にはmainMenuコントロールを1つ配置しています。
Using句を使用します。
Me.ListBox1.Items.Add("開始" & " : " & GC.GetTotalMemory(False))
For i As Int32 = 1 To 1000
Using frm As New Form2
frm.ShowDialog()
End Using
If i Mod 100 = 0 Then
Me.ListBox1.Items.Add(i.ToString & " : " & GC.GetTotalMemory(False))
End If
Next


コード2
Form2を起動し、Form2のActivatedでForm2を閉じます。
Form2にはmainMenuコントロールを1つ配置しています。
Using句を使用します。
GC.Collectを1回実行します。
Me.ListBox1.Items.Add("開始" & " : " & GC.GetTotalMemory(False))
For i As Int32 = 1 To 1000
Using frm As New Form2
frm.ShowDialog()
End Using
GC.Collect()
If i Mod 100 = 0 Then
Me.ListBox1.Items.Add(i.ToString & " : " & GC.GetTotalMemory(False))
End If
Next


コード3
Form3を起動し、Form3のActivatedでForm3を閉じます。
Form3にはmainMenuコントロールを1つ配置しています。
Form3のmainMenuコントロールはmainMenu1 = New System.Windows.Forms.Mainmenu(components)とします。
Using句を使用します。
GC.Collectを1回実行します。
Me.ListBox1.Items.Add("開始" & " : " & GC.GetTotalMemory(False))
For i As Int32 = 1 To 1000
Using frm As New Form3
frm.ShowDialog()
End Using
GC.Collect()
If i Mod 100 = 0 Then
Me.ListBox1.Items.Add(i.ToString & " : " & GC.GetTotalMemory(False))
End If
Next


コード4
Form2を起動し、Form2のActivatedでForm2を閉じます。
Form2にはmainMenuコントロールを1つ配置しています。
Try~finally句を使用します。
Me.ListBox1.Items.Add("開始" & " : " & GC.GetTotalMemory(False))
For i As Int32 = 1 To 1000
Dim frm As New Form2
Try
frm.ShowDialog()
Finally
frm.Dispose()
End Try
If i Mod 100 = 0 Then
Me.ListBox1.Items.Add(i.ToString & " : " & GC.GetTotalMemory(False))
End If
Next


コード5
Form2を起動し、Form2のActivatedでForm2を閉じます。
Form2にはmainMenuコントロールを1つ配置しています。
Try~finally句を使用します。
GC.Collectを1回実行します。
Me.ListBox1.Items.Add("開始" & " : " & GC.GetTotalMemory(False))
For i As Int32 = 1 To 1000
Dim frm As New Form2
Try
frm.ShowDialog()
Finally
frm.Dispose()
End Try
GC.Collect()
If i Mod 100 = 0 Then
Me.ListBox1.Items.Add(i.ToString & " : " & GC.GetTotalMemory(False))
End If
Next


コード6
Form2を起動し、Form2のActivatedでForm2を閉じます。
Form2にはmainMenuコントロールを1つ配置しています。
Try~finally句を使用します。
Form2にNothingを設定します。
GC.Collectを1回実行します。
Me.ListBox1.Items.Add("開始" & " : " & GC.GetTotalMemory(False))
For i As Int32 = 1 To 1000
Dim frm As New Form2
Try
frm.ShowDialog()
Finally
frm.Dispose()
frm = Nothing
End Try
GC.Collect()
If i Mod 100 = 0 Then
Me.ListBox1.Items.Add(i.ToString & " : " & GC.GetTotalMemory(False))
End If
Next


コード7
Form3を起動し、Form3のActivatedでForm3を閉じます。
Form3にはmainMenuコントロールを1つ配置しています。
Form3のmainMenuコントロールはmainMenu1 = New System.Windows.Forms.Mainmenu(components)とします。
Try~finally句を使用します。
GC.Collectを1回実行します。
Me.ListBox1.Items.Add("開始" & " : " & GC.GetTotalMemory(False))
For i As Int32 = 1 To 1000
Dim frm As New Form3
Try
frm.ShowDialog()
Finally
frm.Dispose()
End Try
GC.Collect()
If i Mod 100 = 0 Then
Me.ListBox1.Items.Add(i.ToString & " : " & GC.GetTotalMemory(False))
End If
Next




コード1、コード4はメモリ使用量はほぼ同じですが、他のコードと比べGC.Collectを実行していないので、最もメモリ使用量が高いです。
コード6以外のその他のコードはメモリ使用量はほぼ同じです。
圧倒的にメモリ使用量が少なく、メモリ増加量も少ないのがコード6でした。

う~ん・・・?ナゼ?