2011년 6월 26일 일요일

자바 스윙(Java Swing)

자바 GUI(Graphic User Interface) 프로그래밍의 대표격인 스윙(Swing)에 대해서 오늘부터 단계적으로 다뤄보고자 한다. 자바를 공부하면서 숫자와 문자의 조합으로 결과가 나오는 것이 지루하고 따분하게 느껴졌다면 오늘 이 시간부터 여러분은 새로운 세계(?)에 흥미를 가질지도 모르겠다. 자바의 스윙은 프로그램 컴포넌트 셋으로서 GUI 컴포넌트인 버튼이나 스크롤바등을 여러 플랫폼에서 독립적으로 만들수 있는 기능을 제공한다. 너무 거창하게 설명했남? ㅎㅎ 한마디로 자바의 스윙(Swing)은 그래픽 구현하려고 JDK 개발툴에서 만든 자바 기반 클래스의 일부분이다.


자바의 스윙(Java Swing)은 자바 GUI로 기존에 쓰던 AWT(Abstract Window Toolkit)이라는게 있는데 여기서 쓰던 기본적인 시스템의 자원과 기능을 그대로 제공하며 여기서 더 나아가 표나 트리등의 복잡하고 더욱더 다양한 그래픽 컴포넌트를 사용하고 보완하기 위해 자바 개발툴인 JDK 1.2 버젼부터 도입되어 현재에 이르게 되었다. 다시 말하면 AWT의 부족한 부분을 채우기 위해 만들어졌다고 생각하면 된다. 따라서 필자는 AWT를 따로 강의하지 않고 신개념의 신기술인 자바의 스윙을 바로 들어가겠다. AWT 공부하다 지쳐서 정말 배워야하는 Swing을 배우기 전에 나가떨어지는 이들을 막기 위한 필자의 치밀한 강의전략(?)인 것이다.^^

방금 얘기한 자바 스윙(Java Swing)은 javax.swing.*; 패키지에 그리고 AWT는 java.awt.*; 패키지에 들어있다. 자바의 스윙을 공부할 것이므로 대부분 javax.swing 패키지를 이용할 것이나 부분적으로 필요할 경우 java.awt 패키지도 사용하도록 하겠다. 자 그럼 자바의 스윙에 들어가기에 앞서 기본적인 클래스 트리가 어떤 식으로 구성되어 있는지 살펴보도록 하겠다. 처음이라 와닿지 않을 것이나 언젠가(?) 여러분이 필요할때가 생겨날 것이다. 가벼운 마음으로 구경하기 바란다. 제발 쓸데없이 무조건 외우지 말아라. 쓰다보면 알게된다.ㅎㅎ


보다보면 특이한게 그냥 클래스 이름을 쓰면 될것이지 이상하게 앞에 J라는 대문자가 하나씩 더 들어간 것을 볼수 있을 것이다. 기존 AWT에서는 J가 없었으나 Swing이 생기면서 기존 툴과 구별하기 위해 J를 붙인것으로 알고있으면 된다. 오늘은 스윙을 이용해서 자바를 처음 배울때처럼 그래픽(?)을 구현하여 문자를 출력해보도록 하겠다. 기대하시라~ 쨔짜잔~ ㅎㅎ


여러분이 윈도우에서 여러 프로그램들을 사용할때 일반적으로 나오는 창이 위와 같은데 이것을 이제 자바로 만드는 것이다. 저거 일일이 어떻게 도형그리고 선긋고 만들지라고 생각하면서 앞서가는 이들이 있을지 모르겠는데 위에 보는 기본창은 자바에서 명령어 몇줄만 긁적이면 알아서 만들어주게끔 되어있으니 염려 푹 놓으시라.^^


위에서 보는 그림이 기본창에서 들어가는 대표적인 클래스들인데 오늘은 여기서 JFrame과 JLabel 그리고 Content Pane을 약간 사용하게 될것인데 아래 그림을 보면 해당 제목들이 이해가 더 잘될 것이다. 잘 안보이면 클릭해서 보자. 그림을 확대해서 친절(?)하게 보여준다.ㅎㅎ


그런데 암만봐도 필자가 무슨 말을 하고 있는지 어안이 벙벙한 이들도 있을 것이다. 그도 그럴것이 갑자기 자바로 그림 그리겠다고 하니 말이다. 그건 여러분의 탓이 아니니 염려하지 말자. 필자가 누구더냐? 이제까지 다 이해못했어도 전혀 문제될게 없다. 여러분의 모든 고민을 해결해줄 빵빵한 예제(?)가 아래에 기다리고 있으니 말이다.^^


오늘의 하이라이트(?)인 예제의 결과물이 위와 같다. 예전 같으면 시커먼 모니터 화면에 딸랑 주소 한줄만 출력되었겠지만 거기다가 껍데기(?)만 이쁘게 씌워놔도 뭔가 있는듯하다.ㅎㅎ 그럼 어떻게 위와같은 그래픽을 구현할수 있는지 예제 코드를 살펴보자.


자바 스윙을 시작하는 첫 시간이라 내용을 단순하게 만들기 위해 각고의 노력(?)을 기울인만큼 여러분도 그에 상응한 고통을 수반한 노력(?)을 치뤄야 할것이다.ㅎㅎ 농담이다. 가볍게 봐도 저절로 이해될 것이다. 간략하게 예제를 설명하자면 일단 JFrame과 JLabel 클래스를 쓰기 위해 javax.swing 패키지에서 import 하였고 해당 클래스 이용해서 프레임 만들고 레이블 만들고 프레임 제목 쓰고 사이즈 정하고 보이도록 세팅해준게 전부다. 예제에 대한 설명으로 쓴 주석이 자바 스윙의 첫 예제라 그런지 필자도 모르게 너무 과하게 써버려서 이해하는데 어려울건 없다고 본다.ㅎㅎ

엄밀히 말해서 자바의 스윙 콤포넌트들은 쓰레드에 안전하다고 장담할수 없다. 따라서 메인메소드에서 run( ) 메소드를 이용해 자바 스윙을 구현하는게 바람직하나 지금은 기술적으로 그렇구나라고 알고만 있자. 초반에는 스윙 대부분의 콤포넌트들이 lightweight를 지향하는 경량 프로그램인 것처럼 여러분도 가벼운 마음으로 워밍업한다 생각하고 열심히 스윙(?)을 연습하기 바란다.^^

2011년 6월 23일 목요일

자바의 입력과 출력(I/O Streams)


오늘은 자바의 기본적인 입출력 방법에 대해서 살펴보기로 하겠다. 강좌 초반에 맛배기로 자바의 입출력에 관해서 잠깐 공부한적이 있지만 보다 다양한 방법과 접근을 통해서 심층학습(?)을 해보고자 한다. 자바에서 파일 입출력 부분은 상당히 중요하다. 여러분이 어떤 프로그램을 만들던지간에 유저의 입력과 그와 관련해서 정보를 처리하고 출력하는 시스템은 아마 필수적으로 꼭 들어가는 부분 중 하나일텐데 이 부분에 대해서 자유자재로 대처하지 못한다면 프로그램 제작시 상당한 어려움에 처하는 일이 많을 것이다. 이번 강좌를 통해서 자바의 입출력에 관한한 가장 기본적인 스킬은 여러분이 쉽게 습득할수 있도록 필자가 최선을 다할 것이다. 여러분이 할일은 그저 본 강좌를 열심히 읽기만 하고 따라서 쳐보기만 하면 될것이다.^^


스트림(Stream)은 위의 그림에서 보다시피 데이터의 흐름을 거치는 과정이라 생각하면 된다. 데이터 타입은 우리가 오늘 배울 바이트나 캐릭터 같은 유용한 것들(?)이 스트림을 통해 입력 프로그램이나 아래 그림처럼 입력과 반대로 출력 프로그램도 스트림을 통해 한번에 하나씩 읽어들이면서 처리한다.


오늘은 파일 입출력 부분에서 가장 기초라 할수 있는 파일 카피에 대한 자바 소스를 만들어 보기로 하겠다. 일단 카피할 원본 파일이 있어야 할텐데 원본 파일명은 eminem.txt 라고 하고 안에다가 아래의 내용을 넣고 저장하기 바란다.ㅎㅎ

eminem.txt
====================
"Love The Way You Lie"

(feat. Rihanna)

[Chorus - Rihanna:]
Just gonna stand there and watch me burn
But that's alright because I like the way it hurts
Just gonna stand there and hear me cry
But that's alright because I love the way you lie
I love the way you lie

[Eminem]
I can't tell you what it really is
I can only tell you what it feels like
And right now it's a steel knife in my windpipe
I can't breathe but I still fight while I can fight
As long as the wrong feels right it's like I'm in flight
High off of love, drunk from my hate,
It's like I'm huffing paint and I love it the more I suffer, I suffocate
And right before I'm about to drown, she resuscitates me
She fucking hates me and I love it.
Wait! Where you going?
"I'm leaving you"
No you ain't. Come back we're running right back.
Here we go again
It's so insane cause when it's going good, it's going great
I'm Superman with the wind at his back, she's Lois Lane
But when it's bad it's awful, I feel so ashamed I snapped
Who's that dude? I don't even know his name
I laid hands on her, I'll never stoop so low again
I guess I don't know my own strength

[Chorus - Rihanna:]
Just gonna stand there and watch me burn
But that's alright because I like the way it hurts
Just gonna stand there and hear me cry
But that's alright because I love the way you lie
I love the way you lie
I love the way you lie

[Eminem]
You ever love somebody so much you can barely breathe
When you're with 'em
You meet and neither one of you even know what hit 'em
Got that warm fuzzy feeling
Yeah, them chills you used to get 'em
Now you're getting fucking sick of looking at 'em
You swore you'd never hit 'em; never do nothing to hurt 'em
Now you're in each other's face spewing venom in your words when you spit them
You push, pull each other's hair, scratch, claw, hit 'em
Throw 'em down, pin 'em
So lost in the moments when you're in them
It's the rage that took over it controls you both
So they say you're best to go your separate ways
Guess if they don't know you 'cause today that was yesterday
Yesterday is over, it's a different day
Sound like broken records playing over but you promised her
Next time you show restraint
You don't get another chance
Life is no Nintendo game
But you lied again
Now you get to watch her leave out the window
Guess that's why they call it window pane

[Chorus - Rihanna:]
Just gonna stand there and watch me burn
But that's alright because I like the way it hurts
Just gonna stand there and hear me cry
But that's alright because I love the way you lie
I love the way you lie
I love the way you lie

[Eminem]
Now I know we said things, did things that we didn't mean
And we fall back into the same patterns, same routine
But your temper's just as bad as mine is
You're the same as me
But when it comes to love you're just as blinded
Baby, please come back
It wasn't you, baby it was me
Maybe our relationship isn't as crazy as it seems
Maybe that's what happens when a tornado meets a volcano
All I know is I love you too much to walk away though
Come inside, pick up your bags off the sidewalk
Don't you hear sincerity in my voice when I talk
I told you this is my fault
Look me in the eyeball
Next time I'm pissed, I'll aim my fist at the drywall
Next time. There won't be no next time
I apologize even though I know its lies
I'm tired of the games I just want her back
I know I'm a liar
If she ever tries to fucking leave again
Im'a tie her to the bed and set this house on fire
I'm just gonna

[Chorus - Rihanna:]
Just gonna stand there and watch me burn
But that's alright because I like the way it hurts
Just gonna stand there and hear me cry
But that's alright because I love the way you lie
I love the way you lie
I love the way you lie
====================

명곡(?)이라서 그런지 생각보다 가사가 조금 길다.^^ 여러분이 오늘 배울 자바소스(Test66.java) 파일과 같은 폴더에 위의 eminem.txt 파일을 넣고 실행하면 정상적으로 작동될 것이다. 그럼 예제를 보면서 차근차근 프로그램에 대해서 풀어가겠다.


프로그램이 아주 명확하므로 주석을 달진 않았지만 이해를 돕기 위해 간략하게 설명해 보겠다. 우리의 미션(?)은 eminem.txt 파일안의 내용을 lovethewayyoulie.txt 라는 파일에다가 그대로 카피하는게 주임무이다. 아는 사람은 알겠지만 에미넘(Eminem)의 Love the way you lie 라는 노래 가사를 카피하는 자바 소스다. 에미넘이란 이 친구(?)를 모르는 이들은 이번 기회에 꼭 한번 들어보기 바란다.ㅎㅎ

오늘 쓰일 자바의 파일 입출력을 담당하는 스트림은 FileInputStream과 FileOutputStream이므로 이를 이용하기 위해 import 하였다. 그리고 이에 대한 예외처리를 하기위해 IOException을 또한 불러들였다. 메인메소드를 보면 파일인풋스트림의 인자로 input을 파일아웃풋스트림의 인자로 output을 쓰고 소스를 읽어들이는 파일을 eminem.txt에서 읽도록 FileInputStream을 이용해 객체생성을 한후 input으로 건네주었고 마찬가지로 출력하는 파일로는lovethewayyoulie.txt로 만들라고 FileOutputStream을 통해 객체생성을 하고 output으로 넘겨주었다. 출력파일(lovethewayyoulie.txt)이 없을 경우 자동으로 생성되며 있을 경우 다시 덮어씌워버리니 출력 부분은 신경쓰지 않아도 된다.

int a; 라는 명령문이 나오는데 이게 뭔지 의아해할지도 모르겠다. while문을 보면 a가 input.read( )라는 구문을 받고 있는데 FileInputStream의 read( ) 메소드의 리턴값이 int 이므로 이렇게 받는다. 쉽게 설명하자면 바이트로 즉 컴퓨터에서는 그냥 정수로 문자들을 읽어내는데 각 글자마다 고유의 숫자가 있다. 이를 읽고 파일의 내용이 다 끝났으면 -1 이라는 정수값을 리턴하므로 while 구문이 파일 내용이 끝날때까지 읽게 만들려고 조건식이 위와같이 되는 것이다. 그리고 읽은 값을 output 즉 우리가 지정한 출력파일에다가 한번에 하나씩 카피하게 된다.


글자마다 갖고 있는 고유의 값이 뭐지? 라고 궁금해하는 이들은 아래의 표를 보기 바란다. 우리가 일반적으로 쓰는 알파벳이나 그밖의 기호들은 각기 고유한 숫자 체계를 가지고 있는데 우리가 사용하는 컴퓨터는 바로 이를 기호화하여 처리하므로 문자들을 읽을수 있는 것이다.


위에서 보는 이런 문자 체계를 우리는 아스키 코드(ASCII code)라고 부른다. 아마 컴퓨터를 사용하면서 아니면 키보드를 두드리면서 한번쯤은 들어봤음직한 용어일 것이다. 이런 표를 보면 그냥 외워야되는 것인줄 알고 무작정 암기하는데 제발 그러지말고 그냥 복사해서 필요할때마다 옆에두고 쓰자. 강이의 자바강좌 회원들은 보다 현명(?)하게 이런 상황들을 넘기기 바란다.ㅎㅎ

마지막에 있는 finally 구문은 예외가 생기던 안생기던 항상 처리되는데 try 예외구문을 받는 명령으로 파일을 오픈하고 썼으면 만일에 있을지 모르는 오작동(?)을 방지하기 위해 파일을 닫아주라는 명령이다. 예외구문에 대해서 기억이 잘 안나는 이들은 예전 강좌를 뒤적거려서 보고오기 바란다. 위의 예제를 실행하면 아래와 같은 결과를 얻게 될것이다.

34
76
111
118
101
32
84
104
101
32
..
...

왜 이렇게 되는지는 필자가 족보(?)인 아스키 코드를 여러분에게 주었으니 eminem.txt안의 파일내용과 대조해보면서 왜 이런 숫자들이 찍히는지 연구해보기 바란다. 여러분이 공부하기 쉽도록 출력스트림에서 바이트를 문자로 전환하기 전에 화면에 바이트로된 숫자를 출력하라고 만들어 놓은 것이다. 그리고 예제를 실행했으면 lovethewayyoulie.txt라는 파일이 같은 폴더안에 생성되었을 것인데 잘 카피되었는지 확인해보면서 공부하기 바란다.

java.io 패키지에서 우리가 방금 이용한 FileInputStream 대신에 FileReader를 FileOutputStream 대신에 FileWriter를 쓰고 똑같은 방법으로 위와같은 결과를 도출해낼수 있다. 다른말로 하면 FileReader는 FileInputStream을 FileWriter는 FileOutputStream을 상속받기 때문에 그러하다.

느꼈을지 모르겠지만 위의 프로그램은 뭔가 아쉬운 점이 많다. 한글자 한글자씩 읽어서 옮기는데 이건 너무 답답하지 않은가? 그래서 문장을 한줄씩 읽는 방식이 보편적으로 쓰인다. 이미 예전에 필자가 선보인 방식(?)이니 특별한 설명은 따로 하지 않겠다.ㅎㅎ 그래도 궁금해하는 이들을 위해 예제를 아래와 같이 올리니 뚫어지게 보면서 공부하기 바란다.^^


실행하고 보면 알겠지만 출력결과에서 보듯이 readLine( ) 메소드를 통해 문장을 한줄씩 읽어들이면서 명령을 처리한다. BufferedReader와 PrintWriter 클래스로 이와같이 부드러운 처리가 가능해진다. 차근차근 예제를 공부하면서 오늘 배운건 꼭 여러분의 것으로 만들기 바란다.^^