레이블이 java RandomAccessFile인 게시물을 표시합니다. 모든 게시물 표시
레이블이 java RandomAccessFile인 게시물을 표시합니다. 모든 게시물 표시

2013년 8월 10일 토요일

Raw/Long Raw Type에 관하여

Oracle LongRaw 데이터 타입에 관하여

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  



1. 이진 Data또는 Byte문자열을 위한것

2. RAW및 LONG RAW는 Data전송시 인스턴스에 사용자 세션을 접속하는 SQL*Net과
Inport/Export Utility가 문자변환을 수행하지 않는다는 점을 제외하면 Varchar2 Data
Type과 같은 가변길이 Data 유형이다.

3. Oracle이 RAW나 LONG RAW를 CHAR로 상호 변환하는 경우 한 문자에 4bit가 해당되는
16진수 형태로 표현된다.(11001011 은 'CB')

4.  Long Raw는 Index될수 없으나 Raw는 Index 될수있다.

--------------------------
자바에서 LongRaw 예
--------------------------
1. 읽을때(detail이란 컬럼이 longraw 입니다.)

try{
            InputStream vIcode        =null;
            BufferedReader vvcode    =null;

            Statement stmt = con.createStatement();
            ResultSet rs = stmt.executeQuery(" select name,title,detail,re_id,ip,count,to_char(ilsi,'dd/MON/yyyy(hh:mi)'),path,e_mail,root_id,depth  from db_board where id = "+szID);
            rs.next();
            szName = rs.getString(1);
            szTitle = rs.getString(2);
           
            szDetail= hangul.han(new String(rs.getBytes(3),0));           
            szRe_Id = rs.getString(4);
            szIp = rs.getString(5);
            iCount = rs.getInt(6);
            szIlsi = rs.getString(7);
            szPath = rs.getString(8);
            szE_mail = rs.getString(9);
            szRoot_Id = rs.getString(10);
            szDepth = rs.getString(11);
            iCount++;
            rs.close();
            stmt.executeUpdate(" update db_board set count=count+1 where id = "+szID);
            stmt.close();
   
      }

2. 저장하는 예

PreparedStatement ps = con.prepareStatement("insert into db_board(id,re_id,name,title,detail,passwd,count,ip,ilsi,e_mail,is_re,board_gbn,path,root_id,depth) values (?,0,?,?,?,?,0,?,sysdate,?,'N',?,?,?,0)");

          ps.setInt(1,iId);
          ps.setString(2,hangul.han(szName));
          ps.setString(3,hangul.han(szTitle));

//////////////////////////////////////////////////////////////////////////
          StringBuffer szbWriteDetail = new StringBuffer();
          for( int i = 0,len=szDetail.length() ; i < len ; i++){
              if( szDetail.charAt(i) == ' ')
                  szbWriteDetail.append(" ");
              else if( szDetail.charAt(i) == '<')
                  szbWriteDetail.append("<");
              else if( szDetail.charAt(i) == '>')
                  szbWriteDetail.append(">");
              else if( szDetail.charAt(i) == '\n')
                  szbWriteDetail.append("<br>");
              else
                  szbWriteDetail.append(szDetail.charAt(i));
          }
////////////////////////////////////////////////////////////////////////////

          StringBufferInputStream abc = new  StringBufferInputStream(szbWriteDetail.toString());
          ps.setBinaryStream(4,abc,szbWriteDetail.length());
          ps.setString(5,szPasswd);
          ps.setString(6,szIp);
          ps.setString(7,szE_mail);
          ps.setString(8,szBoard_Gbn);
          ps.setString(9,szPath);
          ps.setInt(10,iId);

          ps.executeUpdate( );

2013년 8월 9일 금요일

[ORACLEJAVA커뮤니티,강좌,oracle char]Char와 VarChar2 Type의 비교분석, 오엔제이프로그래밍

Char, Varchar type비교

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  


A. CHAR Type

- 고정 길이 문자열을 저장한다. 사용자가 고정길이 보다 짧은 값을 저장하면 나머지 공
간은 Space로 체원진다.
- 1~255까지의 문자를 저장.
- 사용자가 후행 공백을 포함하여 고정길이 보다 큰 값을 입력하면 고정 길이에 맞게 값에서
공백이 잘린다.
- 값이 너무크면 Oracle Error발생
- 공백채움비교(blank-padded comparison semantics)를 사용한다.[비교문자열 둘다가
CHAR인경우]
a. 비교하는 두변수의 값이 길이가 다른 경우 짧은쪽을 공백으로 채운다는 것을 의미함

예) ‘a ‘ = ‘a’(우측의 갑은 1 Byte이므로 1 Byte를 공백으로 채워 2 Byte를 만든후 비교한다.)

- 데이타의 컬럼 길이가 짧고 거의 모든 데이타의 길이가 일정량을 넘어 확정된 크기에 대한 사용
비율이 높은 고정 길이인 경우 사용된다. 예를 들면 사번, 각 바이트가 의미가 있는 코드 등에
사용된다.

- 가변 길이로 지정할 경우 사이즈 증가로 인한 많은 체인 발생이 우려되는 경우
- 초기에는 데이타가 입력 되어 있지 않지만 일정 시간이 지나면 데이타가 입력 되어 지는 경우
- 오라클에서 권장하기는 CHAR보다는 VARCHAR2을 사용하는 것이 효과적임

B. VARCHAR2
- 가변길이 문자열을 저장한다. 1 ~2000 Byte 저장가능함.
- 최대 50자를 저장할수 있는 VARCHAR2 TYpe의변수에 10자를 저장한다면 실제 저장공간에 10자만을
저장한다.
- 공백채우지 않음 비교(non-padded comparison semantics)를 사용한다.[비교값 둘다 또는 한쪽
이라도 VARCHAR2 Type인 경우]

예)’a ‘ > ‘a’(우측의 값이 길이가 짧아도 공백으로 채우지 않으니까 왼쪽의 값이 큰 것은 당근)

- 처음 테이블 생성시 해당 블럭에 데이타 증분치를 고려하여 PCTFREE(디폴트 10)라는 파라메터를
지정하게 되는데 데이타 증분이 많이 발생하게 되면 이영역이 모두 소모 되어 체인이 발생하여
원하는 로우를 검색하고자 할때 필요없는 I/O를 발생 시킨다. 하지만 대개 테이블을 생성하게 되는
개발자는 테이블의 증분 가능성및 수치에 대해 예상하여 적절한 PCTFREE 값을 사전에 적절이
지정할 수 있을 뿐만 아니라, USER_TABLES라는 딕션널리 정보를 검색하여 발생한 체인 발생정도를
파악할 수 있다. 만일 심하게 체인이 발생할 경우 EXP/IMP 유틸리티를 이용하여 체인을 제거할
수 있으며 설령 약간의 체인이 존재할 경우라도 해당 테이블을 사용하는데 많은 제약이 되지 않는다.
또한 VARCHAR2 타입을 사용할때 DEFAULT라는 사용자 제약 조건에 의해 사전에 공간을 확보할 수 있다
- VARCHAR2 타입을 사용한다 할지라고 예견 못할 체인 발생에 대해 전혀 문제점이 없다는 것을
알수 있고, VARCHAR2 타입을 사용함으로서 보다 효과적으로 저장 공간을 이용할 수 있으며 이는
긍국적으로 수행 속도의 향상을 의미하게 된다.

------------------------------
적절한 문자 Data Type 선택방법
------------------------------
1. 비교의미 에서 ANSI 호환성이 필요한 경우 , 즉 후행공백이 중요하지 않으면 CHAR유형을
사용하고 중요하다면 VARCHAR2 Type을 사용한다.
2. 저장공간의 효율적 사용을 위해서는 VARCHAR2 Type을 사용한다.(char type 은 고정길이)
3.전체 테이블을 스캔할 경우 CHAR 형태로 저장된 테이블이 VARCHAR2 형태로 저장된 데이타 보다
많은 블럭 입출력을 발생시켜 속도가 느려질 수 있다. 반면 VARCHAR2 형태의 데이타가 증가 될때는
블럭 내 PCTFREE 영역을 사용하게 되고 만일 이 영역이 모자라는 경우 블럭 체인이 발생하여
원하는 데이타를 검색하고자 할 때 하나 이상의 블럭을 검색하게 되어 오히려 수행 속도에 악영향을
미칠 수 있다.

4.VARCHAR2 타입은 가능한 충분히 최대치를 부여하는 것이 효과적이다. 왜냐하면 실지 크기만
저장되지 컬럼 선언시 지정한 사이즈가 실지로 내부 블럭에 저장되지 않는다 따라서 되도록 큰
사이즈를 지정함으로서 길이 부족으로 인한 에러는 방지 할 수 있다. 흔히 현업에서 성명 타입의
사이즈를 결정할때 8 바이트 10바이트 12 바이트등 여러가지 논란이 있어 왔으나 오라클을
사용하는 경우 VARCHAR2 타입으로 넉넉히 확정하더라도 공간이용 측면에서 전혀 불이익이 없이
가변적인 성명(외국인 성명 포함) 길이를 수용할 수 있다.

5.CHAR 타입은 한 바이트라도 값이 들어간다면 지정된 크기 만큼 내부적으로 크기가 확정됨므로
가능한한 최소 길이로 확정하는 것이 효과적이다. 충분히 해당 크기를 예상할 수 있는 컬럼, 즉 사
번, 코드 등등 확정된 컬럼에만 지정하는 것이 효과적이다. 만일 매우 가변적인(컬럼내에 입력되는
데이타의 길이 편차가 클때) 경우 필요없는 공간 낭비를 가져올 수 있다는 사실을 명심해야 한다

[OracleJavaCommunity,오라클자바커뮤니티]이번 강좌에서는 자바에서의 main 메소드에 대해 자세히 알아 보도록 하겠습니다

이번 강좌에서는 자바에서의 main 메소드에 대해 자세히 알아 보도록 하겠습니다. main 앞에 왜 static이 붙으며 왜 public이 붙는지등에 관한 것을 공부해 보도록 하겠습니다. 잘 알아두시기 바랍니다.


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  



main 메소드의 특징 

메인 메소드는 JVM에 의해 자바 프로그램을 실행 할 때 처음 호출되는 메소드 입니다.
메인 메소드는 객체 생성을 위한 첫 실행 메소드 이다. 그러므로 어느 클래스에서 접근이 가능해야 하므로 public 이라는 접근 제어자를 사용 합니다.
해당 클래스로 부터 생성된 모든 객체에서 접근이 가능해야 한다. (static) --> static이라는 말이 붙으면 객체와 관련이 있는 것이 아니라 클래스와 관련이 있으며 초기화가 한번만 일어나며, 클래스가 실행되기 위해 메모리로 로딩되는 시점에 한번만 초기화가 일어 납니다. 즉 전역변수등에 사용되며...등등 [자바기초다지기#7]변수-인스턴스변수, 클래스변수 강좌에서 이미 공부 했던 부분 입니다.
Return 값을 가지지 않습니다.(void)
또한 실행 될 때 인자 값을 받아 들일 수 있습니다.

자바 인터프리터는 Java Application에 주어지는 각 명령형 인자들을 main(String[] args) 메소드에 매개변수로 넘겨 줍니다.
각 명령행 인자는 공백문자(whitespace)로 구분 하며, C/C++에서 메인 함수의 매개변수 개수를 나타내는 argc와 명령형 매개 변수 들을 문자열 배열로 받아 들이는 argv는 결국 Java의 args.length, args로 대체 될 수 있습니다.

[예제]

class ArgTest
{
public static void main (String[] args)
{
for(int i = 0; i < args.length; ++i) //이 프로그램을 실행할때 넘어 오는 아규멘트의 갯수 만큼 루프를 돕니다. >
System.out.println( "args[" + i + "] = " + args[i] );
}
}



[결과1]

java ArgTest test 100 이라고 실행시

args[0] = test
args[1] = 100


[결과2]

java ArgTest "test 100" 이라고 실행시

args[0] = test 100

2013년 8월 8일 목요일

[ORACLEJAVA COMMUNITY, ORACLEJAVANEW.KR]자바, 식별자,자료형,주석

이번 강좌 부터는 기본적인 자바의 문법을 공부해 보도록 하겠습니다. 쉬운것이니 천천히 읽고 실습하시기 바랍니다. 먼저 주석에 대해 보자구요~


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  




주석 (comment)
Line comment : //
Block comment :

식별자
변수, 메쏘드, 클래스, 패키지 이름을 정하는데 사용합니다.
유니코드 자바 문자 또는 유니코드 숫자
A-Z a-z _ $ 혹은 다양한 국가의 문자 사용 가능 합니다.
길이에 제한이 없으며, 대소문자 구분 합니다.
시작은 반드시 유니코드 자바 문자로 시작 해야 합니다.

[원칙]
대소문자 구별
클래스 및 인터페이스의 이름은 대문자로 시작
변수 및 메소드의 이름은 소문자로 시작
두 단어 이상으로 구성 시 각 단어의 시작은 대문자

리터럴 (Literals)
리터럴이란 원시타입, 스트링 타입, 널 타입을 나타내는 소스 코드를 의미 합니다.
Integer Literal, Floating Point Literal
Boolean Literal, Character Literal, String Literal
Null Literal

흔히 수식에서 사용하는 “34”라는 값을 프로그램 내에서 그대로 표현하는 것을 말합니다.
String s = "korea" --> 문자 리터럴
int i=10; --> 숫자 리터럴

자바에서의 자료형


기본자료형
기본 자료형(원시자료형)
byte : 8비트, 2의 보수 (-128 ~ 127)
short : 16비트 (-32768 ~ 32767)
char : 16비트, 유니코드 (0 ~ 65535)
int : 32비트 (-2147483648 ~ 2147483647)
long : 64비트 (-9223372036854775808 ~ 9223372036854775807)
float : 32비트
double : 64비트
boolean : true, false
종류
void 자료형(원시자료형) --> 아무런 값도 반환하지 않는 메소드 정의에 사용
참조형--> 객체의 참조 값을 나타내는 자료형(포인터와 유사)
배열 참조형,클래스 참조형,인터페이스 참조형
변수 --> 해당 자료형의 값을 기억할 수 있는 기억 장소
참고 : 닷넷에서는 자바의 기본자료형을 Value-Type, 참조형을 Reference-Type이라고 부릅니다.
[예제 -- 기본자료형과 참조형의 차이]
//기본자료형과 참조형의 차이
public class Sample1 {
static int a=10, b=10; //a와 b는 기본자료형 이다.(스택에 저장)
public static void main(String[] args) {
System.out.println("초기상태 : a="+a+", b="+b); //여기서는 각각 10으로 나온다.
a=1; //a를 1로...
b=a; //a의 값을 b로 복사해서 넣는다. 즉 b가 1이됨
a=2; //다시 a를 2로...
System.out.println("b="+b); //b는 1
Sample1 s1, s2; //s1과 s2는 객체 참조형으로 메모리힙에 있는 개체를 참조하고(쳐다보고) 있는 것이다.
s1 = new Sample1(); //메모리 힙에 Sample1의 인스턴스를 생성하고 s1이라는 변수가 처다보고 있슴...(포인터 변수 처럼)
s2 = s1; //s1이 쳐다보는 것을 s2도 쳐다 봄(s1이 실제 가지고 있는 값은 주소이다.. 그 주소를 s2에 넣은니 이제부터
//s1과 s2는 같은 곳을 쳐다 보고 있는 것이다. 그림으로 그려보라~
s1.a = 10; //s1에 있는 a라는 변수를 10으로 값을 바꾸었으니 당연히 s1의 a도 값이 바뀌어져 있는 것이다.
System.out.println("s2.a="+s2.a);
}
}

[결과]
초기상태 : a=0, b=0
b=1
s2.a=10



java.awt.Container(Abstract) , ORACLEJAVA 프로그래밍

java.awt.Container(Abstract) 


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  


java.lang.Object --> java.awt.Component --> java.awt.Container

자신의 영역안에 다른 Component를 포함할수 있는 Component

Container도 Component Class의 하위Class 이므로 그 자체도 Component로 취급되며 다른 Container에 부착될 수 있습니다.

일반적으로 GUI를 만들때는 Component를 Container에 배치하고, 그런 작은 Container를 더 큰 Container에 포함시켜서 GUI를 구성 합니다.

Frame과 Applet은 대표적인 최상위 Container이다. 최상위 Container란 다른 Container를 포함하여 맨 바깥쪽 Container로 사용되는 컨테이너를 지칭 합니다. 이에 비해 Panel은 다른 Container에 부착되어 일부 영역을 Control하는 경우에 사용 됩니다. Window는 많이 사용되지 않으며 하위 Class인 Frame이 많이 사용 됩니다.

Dialog와 FileDialog Container는 대화창에서 주로 사용 됩니다.

컴포넌트를 컨테이너에 추가할 때 색인이 지정되지 않을 경우, 목록 끝(즉, 스택 순서 아래)에 추가 됩니다.

Panel, ScollPane, Window의 상위 클래스


Window클래스나 Window 클래스의 파생클래스(Frame등)는 포함 할 수 없습니다.



Container – component 추가/제거/추출 메소드

add(Component) : 지정된 컴포넌트를 컨테이너의 끝에 추가 합니다.

add(Component, int) : 해당 위치에 있는 컨테이너에 지정된 컴포넌트를 추가 합니다.

add(Component, Object) : 지정된 컴포넌트를 컨테이너의 끝에 추가 합니다.

add(Component, Object, int) : 지정된 색인에서 지정된 제약 조건이 있는 컨테이너에 지정된 컴포넌트를 추가 합니다.

add(String, Component) : 컨테이너에 지정된 컴포넌트를 추가 합니다.

remove(Component) : 컨테이너에서 지정된 컴포넌트를 제거 합니다.

remove(int) : 컨테이너에서 index에 의해 지정된 컴포넌트를 제거 합니다.

remove() : 컨테이너에서 모든 컴포넌트를 제거합니다.

getcomponent(int) : 컨테이너에 있는 n번째 컴포넌트를 가져 옵니다.

getcomponentAt(int, int) : x,y 위치가 포함된 컴포넌트 위치를 찾습니다.

getcomponentAt(Point) : 지정된 지점이 포함된 컴포넌트를 가져 옵니다.

getcomponentCount() : 패널에 있는 컴포넌트의 수를 가져 옵니다.

getComponents() : 컴포넌트에 있는 모든 컴포넌트를 가져 옵니다.

isAncestorOf(Component) : 컨테이너의 컴포넌트 계층구조에 컴포넌트가 포함되어 있는지 확인 합니다.



Container – 그래픽/이벤트와 관련된 메소드

update(Graphics) : 컨테이너를 갱신 합니다.

paint(Graphics) : 컨테이너의 색상을 표시 합니다.

paintComponents(Graphics) : 컨테이너에 있는 각 컴포넌트의 색상을 표시 합니다.

print(Graphics) : 컨테이너를 인쇄합니다.

printComponents(Graphics) : 컨테이너의 각 컴포넌트를 인쇄 합니다.

addContainerListener(ContainerListener) : 컨테이너로부터 컨테이너 이벤트를 수신하기 위해 지정된 컨테이너 수신기(listener)를 추가 합니다.

processContainerEvent(ContainerEvent) : 등록된 ContainerListener 객체로 보내어 컨테이너에서 발생하는 컨테이너 이벤트를 처리 합니다.

processEvent(AWTEvent) : 컨테이너의 이벤트를 처리 합니다.

doLayout() : 컨테이너가 컴포넌트를 배치하도록 합니다.

getLayout() : 컨테이너의 배치 관리 프로그램을 가져 옵니다.

setLayout(LayoutManager) :컨테이너에 대한 배치 관리 프로그램을 설정 합니다.

validate() : 컨테이너와 모든 부속 컴포넌트를 확인합니다. 컨테이너와 하부 컴포넌트를 다시 배치 합니다.

invalidate() : 컨테이너와 모든 부속 컴포넌트가 다시 그려져야 한다고 표시 합니다.



Container – 기타 메소드

addNotify() : 컨테이너가 피어(peer)를 작성하도록 통지 합니다.

getAlignmentX() : x축을 따라 정렬 합니다.

getAlignmentY() : y축을 따라 정렬 합니다.

getInsets() : 컨테이너의 경계 크기를 표시하는 컨테이너의 인세트(inset)를 결정 합니다.

getMaximumSize() : 컨테이너의 최대 크기를 리턴 합니다.

getMinimumSize() : 컨테이너의 최소 크기를 리턴 합니다.

getPreferredSize() : 컨테이너의 선호 크기를 리턴 합니다.

invalidate() : 컨테이너를 무효로 합니다.

list(PrintStream, int) : 지정된 출력 스트림에 컨테이너 목록을 인쇄 합니다.

list(PrintWriter, int) : 지정된 들여쓰기 위치에서 시작하여 지정된 인쇄 작성자로 목록을 인쇄 합니다.

removeNotify() : 컨테이너와 모든 부속 컴포넌트가 피어를 제거하도록 통지 합니다.





------------------------------

java.awt.Panel

--------------------------

다른 Component나 그하위 Component들이 표시될수 있는 장소를 제공하나 , 스스로 화면에 그릴수는 업습니다.

자기를 스스로 그릴수 있는 다른 Window나 그하위의 Frame, Dialog 와 같은 Component에 포함시켜서 사용해야 합니다.

Panel Class에서만 제공하는 주요한 메소드 특별히 없습니다. 결국 다른 Component를 포함할수 있다는 점을 제외하면 Canvas와 별차이가 없다고 할수 있습니다.

Applet Class가 Panel Class를 상속합니다.

Applet은 브라우저창에서 실행되므로 자신을 그릴수 있는 기능을 제공하지 않는 Panel을 상속한다고 볼 수 있습니다.



[예제]

/* 프레임에 Panel을 올리는 예제 */
import java.awt.*;
public class PanelTest extends Frame{
public PanelTest(String s) {
super(s);
}
public static void main(String[] args) {
PanelTest f = new PanelTest("Frame에 Pamel을 넣는예제");
Panel p = new Panel();
f.setSize(300,300);
f.setLayout(null);
p.setSize(150,150);
p.setBackground(Color.blue);
f.add(p);
f.setVisible(true);
}

2013년 8월 2일 금요일

JAVA RandomAccessFile (자바 랜덤파일처리)

임의의 바이트, 텍스트등을 파일내 임의의 위치에 쓸수 있도록 허락
InputStream이나 OutputStream의 서브 클래스는 아니지만 파일의 읽기, 쓰기를 위한 독립적인 메소드를 제공한다. 


 오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의) 

length() : 파일의 길이 
getFilePointer() : 현재 포인터의 위치 
seek() : 포인터 위치 설정 
readBoolean(), readByte(),readChar(), readShort(), readLong(), readInt(), readFloat(),readDouble(), readLine(), readUTF() : 해당타입의 데이터 읽기 
writeBoolean(), writeByte(),writeChar(), writeShort(), writeLong(), writeInt(), writeFloat(), writeDouble(), writeUTF() : 해당타입의 데이터 쓰기 
close() : 파일 닫기 



import java.io.*; class RandomTest { public static void main(String[] args) throws IOException {      RandomAccessFile raf=new 
                            RandomAccessFile("test.txt","rw");      raf.seek(raf.length());      raf.writeUTF("The end");      raf.close(); } }



----------------
메모장 –  예제
----------------
import java.awt.*;
import java.awt.event.*;
import java.io.*;
class NotePad extends Frame implements ActionListener {
TextArea text = null;
String filename = null;

public NotePad(String title) {
    super(title); // set title
    MenuBar menuBar=new MenuBar();
    Menu fileMenu = new Menu("File");
    menuBar.add(fileMenu);
    MenuItem openItem = new MenuItem("Open...", new MenuShortcut('O'));
    openItem.setActionCommand("Open"); // for getActionCommand
    openItem.addActionListener(this);
    fileMenu.add(openItem);


    MenuItem saveItem = new MenuItem("Save", new MenuShortcut('S'));
    saveItem.setActionCommand("Save"); // for getActionCommand
    saveItem.addActionListener(this);
    fileMenu.add(saveItem);
    MenuItem saveasItem = new MenuItem("Save As...", new MenuShortcut('V'));
    saveasItem.setActionCommand("SaveAs"); // for getActionCommand
    saveasItem.addActionListener(this);
    fileMenu.add(saveasItem);
    fileMenu.addSeparator();
    MenuItem exitItem = new MenuItem("Exit", new MenuShortcut('X'));
    exitItem.setActionCommand("Exit"); // for getActionCommand
    exitItem.addActionListener(this);
    fileMenu.add(exitItem);
    setMenuBar(menuBar);
    text = new TextArea();   


    add(text, "Center");
    addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent we) {
            dispose();
            System.exit(0);
        }
    });
    setSize(500, 400);    setVisible(true);
}
public static void main(String args[]) throws Exception {
    new NotePad("Simple NotePad...");
}
public void actionPerformed(ActionEvent e) {
    String cmd=e.getActionCommand();
    if (cmd.equals("Exit"))
        System.exit(0);
    else if (cmd.equals("Open")) {
        FileDialog dialog=new FileDialog(this, "Text File Open", FileDialog.LOAD);
        dialog.show(); // file dialog is modal
        String filename=dialog.getFile();


      if (filename != null) {
            String directory=dialog.getDirectory();
            if (directory != null)
                filename=directory+filename;
            loadFile(filename);
        }
    }
    else if (cmd.equals("Save")) {
        if (this.filename != null) saveFile(this.filename);
        else {
            FileDialog dialog=new FileDialog(this, "Text File Save", FileDialog.SAVE);
            dialog.show(); // file dialog is modal
            String filename=dialog.getFile();
            if (filename != null) {
                String directory=dialog.getDirectory();
                if (directory != null)
                    filename=directory+filename;
                saveFile(filename);
            }
        }
    }


else if (cmd.equals("SaveAs")) {
        FileDialog dialog=new FileDialog(this, "Text File Save", FileDialog.SAVE);
        dialog.show(); // file dialog is modal
        String filename=dialog.getFile();
        if (filename != null) {
            String directory=dialog.getDirectory();
            if (directory != null)
                filename=directory+filename;
            saveFile(filename);
        }
    }
}


private void loadFile(String filename) {
    BufferedReader in = null; 
    text.setText("");

    try {
        in = new BufferedReader(new FileReader(filename),1024); 
        String string=null;


      while ((string=in.readLine()) != null) {  text.append(string+'\n');    }
        in.close();
    } 
    catch (IOException ie) {System.err.println("File Read Error : "+ie.getMessage()); }
    setTitle("FileName:"+filename);
    this.filename=filename;
}
private void saveFile(String filename) {
    BufferedWriter out = null; 
    try {
        out = new BufferedWriter(new FileWriter(filename));
      String string=text.getText();
        out.write(string); 
      out.close();
  }
    catch(IOException e) { System.err.println("File Read Error : "+e.getMessage()); }
    setTitle("FileName:"+filename);
    this.filename=filename;
}
}