<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet href="http://rss.egloos.com/style/blog.xsl" type="text/xsl" media="screen"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
	<title>만성피로님의 이글루</title>
	<link>http://maydaisy.egloos.com</link>
	<description>-_-v</description>
	<language>ko</language>
	<pubDate>Tue, 10 Feb 2009 10:32:53 GMT</pubDate>
	<generator>Egloos</generator>
	<image>
		<title>만성피로님의 이글루</title>
		<url>http://pds8.egloos.com/logo/200803/06/62/f0018062.jpg</url>
		<link>http://maydaisy.egloos.com</link>
		<width>80</width>
		<height>69</height>
		<description>-_-v</description>
	</image>
  	<item>
		<title><![CDATA[ 블로그 이사 했어요 ~ ]]> </title>
		<link>http://maydaisy.egloos.com/1299430</link>
		<guid>http://maydaisy.egloos.com/1299430</guid>
		<description>
			<![CDATA[ 
  만성피로가 블로그를 이사 했습니다.<br><br>이글루스를 사용하다가 티스토리로 이사를 -_-;;;<br><br>이사한 김에 자바 기초를 다시 리뷰하면서 글을 작성하고 있습니다.<br><br>블로그 주소<br><br><a href="http://maydaisy.tistory.com/">http://maydaisy.tistory.com/</a><br><br>감사합니다.			 ]]> 
		</description>

		<comments>http://maydaisy.egloos.com/1299430#comments</comments>
		<pubDate>Tue, 10 Feb 2009 10:32:53 GMT</pubDate>
		<dc:creator>만성피로</dc:creator>
	</item>
	<item>
		<title><![CDATA[ 파일 업데이트 사용에 대한 고민. ]]> </title>
		<link>http://maydaisy.egloos.com/1173652</link>
		<guid>http://maydaisy.egloos.com/1173652</guid>
		<description>
			<![CDATA[ 
  지난 번 DB 이용 방법에 대해서 약간의 고민을 했던 것과 비슷하게 파일 업데이트에 대한 것을 잠시 고민하고자 짧은 글이지만 핵심적인 이야기를 하고자 합니다.<br><br>파일을 업데이트 하는 방식 중 <br><br>첫번째로&nbsp;서버쪽 파일과 클라이언트 쪽 파일을 비교해서 최종 수정 시간이 언제인가를 확인 한 뒤에 서버 쪽이 더 최신의 수정 시간을 갖고 있을 경우 업데이트를 하는 방식.<br><br>두번째로 파일의 크기를 비교해서 서버쪽과 클라이언트 쪽의 파일 크기가 다르다면 업데이트 하는 방식.<br><br>마지막으로 클라이언트의 버전 정보를 서버쪽에 전송 받아서 버전이 구 버전인지 확인을 한 뒤 파일을 업데이트 하는 방식.<br><br>이렇게 3가지 방식을 두고 고민을 하고 있습니다.<br><br><br>일반적으로 게임에서 많이 볼 수 있는 파일 업데이트 방식은 두번쨰 방식을 주로 이용하는 것으로 알고 있는데 과연 두번째 방법이 좋은 것인지에 대해서는 확실히 알수는 없다고 생각 되는 부분이 존재합니다.<br><br>만약 클라이언트 쪽에서 바이너리 편집기를 이용해서 파일의 내용을 수정한다면 파일의 사이즈는 변화가 없기 때문에 서버 입장에서는 전혀 문제가 없다고 판정을 내린다는 점과&nbsp;이 문제를 해결하고자 클라이언트의 파일들을 서버가 일일이&nbsp;내용까지 확인한다는 것은 서버 입장으로는 무리수를 두는 시스템이라고 생각되는 부분입니다.<br><br>그리고 첫번째 방법은 단순히 파일의 최신 업데이트 날짜 비교가 아니여도 서버쪽에 파일 수정 시각과 클라이언트 쪽에 파일 수정 시각이 다를 경우에 업데이트를 한다고 약간 바꿔서 생각 한다면 편리할 것이라고 생각 되나.. 파일의 수정 시각은 클라이언트 쪽에서 위조가 가능 하다는 것으로 알고 있는 부분입니다.<br><br>마지막으로는 클라이언트 쪽에 버전 정보 역시 첫번째 방법과는 크게 다르지는 않을 것으로 보인다는 점.. 쉽게 가는 프로그래밍 이라면 물론 3번이 가장 속 편한 해결책이라 보입니다.<br><br>3 가지 방법 그 어느것도 장단점은 존재 한다고 봅니다. <br>과연 어떤 것을 이용하는 것이 좋을까요?<br>(이미 마음은 기울어졌지만...-_-;;)<br><br>아 그리고 3가지 방법 모두 다 객체스트림을 이용한 방법으로 구현할 계획입니다. ^^;<br><br/><br/>tag : <a href="/tag/java" rel="tag">java</a>,&nbsp;<a href="/tag/자바" rel="tag">자바</a>,&nbsp;<a href="/tag/파일업데이트" rel="tag">파일업데이트</a>,&nbsp;<a href="/tag/프로젝트" rel="tag">프로젝트</a>			 ]]> 
		</description>
		<category>정리할 자료들</category>
		<category>java</category>
		<category>자바</category>
		<category>파일업데이트</category>
		<category>프로젝트</category>

		<comments>http://maydaisy.egloos.com/1173652#comments</comments>
		<pubDate>Mon, 24 Nov 2008 15:37:46 GMT</pubDate>
		<dc:creator>만성피로</dc:creator>
	</item>
	<item>
		<title><![CDATA[ 객체를 저장하고 읽어보자. ]]> </title>
		<link>http://maydaisy.egloos.com/1172498</link>
		<guid>http://maydaisy.egloos.com/1172498</guid>
		<description>
			<![CDATA[ 
  <p>이번 글에서는 객체를 저장하고 로드하는 것에 대해서 이야기 하도록 하겠습니다.<br><br>이 이야기를 하기 전에 우리가 java.io 패키지를 사용 했던 것을 잠시 생각해 봅시다.<br><br>가장 처음에서는 문자 스트림을 이용한 예지를 가지고 공부 했었습니다.<br>주로 키보드 입력 받아들이기, 텍스트 파일 읽기/쓰기 입니다.<br><br>그리고 이후에 했던 것은 바이트스트림을 이용했습니다.<br>텍스트 파일이 아닌 바이너리 파일을 복사 또는 텍스트 파일을 바이트스트림을 이용해서 읽기 및 쓰기도 했었습니다.<br><br>마지막으로는 네트워크 프로그래밍 때 이용을 했었습니다.<br>네트워크 프로그래밍에서는 문자/바이트 스트림을 적절하게 이용하면 모두 이용할 수 있다는 것은 알고 있을 거라 생각됩니다.<br><br>그럼 이제 본론으로 돌아와 객체 입출력 이야기를&nbsp;하도록 하겠습니다.<br><br>일단 객체를 가지고 입출력을 하기 이전에 문자스트림도 객체를 이용한 입출력이 아닐까 하는 생각을 할 수 있습니다.<br>문자열을 이용하려면 String 클래스의 레퍼런스 변수를 이용해야 했기 때문이죠.<br><br>그럼 이 부분에 대해서 조금 더 알아보고 넘어가도록 합시다.<br><br>객체를 입출력 하기 위해서는 가장 먼저 해당 <strong><span style="COLOR: #ff0000">객체의 클래스가 Serializable 인터페이스를&nbsp;구현</span></strong>해야 객체 입출력을 할 수 있는 가장 기본 조건이 만들어 집니다.(이 인터페이스는 추상메소드가 없기 때문에 implements를 하는 것 자체가&nbsp;구현이 되는 약간의 특이한 인터페이스라고 볼수 있습니다.)<br><br>그럼 String 클래스는 Serializable&nbsp;인터페이스를 구현 했을까요?<br>API를 확인 해 보면 구현 하고 있는 것을 쉽게 확인이 가능합니다.<br>그리고 실제 String 클래스의 소스 파일에서도 구현을 하고 있다는 것을 쉽게 확인이 가능합니다.</p><p class="바탕글"><table style="BORDER-BOTTOM: #000000 0.28pt solid; BORDER-LEFT: #000000 0.28pt solid; BORDER-COLLAPSE: collapse; BORDER-TOP: #000000 0.28pt solid; BORDER-RIGHT: #000000 0.28pt solid"><tbody><tr><td style="BORDER-BOTTOM: #000000 0.28pt solid; BORDER-LEFT: #000000 0.28pt solid; WIDTH: 419.54pt; HEIGHT: 2.82pt; BORDER-TOP: #000000 0.28pt solid; BORDER-RIGHT: #000000 0.28pt solid" valign="center"><p class="바탕글">String 클래스의 일부 소스</p></td></tr><tr><td style="BORDER-BOTTOM: #000000 0.28pt solid; BORDER-LEFT: #000000 0.28pt solid; WIDTH: 419.54pt; HEIGHT: 2.82pt; BORDER-TOP: #000000 0.28pt solid; BORDER-RIGHT: #000000 0.28pt solid" valign="center"><p class="바탕글">public final class String</p><p class="바탕글"><span style="COLOR: #ff0000" lang="EN-US">implements java.io.Serializable</span>, Comparable&lt;String&gt;, CharSequence</p><p class="바탕글">{</p><p class="바탕글">/** The value is used for character storage. */</p><p class="바탕글">...</p></td></tr></tbody></table></p><p><br>그래서 객체입출력을 모르는 상태에서도 문자스트림을 이용하는데 전혀 문제가 없었습니다. 그렇지만 문자스트림을 객체입출력이라 보는 것은 좀 어렵다고 생각 됩니다. File 클래스 또한 Serializable 인터페이스를 구현 하고 있고 각각의 입출력을 하기 위한 문자/바이트 스트림 구조가 완성 돼 있기 때문입니다. <br><br>이 점에 대해서 대충 정리를 하자면&nbsp;이런 식으로 걸고 넘어진다면&nbsp;각각의 객체의 특징을 모호하게 만든다고 해야 할까요? ㅎㅎ<br>자바에서는 모든 클래스들은 Object의 자손들인데 여기서 부터 걸고 넘어져야 겠지요.. ㅎㅎ<br><br>그럼 객체 입출력을 위한 준비물 클래스를 소개 하도록 하겠습니다.<br>1. 위에서도 언급을 했던 Serializable 인터페이스를 구현 하는 클래스가 필요합니다.<br>2. 입출력을 위해서 ObjectInputStream, ObjectOutputStream 클래스가 필요합니다.<br>3. 문자/바이트 스트림 떄 처럼 Buffered..들을 이용할 수 있으므로 조건적으로 필요할 수 있는 부분입니다.<br><br>위에 준비물을 이용해서 우리가 기초적으로 했었던 입출력 예제와 동일하게 이용하면 됩니다.<br><br>클래스 사용 예)<br>ObjectOutputStream oos = new ObjectOutputStream(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new BufferedOutputStream(new FileOutputStream("data")));<br>ObjectInputStream ois = new ObjectInputStream(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new BufferedInputStream(new FileInputStream("data")));<br><br>여기 까지는 확실히 익숙한 소스라는 것을 쉽게 확인이 가능합니다.<br>그럼 다음으로..<br><br>이들을 저장 할 떄는 writeObject(객체명); 읽을 때는 readObject(); 메소드를 사용 하면 손쉽게 이용할 수 있습니다.<br>그런데 여기서 한가지 문제가 발생 되는 것이 존재합니다. 바로 오브젝트로 쓰고 오브젝트로 읽는 다는 점입니다. <br><br>객체를 저장 할 떄는 오브젝트 클래스로 저장 하지만 실제 파일은 바이너리 파일이므로 문제가 없습니다.<br>(위에서 확인을 해보면 바이트스트림을 이용한 것을 알 수 있습니다.)<br><br>그러나 파일을 읽을 때는 오브젝트 클래스로 읽어 들이는데&nbsp;'오브젝트 클래스로 읽은 데이터를 어떻게 처리 할 것인가?'에서 문제를 발생 시키게 되는 것입니다.<br><br>SaveData 클래스의 객체를 저장 했다면 다시 SaveData 객체에 넣어줘야 하는 것이지요. 어떻게 해결 해야 할까요?<br>답은 간단합니다. 오브젝트 클래스로 읽어들였으면 SaveData 클래스로 캐스팅을 해주면 됩니다.<br><br>이점에 대해서는 Vector 클래스를 이용 할 때와 비슷하다고 생각하면 이해하는데 도움이 될 것입니다.<br><br>그럼 전체 소스를 보도록 합시다.<br><br>import java.io.*;<br>// 입출력에 사용 될 클래스<br>class SaveData implements Serializable {<br><br>//&nbsp;맴버변수<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private String name;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private String url;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int j;</p><p><br>// 기본 생성자<br>&nbsp;public SaveData() {<br>&nbsp;&nbsp;this.name = "만성피로";<br>&nbsp;&nbsp;this.url = "<a href="http://maydaisy.egloos.com/">http://maydaisy.egloos.com/</a>";<br>&nbsp;&nbsp;this.i = 100;<br>&nbsp;&nbsp;this.j = 1000;<br>&nbsp;}<br><br>// 오버로딩을 이용한 또 다른 생성자</p><p>&nbsp;public SaveData(String name, String url, int i, int j) {<br>&nbsp;&nbsp;this.name = name;<br>&nbsp;&nbsp;this.url = url;<br>&nbsp;&nbsp;this.i = i;<br>&nbsp;&nbsp;this.j = j;<br>&nbsp;}<br><br>// 출력 메소드</p><p>&nbsp;public void print() {<br>&nbsp;&nbsp;System.out.println(this.name);<br>&nbsp;&nbsp;System.out.println(this.url);<br>&nbsp;&nbsp;System.out.println(this.i);<br>&nbsp;&nbsp;System.out.println(this.j+"\n");<br>&nbsp;}<br>}<br><br>// 메인 클래스<br>public class ObjectTest {<br><br>// 메인 메소드</p><p>&nbsp;public static void main(String[] args) {<br>&nbsp;&nbsp;SaveData[] data = new SaveData[2];<br>&nbsp;&nbsp;SaveData[] open = new SaveData[2];<br><br>// 각 객체에는 다른 생성자를 이용해서 객체에 연결해준다.</p><p>&nbsp;&nbsp;data[0] = new SaveData();<br>&nbsp;&nbsp;data[1] = new SaveData("인사불성", "???", 10, 20);<br></p><p>&nbsp;&nbsp;try {<br>// 객체를 저장한다.<br>&nbsp;&nbsp;&nbsp;ObjectOutputStream oos = new ObjectOutputStream(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new BufferedOutputStream(new FileOutputStream("data")));<br>&nbsp;&nbsp;&nbsp;oos.writeObject(data);<br>&nbsp;&nbsp;&nbsp;oos.flush();<br>&nbsp;&nbsp;&nbsp;oos.close();<br>&nbsp;&nbsp;&nbsp;<br>//&nbsp;저장 파일을 객체로 읽는다.<br>&nbsp;&nbsp;&nbsp;ObjectInputStream ois = new ObjectInputStream(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new BufferedInputStream(new FileInputStream("data")));<br><br>// 읽어들인 객체는 오브젝트 형이므로 캐스팅을 해줘야 한다.<br>&nbsp;&nbsp;&nbsp;open = (SaveData[])ois.readObject();<br>&nbsp;&nbsp;&nbsp;ois.close();<br>&nbsp;&nbsp;} catch (Exception e) {<br>&nbsp;&nbsp;&nbsp;e.printStackTrace();<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;<br>// 배열객체의 내용을 확인한다.<br>&nbsp;&nbsp;for(int i=0;i&lt;open.length;i++){<br>&nbsp;&nbsp;&nbsp;open[i].print();<br>&nbsp;&nbsp;}<br>&nbsp;}<br>}<br><br>위와 같은 예제를 이용해서 객체를 저장 한 경우에 이 파일을 텍스트 파일로 읽으면 문자 깨짐 현상이 일어납니다. 당연히 바이너리 파일이기 때문이지요. 그러나 이 파일을 바이너리 코드 편집기를 통해서 열기를 해보면 잼있는 현상을 볼 수 있습니다.<br><br>그 예로 위에서 data[0] 객체에 int 형 변수 i에 1000 이라는 숫자를 넣어서 저장을 했습니다. 이것을 바이너리 편집기를 이용해서 열어보면..<br><div style="text-align:center"><img class="image_mid" border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds11.egloos.com/pds/200811/24/62/f0018062_492aa1150746f.jpg" width="500" height="117.346938776" onclick="Control.Modal.openDialog(this, event, 'http://pds11.egloos.com/pds/200811/24/62/f0018062_492aa1150746f.jpg');" /></div></p>16진 코드 사이에서 10진수 1000이 16진수로 저장 된 것을 발견 할 수 있습니다. 03 E8 부분이 10진수 1000이 되는 부분이지요.<br><br>이 부분을 수정해서 저장 한다면 당연히 객체를 읽어 오기만 하는 소스를 짜서 파일을 바이너리 편집기로 수정 한 뒤 읽어 들이면 값이 변화된 것을 확인 할 수 있습니다.<br><br>이 부분은 게임 세이브 파일을 해킹해서 수정해본 사람이라면 쉽게 이해가 될 것이라고 봅니다.<br>(파일에 코드가 뒤집힌 경우는 암호화 기법을 이용해서 마지막에 체크썸 코드를 넣는 방식을 취한 경우가 대부분일 겁니다.)<br><br>이 점을 생각해 일반적으로 게임에서 세이브를 하는 방식은 객체를 저장하는 방식을 취한다는 것을 예상 할 수 있습니다. 저 또한 그렇게 이용할 것이라고 생각하고 있답니다.<br><br>그럼 이번 글은 여기서 마치도록 하겠습니다.<br><br>개인적으로 조금 흥미를 유발하는 부분이 많아서 생각 했던 것보다 내용이 좀 길어졌네요 ^^;;<br><br>그럼 다음에 또 만나요 ~<br/><br/>tag : <a href="/tag/java" rel="tag">java</a>,&nbsp;<a href="/tag/ObjectInputStream" rel="tag">ObjectInputStream</a>,&nbsp;<a href="/tag/ObjectOutputStream" rel="tag">ObjectOutputStream</a>,&nbsp;<a href="/tag/객체입출력" rel="tag">객체입출력</a>,&nbsp;<a href="/tag/세이브" rel="tag">세이브</a>,&nbsp;<a href="/tag/로드" rel="tag">로드</a>,&nbsp;<a href="/tag/자바" rel="tag">자바</a>,&nbsp;<a href="/tag/오브젝트" rel="tag">오브젝트</a>			 ]]> 
		</description>
		<category>정리할 자료들</category>
		<category>java</category>
		<category>ObjectInputStream</category>
		<category>ObjectOutputStream</category>
		<category>객체입출력</category>
		<category>세이브</category>
		<category>로드</category>
		<category>자바</category>
		<category>오브젝트</category>

		<comments>http://maydaisy.egloos.com/1172498#comments</comments>
		<pubDate>Mon, 24 Nov 2008 12:51:30 GMT</pubDate>
		<dc:creator>만성피로</dc:creator>
	</item>
	<item>
		<title><![CDATA[ 화이트 보드 만들기 예제. ]]> </title>
		<link>http://maydaisy.egloos.com/1145156</link>
		<guid>http://maydaisy.egloos.com/1145156</guid>
		<description>
			<![CDATA[ 
  이번 글에서는 화이트보드를 만들어 보도록 하겠습니다.<br><br>그림은 보통 하얀색 도화지에 연필을 이용해서 그림을 그리게 됩니다.<br>이것을 자바로&nbsp;만들어야 한다면&nbsp;도화지와 연필을 만들어야 합니다.<br>## 혹시나 해서 씁니다. Canvas를 떠올리지 않는 편이 좋습니다. 혼란에 빠지지 마시길 ㅎㅎㅎ...<br><br>도화지는 화이트보드 클래스가 될 것이고, 연필은 펜 클래스가 될 것입니다.<br>설계한&nbsp;방식에 따라 다르지만 여기서 펜 클래스는&nbsp;펜의 객체&nbsp;자체가 그림을 그리는 것은 아닙니다.<br>펜 클래스는 현재 그릴 그림이 사각형인지, 삼각형인지를 설정하게 되는 클래스 입니다.<br><br>잠깐 다른 것을 예로 들자면..<br>학생 정보를 담고 있는 Student 라는 클래스가 존재합니다. 이 안에는 각 학생에 대한 정보를 담을 수 있는<br>이름, 학번, 성적 필드가 존재하겠지요. 이와 마찬가지 입니다. 펜은 사각형 펜, 삼각형 펜 등이 될 수 있는 것 입니다.<br><br>가장 대표적인 클래스 두개를 이야기 했으니 만들어야 할 화이트보드의 인터페이스를 보도록 합시다.<br><div style="text-align:center"><img class="image_mid" border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds10.egloos.com/pds/200811/20/62/f0018062_4925012b2b694.jpg" width="500" height="500" onclick="Control.Modal.openDialog(this, event, 'http://pds10.egloos.com/pds/200811/20/62/f0018062_4925012b2b694.jpg');" /></div>위에 그림을 보면 좌측에는 8개의 버튼이 존재하고 가운데는 도화지에 해당하는 공란이 있습니다.<br><br>좀더 자세하게 설명을 하면<br>좌측에 버튼들은 하나의 패널 안에 GridLayout를 이용해서 배치 한 뒤 메인프레임에 적용 된 것이고,<br>가운데 공란은 보기에는 공란이지만 프레임에 Canvas를 적용한 것 입니다.<br><br>그럼 본격적으로 요구조건을 나열하겠습니다.<br><br>1차 요구조건<br>Pen 클래스<br>- 펜의 타입을 설정하는 int type를 맴버변수로 갖고 있다.<br>- 펜을 설정하는 setType, 설정을 리턴하는 getType 변수를 갖고 있다.<br><br>MyWhiteBoard 클래스<br>- 프레임을 상속한다.<br>- Pen 클래스의 객체를 맴버변수로 갖고 있다.<br>- MenuPanel&nbsp;클래스의 객체를 맴버변수로 갖고 있다.<br>- MyCanvas&nbsp;클래스의 객체를 맴버변수로 갖고 있다.<br>- 프레임 크기는 가로, 세로 500 전후 또는 임의로 설정한다.<br>- 실행 시 프레임은 윈도우 화면 정 중앙에 출력된다.<br>- 좌측에는 MenuPanel 클래스의 객체가 배치돼야 한다.<br>- 가운데는 MyCanvas 클래스의 객체가 배치돼야 한다.<br>- 프로그램 종료 이벤트를 적용한다.<br><br>--- 아래의 클래스들은 내부 클래스로 구현 한다.--------------<br>MenuPanel 클래스<br>- Panel 클래스를 상속한다.<br>- GridLayout를 이용해서 버튼을 배치한다.<br><br>MyCanvas 클래스<br>- Canvas 클래스를 상속한다.<br>- 마우스에 좌표를 기억할 xp, yp, xr, yr 맴버변수를 갖고 있다.<br>- 마우스가&nbsp;눌러질 될 때와 떼어질 때 좌표를 기억하도록 하는 이벤트를 만든다.<br>- MouseListenet 인터페이스 또는 MouseAdapter 클래스를 이용하여 마우스 이벤트를 구현한다.<br>##&nbsp;이벤트가 캔버스에 직접&nbsp;그림을 그리는것은 아니다. 이벤트는 좌표를 기억하는 용도로 구현한다.<br><br>MenuListener 클래스<br>- ActionListener 인터페이스를 구현한다.<br>---------------------------------------------------------<br><br><br>2차 요구 조건<br>MenuPanel 클래스<br>- 각 버튼에 MenuListener 클래스를 이용하여 이벤트를 적용시킨다.<br><br>MenuListener 클래스<br>- 모두지우기는 MyWhiteBoard&nbsp;클래스의 MyCanvas객체를 이용해서 clearRect() 메소드를 이용해서 지운다.<br>- 눌러진 버튼에 따라 MyWhiteBoard&nbsp;클래스의 Pen객체에 type를 설정한다.<br># type는 0 부터 사각형이고 6은 지우기이다. 그러나 임의의 방식을 이용해도 상관 없다.<br># clearRect() 메소드를 이용해서 전체지우기를 할 때는 클릭 했을 때 바로지워진다.<br><br>MyCanvas 클래스<br>- 마우스가 떼질 때 발생하는 이벤트 메소드에서 draw() 메소드를 호출한다.<br>- draw() 메소드는 MyWhiteBoard의 MyCanvas객체를 이용해 그림을 그리는 역할을 한다.<br><br>3차 요구 조건<br>- 위에 조건을 종합해 보면 그림을 그리는 방식은 그래그를 하는 방식으로 그림을 그린다. 그런데 여기서 발생할 수 있는 문제가 한가지 존재 한다. 마우스 드래그 방향이 좌측 상단에서 우측 하단으로(↘) 그려 질 때는 전혀 문제가 없다. 그러나 다음의 방향으로 드래그를 할 경우에는 문제가 발생한다. 다음의 요구사항을 처리해라.<br>&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;좌측 하단에서 우측 상단으로 드래그 해서 그린다.(↗)<br>&nbsp;&nbsp;&nbsp;&nbsp;2. 우측 하단에서 좌측 상단으로 드래그 해서 그린다.(↖)<br>&nbsp;&nbsp;&nbsp;&nbsp;3. 우측 상단에서 좌측 하단으로 드래그 해서 그린다.(↙)<br><br>- 부채꼴의 경우 그려지는 부채꼴의 각도는 임의로 한다. 다음에 그림 처럼 그려지도록 한다.<div style="text-align:center"><img class="image_mid" border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds13.egloos.com/pds/200811/20/62/f0018062_49250abc26aa5.jpg" width="274" height="257" onclick="Control.Modal.openDialog(this, event, 'http://pds13.egloos.com/pds/200811/20/62/f0018062_49250abc26aa5.jpg');" /></div>이 정도의 요구조건이면 완성 할 수 있을 듯 합니다. 해보시고 궁금한 점이나 부족한 부분이 있으면 댓글을 달아주시기 바랍니다.<br><br>그리고 완성 된 파일을 공개해 두겠습니다.<br><a href="http://pds10.egloos.com/pds/200811/20/62/MyWhiteBoard.java">MyWhiteBoard.java</a><br><br>다 완성 했다면 본인의 실력을 한층 올릴 수 있도록 추가 기능을 넣어 보는 것도 좋은 공부입니다.<br><br>감사합니다. ^^;<br><br><br/><br/>tag : <a href="/tag/java" rel="tag">java</a>,&nbsp;<a href="/tag/자바" rel="tag">자바</a>,&nbsp;<a href="/tag/whiteboard" rel="tag">whiteboard</a>,&nbsp;<a href="/tag/화이트보드" rel="tag">화이트보드</a>,&nbsp;<a href="/tag/자바예제" rel="tag">자바예제</a>			 ]]> 
		</description>
		<category>정리할 자료들</category>
		<category>java</category>
		<category>자바</category>
		<category>whiteboard</category>
		<category>화이트보드</category>
		<category>자바예제</category>

		<comments>http://maydaisy.egloos.com/1145156#comments</comments>
		<pubDate>Thu, 20 Nov 2008 07:05:44 GMT</pubDate>
		<dc:creator>만성피로</dc:creator>
	</item>
	<item>
		<title><![CDATA[ 1:1 채팅 프로그램 예제. ]]> </title>
		<link>http://maydaisy.egloos.com/1116250</link>
		<guid>http://maydaisy.egloos.com/1116250</guid>
		<description>
			<![CDATA[ 
  이번 글에서는 1:1 채팅 프로그램 예제에 대해서 이야기 하고자 합니다.<br><br>그럼 가장 먼저 해야 할 것은 설계 입니다. 채팅 프로그램이 어렵지는 않지만 처음 만들어 보는 것이라면 어떤 구조로 동작 할 것인지 설계를 하는 편이 좋습니다.<br><br>그럼 간단하게 설계를 하도록 합시다.<br><br>가장 먼저 java.net 패키지에서 어떤 클래스들을 사용해야 할지를 생각해 봅시다.<br><br>보통 기본 예제로 배우기 쉬운 것이 ServerSocket 클래스와 Socket 클래스를 이용한 에코서버 만들기 또는 메시지를 전달 할 수 있는 예제일 것입니다. <br><br>우리는 이 점을 이용해서 Socket클래스와 ServerSocket 클래스를 활용할 것이므로 메시지를 받을 때는 ServerSocket 클래스를 이용하고 메시지를 보낼 때는 Socket 클래스를 이용하면&nbsp;됩니다. <br><br><br>두번 째로 채팅 프로그램에서 메시지를 주고 받는 방식에 대한 세부적인 설계가 필요합니다. java.net 패키지를 이용해서 어떻게 주고 받을 것인가를 간략하게 설계 했으나 <u>메시지를 주고 받게 되는 것은 텍스트/바이트 스트림</u>입니다.<br><br><u>메시지를 송신 할 때는 출력에 해당 하므로 PrintWriter 클래스를 활용할 것입니다.<br>그렇다면 당연히 메시지를 수신 할 때는 입력에 해당 하므로 BufferedReader 클래스를 활용할 것입니다.</u><br><br>세번 째로는 위에 두가지를 조금 정리 하도록 하겠습니다.<br>메시지를 받을 때는 ServerSocket&nbsp; 클래스를 사용합니다.&nbsp;이 동작은 메시지 수신에 해당하는 동작이므로 BufferedReader 클래스와 같이 동작해야 합니다.<br>메시지를 보낼 때는 Socket 클래스를 사용합니다. 이 동작은 메시지 송신에 해당하는 동작이므로 PrintWriter 클래스와 같이 동작해야 합니다.<br><br>네번 째로는 송수신이&nbsp;동시에&nbsp;동작해야 합니다. 수신을 하면서도 송신이 가능해야 하므로 <u>멀티쓰레드를 이용하는 편이 좋습니다.</u><br><br>조금 더 자세하기 이야기를 하자면 송신을 하는 방법은 송신을 해야 할 때만 송신을 하면 되는 것이므로 큰 문제가 없으나 수신의 경우에는 언제나 받을 준비가 되야 하기 때문에 수신을 위한 동작이 돌고 있어야 하면서도 송신도 가능해야 합니다. <br>만약에 이 동작이 단일 쓰레드 라면 이 부분에서 문제가 될 소지가 있습니다. 내가 메시지를 보내는 사이에 수신을 해야 한다면 어떻게 될까요? <br>일단 무식한 결론을 내리겠습니다. 단일 쓰레드를 이용해도 컴퓨터의 동작 빠르기 때문에 큰 문제가 없을 듯 합니다. 그러나 메시지를 받는데 1분이 걸리고 메시지를 보내는데 1분이 걸린다고 가정 했을 때는&nbsp;단일 쓰레드의 경우에는 이부분에서 2분이라는 시간을 소요하게 됩니다.<br>멀티 쓰레드라면 보내는 것과 받는 것이 동시에 동작하므로 1분이 걸리게 되는 것이지요.<br>또한 다수의 채팅방에 경우에 여러 사람이 메시지를 전달 할 때 단일 쓰레드로 처리 하면 발생하는 문제가 있기 때문입니다. 100명이 메시지를 전달 한다면 마지막&nbsp;메시지는 출력되는데 오래 걸리겠지요..<br><span style="COLOR: #003300">(여기서 전이중 통신 반이중 통신 등 네트워크와는 상관 없이 멀티쓰레드를 위한 예 이므로 네트워크적인 요소는 일단 접어두고 생각하셔야 합니다.)</span><br><br>마지막으로는 적절한 인터페이스와 몇번 포트를 사용할 것인가를 정해야 합니다. 인터페이스 구성은 프로그램을 짜는 사람마다 다르므로 예제는 그림으로 보여드리도록 하겠습니다.<br><div style="text-align:center"><img class="image_mid" border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds12.egloos.com/pds/200811/17/62/f0018062_492145e5c18e0.jpg" width="500" height="416.666666667" onclick="Control.Modal.openDialog(this, event, 'http://pds12.egloos.com/pds/200811/17/62/f0018062_492145e5c18e0.jpg');" /></div>포트 또한 알아서 정하셔도 됩니다. 예제에서는 10000번 포트를 사용했습니다.<br><br><br>1. ServerSocket 클래스는 메시지를 받을 때 사용한다.<br>2. Socket 클래스는 메시지를 보낼 때 사용한다.<br>3. 송신은 PrintWriter 클래스 사용, 수신은 BufferedReader&nbsp;클래스 사용.<br>4. 송신과 수신은 동시에 동작할 수 있어야 한다.(멀티쓰레드 이용)<br>5. 적절한 인터페이스 구성과 사용할 포트번호를 정한다.<br><br>이를 간단하게 클래스 다이어그램으로 그리면 아래와 같습니다.<br><!--StartFragment--><p class="바탕글"><table style="BORDER-BOTTOM: #000000 0.28pt solid; BORDER-LEFT: #000000 0.28pt solid; BORDER-COLLAPSE: collapse; BORDER-TOP: #000000 0.28pt solid; BORDER-RIGHT: #000000 0.28pt solid"><tbody><tr><td style="BORDER-BOTTOM: #000000 0.28pt solid; BORDER-LEFT: #000000 0.28pt solid; WIDTH: 348.79pt; HEIGHT: 2.82pt; BORDER-TOP: #000000 0.28pt solid; BORDER-RIGHT: #000000 0.28pt solid" valign="center"><p class="바탕글">OneToOneChat - JFrame(상속), Runnable(구현), ActionListenet(구현)</p></td></tr><tr><td style="BORDER-BOTTOM: #000000 0.28pt solid; BORDER-LEFT: #000000 0.28pt solid; WIDTH: 348.79pt; HEIGHT: 2.82pt; BORDER-TOP: #000000 0.28pt solid; BORDER-RIGHT: #000000 0.28pt solid" valign="center"><p class="바탕글">-Socket serversocket<br>-Socket sendsocket</p><p class="바탕글">-ServerSocket server</p><p class="바탕글">-BufferedReader in</p><p class="바탕글">-PrintWriter out</p><p class="바탕글">적절한 인터페이스...</p></td></tr><tr><td style="BORDER-BOTTOM: #000000 0.28pt solid; BORDER-LEFT: #000000 0.28pt solid; WIDTH: 348.79pt; HEIGHT: 2.82pt; BORDER-TOP: #000000 0.28pt solid; BORDER-RIGHT: #000000 0.28pt solid" valign="center"><p class="바탕글">+OneToOneChat()</p><p class="바탕글">+setServer() : void</p><p class="바탕글">+process() : void</p><p class="바탕글">+run() : void</p><p class="바탕글">+send() : void</p><p class="바탕글">+exit() : void</p><p class="바탕글">+actionPerformed(ActionEvent e) : void</p></td></tr></tbody></table></p><br>간략하게 설명을 하자면<br>OneToOneChat 클래스 하나로 구현이 가능합니다. 쉽기 때문이지요.<br><p class="바탕글">생성자를 이용해서 인터페이스를 구성합니다.<br><br>setServer() 메소드는 server 객체에 포트번호 10000번을 인수로&nbsp;하는 ServerSocket 생성자를 이용해 셋팅을 해줍니다.<br><br>process() 메소드는 serversocket 객체를 이용해서 언제든지 메시지를 받을 수 있도록 설정합니다. 이 메소드가 하는 일은 상대방으로부터 메시지를 수신하는 역할을 합니다.<br><br>run() 메소드는 Runnable 인터페이스를 구현 한 것입니다. 이 메소드는 setServer(),&nbsp;process() 메소드를 동작 시키는 역할을 합니다.<br><br>send() 메소드는 sendsocket 객체를 이용해 메시지를 송신 하는 역할을 합니다.<br><br>exit() 메소드는 프로그램을 종료하면 상대방에게 프로그램을 종료 했다는 메시지를 보내고 프로그램 동작을 종료 하는 역할을 합니다.<br><br>actionPerformed(ActionEvent e) 메소드는 ActionListenet 인터페이스를 구현 한 메소드 입니다. 메시지를 전달 하는 send() 메소드를 동작 시키는 역할을 합니다.<br><br>기타..<br>프로그램 종료 이벤트는&nbsp;무명 클래스로 동작하고 WindowAdapter 클래스를 이용합니다. 동작 시키는 이벤트는 exit() 메소드를 동작 시키는 역할을 합니다.<br>대화 상대가 없을 경우에 Exception을 발생 시켜 "호스트는 오프라인 또는 존재하지 않을 수도 있습니다." 메시지를 출력하도록 합니다.<br>멀티 쓰레드를 이용하므로 메인메소드와&nbsp;run() 메소드는 동시에 동작 해야 합니다.<br><br>이것으로 필요한 설계에 조건은 대부분 다 모인 듯 합니다.<br><br>이제 이와 비슷한 토대로 작성을 하고 동작 되는지를 확인합니다.<br><br><br>그리고 소스를 아래 파일을 참고 하시기 바랍니다.<br><a href="http://pds13.egloos.com/pds/200811/17/62/OneToOneChat.java">OneToOneChat.java</a></p><br/><br/>tag : <a href="/tag/java" rel="tag">java</a>,&nbsp;<a href="/tag/자바" rel="tag">자바</a>,&nbsp;<a href="/tag/socket" rel="tag">socket</a>,&nbsp;<a href="/tag/serversocket" rel="tag">serversocket</a>,&nbsp;<a href="/tag/채팅" rel="tag">채팅</a>,&nbsp;<a href="/tag/채팅프로그램" rel="tag">채팅프로그램</a>,&nbsp;<a href="/tag/채팅예제" rel="tag">채팅예제</a>			 ]]> 
		</description>
		<category>정리할 자료들</category>
		<category>java</category>
		<category>자바</category>
		<category>socket</category>
		<category>serversocket</category>
		<category>채팅</category>
		<category>채팅프로그램</category>
		<category>채팅예제</category>

		<comments>http://maydaisy.egloos.com/1116250#comments</comments>
		<pubDate>Mon, 17 Nov 2008 11:22:09 GMT</pubDate>
		<dc:creator>만성피로</dc:creator>
	</item>
	<item>
		<title><![CDATA[ 인터페이스 부분 셋팅 파일 ]]> </title>
		<link>http://maydaisy.egloos.com/1111584</link>
		<guid>http://maydaisy.egloos.com/1111584</guid>
		<description>
			<![CDATA[ 
  <a href="http://pds13.egloos.com/pds/200811/16/62/Quiz.zip">Quiz.zip</a><br><br>프로젝트 진행에 관한 파일.<br><br>기본적인 인터페이스만 완료.<br><br>DB와 네트워크 부분 그리고 그 밖에 부분은 제외 시킨 파일.			 ]]> 
		</description>
		<category>정리할 자료들</category>

		<comments>http://maydaisy.egloos.com/1111584#comments</comments>
		<pubDate>Sun, 16 Nov 2008 11:32:28 GMT</pubDate>
		<dc:creator>만성피로</dc:creator>
	</item>
	<item>
		<title><![CDATA[ DB 사용에 대한 고민. ]]> </title>
		<link>http://maydaisy.egloos.com/1111452</link>
		<guid>http://maydaisy.egloos.com/1111452</guid>
		<description>
			<![CDATA[ 
  <p>현재 프로젝트 진행 정도는 DB와 네트워크 부분 수정 문제로 프로젝트가 잠시 중단 된 시점이다.<br><br>DB를 사용 하는 방법에는 2가지를 고려 중이다.<br><br>1. 클라이언트 쪽에서 DB 서버에 직접 접근을 한다.<br>2. 네트워크를 통해서 서버에 쿼리메시지를 보내고 서버는 받은 쿼리메시지를 이용해서 DB에 접근하는 방법이다.<br><br>그러나 DB에 접근 할 수 있는 계정을 호스트 마다 정할 수 있다는 점에서 약간 주춤 했던 것이 한가지 있다.<br>계정명@호스트명 이런식으로 정한다면 모든 호스트에 대한 설정이 문제가 됐었다.<br><br>이점에 대해서 검색을 해본 결과..<br><br>계정명@<strong><span style="COLOR: #ff0000">% </span></strong><br><br>이렇게 하면 그 어떤 호스트에서도 접근이 가능하다. 그럼 1번의 방법을 이용한다면 클라이언트가 DB에 직접 접근이 가능하다.<br>이렇게 한다면 java.net 패키지 없이 서버 DB에 접근이 가능하다.<br><br>그러나 1번을 이용하지는 않으려고 생각중이다. 여러 클라이언트에서 DB에 접근을 시도 한다고 가정 했을 때 문제가 될 소지가 있다고 보기 때문이다.<br><br>2번의 방법을 이용한다면 서버쪽에 DB 쿼리 메시지를 처리해줄 프로그래밍만 해주면<br>클라이언트&nbsp;&lt;-네트워크이용-&gt;&nbsp;서버&nbsp; &lt;-DB이용-&gt; MySQL<br>위와 같은 구조로 한다면 프로젝트의 질적인&nbsp;부분에서도 더 좋다고&nbsp;생각된다.<br><br>끝으로 현재 까지 진행 상황은 <br>로그인, 계정 생성, 계정 삭제, 암호변경, 계정찾기 까지 모두 완료 된 상태이다.<br></p><br/><br/>tag : <a href="/tag/java" rel="tag">java</a>,&nbsp;<a href="/tag/자바" rel="tag">자바</a>,&nbsp;<a href="/tag/프로젝트" rel="tag">프로젝트</a>,&nbsp;<a href="/tag/DB" rel="tag">DB</a>			 ]]> 
		</description>
		<category>정리할 자료들</category>
		<category>java</category>
		<category>자바</category>
		<category>프로젝트</category>
		<category>DB</category>

		<comments>http://maydaisy.egloos.com/1111452#comments</comments>
		<pubDate>Sun, 16 Nov 2008 11:08:25 GMT</pubDate>
		<dc:creator>만성피로</dc:creator>
	</item>
	<item>
		<title><![CDATA[ 윈도우 창 속에 윈도우 창 - JInternalFrame. ]]> </title>
		<link>http://maydaisy.egloos.com/1081246</link>
		<guid>http://maydaisy.egloos.com/1081246</guid>
		<description>
			<![CDATA[ 
  <p><div style="text-align:center"><img class="image_mid" border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds10.egloos.com/pds/200811/10/62/f0018062_491835121dbb0.jpg" width="331" height="264" onclick="Control.Modal.openDialog(this, event, 'http://pds10.egloos.com/pds/200811/10/62/f0018062_491835121dbb0.jpg');" /></div>위에 보이는 이미지는 원도우 창 안에 윈도우 창이 존재하는 이미지 입니다. 보통 포토샵 프로그램에서 여러 이미지를 불러오게 되면 포토샵 프로그램 창 안에 여러가지 이미지들이 각각 따로 배치가 돼 있는 것을 볼 수 있습니다. 오늘은 바로 이와 같이 윈도우 창 안에 윈도우 창을 넣는 방법에 대해서 이야기 해 봅시다.<br><br>그럼 위에 이미지를 아주 단순하게 생각을 해 봅시다.<br><br>JFrame 안에 JFrame를 넣는다.<br>이 단순한 생각을 코딩한다면 JFrame.add(JFrame) 이런 방식을 사용한다는 의미 일 것입니다.<br>그러나 실제로 돌리면 안된다는 것을 알 수 있습니다. 물론 공부를 탄탄히 하셨다면 왜 인지도 알수 있겠지요.<br><br>그럼 어떻게 해야 할까요? 방법은 간단합니다 JInternalFrame 클래스를 이용하면 됩니다. <br>JInternalFrame 클래스에 대한 자세한 정보는 API를 참고하세요.<br><br>이용 방법은 간단합니다. add를 이용해서 넣어주면 됩니다.<br><br>그러나 여기서 주의해야 할 것이 한가지 있는데..<br><br>setSize, setLocation 등 일부 메소드가 먹히지 않는 경우가 발생할 수 있습니다.<br><br>그 이유는 바로 레이아웃 메니저에 대한 설정 문제 입니다. 이런 간단한 설명으로는 이해가 부족할 수 있으니 간단한 예제를 통해서 더 자세히 알아보도록 합시다.<br><br>import javax.swing.*;</p><p>public class Internaltest {</p><p>&nbsp;public static void main(String[] args) {<br>&nbsp;&nbsp;JFrame frm = new JFrame("외부 윈도우 창");<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;JPanel jp = new JPanel();<br><strong><span style="COLOR: #ff0000">&nbsp;&nbsp;frm.setLayout(null);</span></strong><br>&nbsp;&nbsp;// 이 부분이 생각보다 중요할 수 있습니다. 레이아웃 메니저 때문에 원하는 데로 설정이 안될 수도 있습니다.<br>&nbsp; // JPanel, JFrame는&nbsp;기본적인 레이아웃이 다르게 설정 돼 있죠..<br><br>&nbsp;&nbsp;JInternalFrame inter = new JInternalFrame("내부 윈도우 창",false,false,false,false);<br>&nbsp;&nbsp;&nbsp;&nbsp;// JInternalFrame&nbsp;클래스는 생성자가 많으니 API를 잘 참고해야 합니다.<br><br>&nbsp;&nbsp;inter.setSize(200,300);<br>&nbsp;&nbsp;inter.setLocation(100, 50);<br>&nbsp;&nbsp;inter.setVisible(true);<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;frm.add(inter);<br>&nbsp;&nbsp;frm.setSize(500,500);<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;frm.setVisible(true);<br>&nbsp;&nbsp;<br>&nbsp;}<br>}<br><br>간단한 예제이지만 실제로 해보지 않으면 도움이 되질 못합니다. 꼭 해보시길 바랍니다. </p><br/><br/>tag : <a href="/tag/java" rel="tag">java</a>,&nbsp;<a href="/tag/자바" rel="tag">자바</a>,&nbsp;<a href="/tag/JInternalFrame" rel="tag">JInternalFrame</a>,&nbsp;<a href="/tag/내부프레임" rel="tag">내부프레임</a>,&nbsp;<a href="/tag/내부프레임레이아웃" rel="tag">내부프레임레이아웃</a>			 ]]> 
		</description>
		<category>정리할 자료들</category>
		<category>java</category>
		<category>자바</category>
		<category>JInternalFrame</category>
		<category>내부프레임</category>
		<category>내부프레임레이아웃</category>

		<comments>http://maydaisy.egloos.com/1081246#comments</comments>
		<pubDate>Mon, 10 Nov 2008 13:42:37 GMT</pubDate>
		<dc:creator>만성피로</dc:creator>
	</item>
	<item>
		<title><![CDATA[ 메뉴바 만들기. ]]> </title>
		<link>http://maydaisy.egloos.com/1068304</link>
		<guid>http://maydaisy.egloos.com/1068304</guid>
		<description>
			<![CDATA[ 
  <p>이번 글에서는 메뉴바를 만들어 보도록 하겠습니다.<br>그리고 awt에 있는 Menu가 아닌 swing에 있는 JMenu를 예로 합니다.<br><br><div style="text-align:center"><img class="image_mid" border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds12.egloos.com/pds/200811/07/62/f0018062_491435591c08a.jpg" width="263" height="210" onclick="Control.Modal.openDialog(this, event, 'http://pds12.egloos.com/pds/200811/07/62/f0018062_491435591c08a.jpg');" /></div></p>위에 보이는 그림은 현재 프로젝트를 진행하고 있는 기본 인터페이스 입니다. 저것을 가지고 쉽게 그림으로 알아보도록 합시다.<br><br>메뉴를 위와 같이 구성 하려면 다음의&nbsp;3가지 클래스를 이용해야 합니다. <br>JMenuBar 클래스<br>JMenu 클래스<br>JMenuItem 클래스<br><br>조금 귀찮죠 -_-? 그래도 오히려 이 때문에 더 쉽게 기억 될 수 있으니 철자만 잘 외우세요 -_-;<br><br><br><div style="text-align:center"><img class="image_mid" border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds11.egloos.com/pds/200811/07/62/f0018062_491435fc0ef16.jpg" width="263" height="210" onclick="Control.Modal.openDialog(this, event, 'http://pds11.egloos.com/pds/200811/07/62/f0018062_491435fc0ef16.jpg');" /></div>가장 먼저 위에 그림에서 활성화 된 부분에 해당하는 클래스는 JMenuBar 클래스 입니다.<br>모든 메뉴의 내용들은 최종적으로&nbsp; JMenuBar&nbsp;클래스에 들어가게 됩니다.<br><br>더 쉽게 말하자면 우리가 각종 JButton, JTextArea, JPanel은 모두 JFrame에 들어가는 것과 같다고 할 수 있습니다.<br><br>그럼 다음 그림을 보도록 합시다.<br><div style="text-align:center"><img class="image_mid" border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds12.egloos.com/pds/200811/07/62/f0018062_49143781909b9.jpg" width="263" height="210" onclick="Control.Modal.openDialog(this, event, 'http://pds12.egloos.com/pds/200811/07/62/f0018062_49143781909b9.jpg');" /></div>좀 전에 그림과 약간 비슷하지만 위에 활성화 된 영역은 JMenu 클래스 입니다.<br>파일에 해당하는 JMenu 객체<br>게임에 해당하는 JMenu 객체<br>도움말에 해당하는 JMenu 객체<br>이렇게 3개가 존재하게 됩니다.<br><br>이 3개의 객체들은 JMenuBar에 들어가게 되는 것이지요.<br>JMenuBar 객체.add(파일);<br>JMenuBar 객체.add(게임);<br>JMenuBar 객체.add(도움말);<br>이런 식입니다.<br><br>그럼 마지막으로<br><div style="text-align:center"><img class="image_mid" border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds10.egloos.com/pds/200811/07/62/f0018062_4914380daf601.jpg" width="263" height="210" onclick="Control.Modal.openDialog(this, event, 'http://pds10.egloos.com/pds/200811/07/62/f0018062_4914380daf601.jpg');" /></div>위에 보이는 활성화 된 영역은 JMenuItem 클래스 입니다.<br>형식은 List 클래스 활용과 비슷하기도 합니다. 허나 다른점은 각 메뉴별로 JMenuItem형 객체라는 점이지요<br>현재 보이는 그림을 예로 들면<br>로그인 부터 종료 까지 총 6개의 JMenuItem 객체가 JMenu형 객체(파일)에 속하는 것입니다.<br>JMenu 객체.add(로그인);<br>.....<br>JMenu 객체.add(종료);<br><br>이런식입니다. 아주 간단하고 쉽습니다.<br><br>이를 예제 소스의 일부를&nbsp;보도록 합시다.<br><br>&nbsp;&nbsp;file = new JMenu("파일");<br>&nbsp;&nbsp;game = new JMenu("게임");<br>&nbsp;&nbsp;help = new JMenu("도움말");<br>&nbsp;&nbsp;<br>//파일 메뉴의 항목들<br>&nbsp;&nbsp;file_login = new JMenuItem("로그인");<br>&nbsp;&nbsp;file_idCreate = new JMenuItem("계정생성");<br>&nbsp;&nbsp;file_idSearch = new JMenuItem("계정/암호 찾기");<br>&nbsp;&nbsp;file_passChange = new JMenuItem("암호변경");<br>&nbsp;&nbsp;file_logout = new JMenuItem("로그아웃");<br>&nbsp;&nbsp;file_exit = new JMenuItem("종료");<br>&nbsp;&nbsp;<br>//게임 메뉴의 항목들<br>&nbsp;&nbsp;game_start = new JMenuItem("게임시작");<br>&nbsp;&nbsp;game_rank = new JMenuItem("랭킹보드");<br>&nbsp;&nbsp;<br>//도움말 메뉴의 항목들<br>&nbsp;&nbsp;help_info = new JMenuItem("게임정보");<br>&nbsp;&nbsp;help_update = new JMenuItem("업데이트");<br>&nbsp;&nbsp;<br>//항목을 해당 목록에 넣기<br>&nbsp;&nbsp;file.add(file_login);<br>&nbsp;&nbsp;file.add(file_idCreate);<br>&nbsp;&nbsp;file.add(file_idSearch);<br>&nbsp;&nbsp;file.add(file_passChange);<br>&nbsp;&nbsp;file.add(file_logout);<br>&nbsp;&nbsp;file.add(file_exit);<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;game.add(game_start);<br>&nbsp;&nbsp;game.add(game_rank);<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;help.add(help_info);<br>&nbsp;&nbsp;help.add(help_update);<br><br>//메뉴바에 모두 배치&nbsp;&nbsp;<br>&nbsp;&nbsp;menubar = new JMenuBar();<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;menubar.add(file);<br>&nbsp;&nbsp;menubar.add(game);<br>&nbsp;&nbsp;menubar.add(help);<br><br>전체적으로 봤을 때 awt를 배울 때와 같은 형식입니다. 쉽게 생각하도록 합시다.<br><br>그리고 각 메뉴를 클릭 했을 때 일어나야 할 이벤트들은 ActionListener을 써야 한다는 점을 생각해보도록 합시다.<br>왜? 라는 생각을 할 수도 있겠지만 ActionListener가 무엇을 하는 것인가? 라는 것을 생각해 보면 알 수 있습니다.<br><br>그리고 JFrame에 적용 시키는 방법은 약간 다릅니다.<br>add()를 활용하는 것이 아니라 setJMenuBar() 메소드를 이용해야 합니다.<br><br>JFrame형객체.setJMenuBar(JMenuBar형객체);<br><br>여기까지가 메뉴바에 대한 간단한 설명이었습니다. 더 자세한건 API를 참고하면 됩니다.<br><br>다음 글에는 JInternalFrame에 대해서 이야기를 해봅시다.<br/><br/>tag : <a href="/tag/java" rel="tag">java</a>,&nbsp;<a href="/tag/자바" rel="tag">자바</a>,&nbsp;<a href="/tag/menu" rel="tag">menu</a>,&nbsp;<a href="/tag/JMenu" rel="tag">JMenu</a>,&nbsp;<a href="/tag/JMenuBar" rel="tag">JMenuBar</a>,&nbsp;<a href="/tag/JMenuItem" rel="tag">JMenuItem</a>,&nbsp;<a href="/tag/메뉴" rel="tag">메뉴</a>,&nbsp;<a href="/tag/메뉴바" rel="tag">메뉴바</a>			 ]]> 
		</description>
		<category>정리할 자료들</category>
		<category>java</category>
		<category>자바</category>
		<category>menu</category>
		<category>JMenu</category>
		<category>JMenuBar</category>
		<category>JMenuItem</category>
		<category>메뉴</category>
		<category>메뉴바</category>

		<comments>http://maydaisy.egloos.com/1068304#comments</comments>
		<pubDate>Fri, 07 Nov 2008 12:56:36 GMT</pubDate>
		<dc:creator>만성피로</dc:creator>
	</item>
	<item>
		<title><![CDATA[ 실습 과제 풀이. ]]> </title>
		<link>http://maydaisy.egloos.com/1049116</link>
		<guid>http://maydaisy.egloos.com/1049116</guid>
		<description>
			<![CDATA[ 
  <p><div style="text-align:center"><img class="image_mid" border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds13.egloos.com/pds/200811/03/62/f0018062_490ee894b36f8.jpg" width="280" height="130" onclick="Control.Modal.openDialog(this, event, 'http://pds13.egloos.com/pds/200811/03/62/f0018062_490ee894b36f8.jpg');" /></div>우리가 흔히 프로그램을 설치 또는 특정 작업을&nbsp;컴퓨터가 처리 할 때 몇 퍼센트 정도 진행이 됐는지 알 수 있도록 하기 위해서 위와 같이 JProgressBar(JProgressBar는 자바에서 불리우는 명칭이자 클래스 입니다.)를 이용합니다.<br><br>위에 보이는 그림은 참으로 단순하기 그지 없는 JProgressBar 실습예제입니다. 그러나..<br><br>실습 과정에서 약간의 문제가 발생하는 부분이 있어서 해설편을 이렇게 준비를 했습니다.<br><br>그럼 하나 하나 알아보도록 합시다.<br>일단 위에 보이는대로 인터페이스를 완성합니다.<br>그리고 각 버튼에 이벤트를 정해주고 실행을 합니다.<br><br>문제가 되는 부분은 여기 부터 입니다. 캡쳐가 없어서 보여드리지는 못하지만 다음의 문제가 발생하는 경우 잘 봐두셔야 합니다.<br>증가 버튼을 누르면 버튼이 눌린 상태로 다운 먹은 듯한 현상이 잠시 일어난 뒤에 바의 색이 전부 파랗게 차 있다.<br><br>이런 문제가 발생했다면 해결 방법은 다음과 같습니다.<br><br>이벤트 버튼에 직접 JProgressBar 객체에 상태를 변화시키는 코딩을 했기 때문에 발생하는 문제입니다.<br><br>왜? 그렇게 코딩을 하면 안되느냐?<br>이는 멀티쓰레딩과도 같은 효과를 바라는 것이기 때문에 문제가 되는 것입니다.<br><br>우리는 메인 메소드를 통해서 프로그램을 동작시킵니다.<br>그 말은 현재 프로그램은 메인메소드가 동작중이라는 말이 되지요.<br><br>그러나 이벤트리스너를 적용시켰다면 버튼을 눌렀을 때는 이벤트가 발생합니다.<br>이벤트는 하나의 메소드가 실행되는 것이지요..<br><br>그럼 당연히 메인메소드는 잠시 중단이 되고 이벤트 메소드가 실행됩니다.<br>그래서 화면이 멈춰 있는 듯한 현상이 일어나는 것입니다.<br><br>약간의 해설을 더 하자면 완성된 인터페이스가 보여지는 것은 메인메소드에서 실행되기 때문입니다.<br>이벤트리스너는 단순히 이벤트 메소드를 실행하는 것입니다.(이래도 어렵다면 그림을 그리세요)<br><br>이를 해결 하는 방법은 두가지 방법이 존재합니다.<br>1. 멀티쓰레드를 이용한다.<br>2. 이벤트가 메인메소드에서 실행돼야 한다.<br><br>이 두가지 방법을 보면 멀티쓰레드를 사용할 줄 안다면 1번이 더 쉽다고 느껴질 수 있습니다. 그러나 멀티쓰레드로 해결하지는 않겠습니다. 멀티 쓰레드로 한다면 약간의 문제의 소지가 더 있기 때문에 2번으로 해결하겠습니다.<br><br>메인메소드에서 이벤트가 실행돼야 한다.<br>어떻게 할까요? 이벤트 메소드를 메인 안에서 해결한다는 것은 메인 메소드 안에서 무명 클래스 또는 기타 여러가지 방법을 이용해야 하지 않을까 하는 생각이 들 수도 있습니다. 그렇다면 변수의 접근할 수 있는 권한 설정이 바껴야 한다는 점도 있을 수 있고 여러가지 귀찮은 상황이 일어날 수 있습니다.<br><br>그래서 아주 간단하게 해결 하도록 하겠습니다.<br><br>일단 버튼을 클릭해서 실행 했을 때 JProgressBar 객체의 상태 변화를 주지는 않겠습니다.<br>단순히 <br>증가는 증가 스위치, 감소는 감소 스위치, 정지는 정지 스위치<br>이렇게 변수를 지정해서 사용하겠습니다.<br>그럼 버튼을 클릭하면 메인은 아주 찰나의 시간 동안 멈추고 이벤트를 처리하고 다시 메인으로 돌아옵니다.<br>그럼 메인에서 스위치에 따라 동작을 하도록 하면 됩니다.<br><br>메인에서 직접 짜도 되고 메소드를 메인에서 실행 하는 방법을 취하면 됩니다.<br>이는 아주 간단하게 이해 할 수 있도록 소스롤 보는쪽으로 합시다.<br>&nbsp;public void progressBar() {<br>&nbsp;&nbsp;try {<br>&nbsp;&nbsp;&nbsp;while (true) { //&nbsp;루프는 무한으로 돌아야 한다.<br>&nbsp;&nbsp;&nbsp;&nbsp;while (state == <strong><span style="COLOR: #ff0000">PLUS</span></strong>) { //&nbsp;state&nbsp;변수의 변화에 따라 루프문을&nbsp;실행한다.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(50); //잠시 쉰다.<br><span style="COLOR: #009900">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jpb.setValue(index); // JProgressBar&nbsp;객체에 값을 변화 시킨다.</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;label.setText("현재상태 : " + index + "%");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (index &lt; 100) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p><p>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;while (state == <strong><span style="COLOR: #ff0000">MINUS</span></strong>) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(50);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jpb.setValue(index);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;label.setText("현재상태 : " + index + "%");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (index &gt; 0) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index--;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;while (state == <strong><span style="COLOR: #ff0000">STOP</span></strong>) {<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;} catch (Exception e) {<br>&nbsp;&nbsp;&nbsp;e.printStackTrace();<br>&nbsp;&nbsp;}<br>&nbsp;}<br><br>PLUS, MINUS, STOP는 final 변수이고 state가 액션리스터 메소드에서 값을 변화합니다.<br>&nbsp;private final int PLUS = 1;<br>&nbsp;private final int STOP = 0;<br>&nbsp;private final int MINUS = 2;<br>&nbsp;private int state = 0;<br><br>그리고 메인메소드에서 이 루프문이 들어 있는 메소드를 실행하면 메인에서 동작하는 것이기에 다운 된 듯한 현상을 깔끔히 해결 할 수 있습니다.<br>&nbsp;public static void main(String[] args){<br><span style="COLOR: #ff0000">&nbsp;&nbsp;Exam1102 ex = new Exam1102();<br>&nbsp;&nbsp;ex.progressBar();</span><br>&nbsp;}<br><br><span style="COLOR: #3333ff">전체 소스는 아래 파일을 참고 하세요.</span><br><a href="http://pds10.egloos.com/pds/200811/03/62/Exam1102.java">Exam1102.java</a>&nbsp;<br><br>그리고 아까 잠시 이야기 했던 멀티쓰레드를 이용하는 방법에 대해서 이야기&nbsp;합시다.<br><br>이 문제가 발생할 수 있는 이유는 다음과 같습니다.<br>처음 이벤트를 실행 할 때는 전혀 문제가 되지 않습니다. 그러나 문제는 그 이후부터 발생합니다.<br>멀티쓰레드를 이용하기 위해서는 약간의 조건이 붙는데 한번 실행 된 메소드는 다시 실행이 불가능합니다.<br>다시 실행을 하려면 객체를 다시 만들어야 한다는 점이지요.<br>메소드의 재활용이 불가능하다.(?) 라고 할 수 있습니다.<br>그렇다면 매번 버튼이 눌러질 떄 마다 객체를 새로 생성해야 한다는 것이 문제가 되지요.<br>어떻게든 잘만 코딩을 한다면 이 문제점을 해결 할수도 있다고 보는데 일단은 효율적인 면에서 떨어진다고 봅니다.<br>너무 어려운 길을 돌아서 가는 방법이기 때문이지요.<br>자바를 이해하고 연구 분석을 하기에는 괜찮은 방법일지는 모르겠지만 얻는 것보다 손해 보는 것이 더 많다고 판단 되기 때문에 이 방법은 추천하지 않습니다.<br><br>그럼 이번 글은 여기서 마치도록 하겠습니다.<br><br>멀티쓰레드에 관한 정보는 아직 부족한 것이 많으니 보충 설명은 댓글을 달아주세요 ^^;</p><br/><br/>tag : <a href="/tag/java" rel="tag">java</a>,&nbsp;<a href="/tag/자바" rel="tag">자바</a>,&nbsp;<a href="/tag/멀티쓰레드" rel="tag">멀티쓰레드</a>,&nbsp;<a href="/tag/JPROGRESSBAR" rel="tag">JPROGRESSBAR</a>			 ]]> 
		</description>
		<category>정리할 자료들</category>
		<category>java</category>
		<category>자바</category>
		<category>멀티쓰레드</category>
		<category>JPROGRESSBAR</category>

		<comments>http://maydaisy.egloos.com/1049116#comments</comments>
		<pubDate>Mon, 03 Nov 2008 12:49:21 GMT</pubDate>
		<dc:creator>만성피로</dc:creator>
	</item>
</channel>
</rss>
