2008/09/04 02:09
AWT Notepad Hello World/Java/JSP/EJB2008/09/04 02:09
/*
* AWT는 처음 배우는 거라, 저도 정리 좀 할 겸 설명 달아봅니다.
* 혹시 제가 잘못 이해하고 있거나 더 나은 방법이 있으면 말씀해주세요.
*/
/*
* 08.09.03 - 메모장 만들기
* // 요구사항, 제한사항을 작성하면서
* +---------------------------------+ // 전체적인 설계를 대충 그려봅니다.
* | +-----+ +-----+ +---------+ R |
* | |...▽| +...▽+ +---------+ G |
* | +-----+ +-----+ +---------+ B |
* | |
* | []진하게 []이탤릭 |
* | +----------------------+ +----+ |
* | | | |등록| |
* | +----------------------+ +----+ |
* | +-----------------------------+ |
* | | | |
* | | | |
* | | | |
* | | | |
* | | | |
* | +-----------------------------+ |
* +---------------------------------+
*
* 첫번째 드롭다운 - 글자 색상
* 두번째 드롭다운 - 글자 크기
* 세번째 스크롤바 - RGB 컬러(배경)
* 진하게/이탤릭 체크박스
* 중간 텍스트필드에 글 쓰고 등록 버튼 누르면
* 아래쪽 텍스트에어리어에 등록
* 색상, 크기 변경은 텍스트에어리어 전체에 적용
*/
package exam;
import java.awt.*;
import java.awt.event.*;
public class AWTNotepad extends Frame
implements ActionListener, AdjustmentListener, ItemListener {
// 컬러 리스트와 컬러 이름을 배열에 선언했습니다.
// 배열로 선언하는 이유는 색상에 대한 추가/삭제를 보다 편하게 하기 위해서입니다.
Color[] colorList = {Color.black, Color.blue, Color.cyan, Color.darkGray,
Color.gray, Color.green, Color.lightGray, Color.magenta, Color.orange,
Color.pink, Color.red, Color.white, Color.yellow};
String[] colorName = {"Black", "Blue", "Cyan", "DarkGray", "Gray", "Green",
"LightGray", "Magenta", "Orange", "Pink", "Red", "White", "yellow"};
// 클래스에서 사용할 멤버변수를 선언합니다.
// Event처리를 위해 Listener에서 참조하는 변수(개체)들입니다.
// Label과 같이 재사용성이 없다 판단되는 변수는 지역변수로 선언했습니다.
Choice chFontColor;
Choice chFontSize;
Checkbox cbxBold;
Checkbox cbxItalic;
Scrollbar scbR;
Scrollbar scbG;
Scrollbar scbB;
TextField txtUser;
TextArea txtResult;
// 생성자를 선언합니다.
// 책의 예제는 대부분 이런 방식으로 AWT를 사용하는데,
// 실제로 이렇게 쓰는게 일반적인지 어떤지는 모르겠습니다.
public AWTNotepad(String str) {
super(str);
// 프레임 설정 // 프레임에 대한 설정을 합니다.
addWindowListener(new WindowHandler()); // 닫기 버튼 처리를 위한 부분입니다.
setSize(600, 400);
setBackground(Color.lightGray);
setResizable(false); // 프레임의 크기변경을 막습니다.
setVisible(true);
// 패널 설정
Panel pFontColor = new Panel(null); // 레이아웃을 사용하지 않고 절대좌표로
Panel pFontSize = new Panel(null); // 처리하기 위해 각 부분을 패널로 나눈 뒤
Panel pFontType = new Panel(null); // new Panel(null)로 선언합니다.
Panel pBgColor = new Panel(null);
Panel pInputText = new Panel(null);
Panel pText = new Panel(null);
Panel pTmp = new Panel(null); // 버그인지 마지막 패널이 끝없이 확장되며
// 제 위치를
// 잘 찾지 못해서 생성한 쓰레기패널입니다.
// 무식한 방법입니다만, 각 패널의 위치를 일일히 계산해서 좌표값을 찍어줬습니다.
// 각 패널 위치는 아래와 같습니다.
//
// +------------+-----------+----------+
// | pFontColor | pFontSize | |
// +------------+-----------+ pBgColor |
// | pFontType | |
// +------------------------+----------+
// | pInputText |
// +-----------------------------------+
// | |
// | pText |
// | |
// +-----------------------------------+
//
// setBounds(x축위치, y축위치, 가로크기, 세로크기)
//
// 최상단의 pFontColor, pFontSize, pBgColor에 대한
// y축위치가 20부터 시작하는 이유는,
// 윈도우 타이틀도 세로축 길이에 포함되기 때문.
//
// pTmp를 최하단에 0, 0 크기로 지정합니다.
pFontColor.setBounds(0, 20, 175, 30);
pFontSize.setBounds(175, 20, 175, 30);
pFontType.setBounds(0, 50, 350, 30);
pBgColor.setBounds(350, 20, 250, 60);
pInputText.setBounds(0, 80, 600, 30);
pText.setBounds(0, 110, 600, 290);
pTmp.setBounds(0, 400, 0, 0);
// 글자 색상
Label lblFontColor = new Label("글자 색상");
chFontColor = new Choice();
// 자료형 Color로 선언된 배열 ColorName을 Foreach문으로 chFontColor에 넣습니다
for (String s: colorName) chFontColor.add(s);
// 기본값을 Black으로 설정합니다.
chFontColor.select("Black");
// Label과 Choice를 절대좌표로 위치등록합니다.
// 이때 좌표 기준은 프레임이 아닌 패널입니다.
lblFontColor.setBounds(10, 10, 60, 20);
chFontColor.setBounds(70, 10, 100, 20);
// 글자 크기
Label lblFontSize = new Label("글자 크기");
chFontSize = new Choice();
// 이건 그냥.. 귀찮아서 일일히 넣었습니다.-_-;
chFontSize.add("6");
chFontSize.add("8");
chFontSize.add("10");
chFontSize.add("11");
chFontSize.add("12");
chFontSize.add("16");
chFontSize.add("20");
chFontSize.add("24");
chFontSize.add("32");
chFontSize.select("12"); // 기본값을 12로 설정합니다.
lblFontSize.setBounds(10, 10, 60, 20);
chFontSize.setBounds(70, 10, 100, 20);
// 글자 타입
cbxBold = new Checkbox("진하게");
cbxItalic = new Checkbox("기울임");
cbxBold.setBounds(10, 10, 60, 20);
cbxItalic.setBounds(80, 10, 60, 20);
// 배경 색상
Label lblR = new Label("R");
Label lblG = new Label("G");
Label lblB = new Label("B");
// 스크롤바 3개를 생성하는데,
//
// Scrollbar.HORIZONTAL : 가로형태의 스크롤바
// 255 : 스크롤바의 초기 위치.
// 100 : 스크롤바의 크기.
// 0 : 스크롤바의 시작값. 가장 왼쪽에 위치했을 때의 반환값
// 355 : 스크롤바의 마지막값. 가장 우측에 위치했을 때의 반환값
//
// (마지막값)-(시작값)-(스크롤바크기) : 스크롤바 이동에 따른 값의 범위입니다.
//
// RGB컬러는 0, 0, 0 부터 255, 255, 255 까지로 표현되기 때문에
// 0부터 255까지 변화할 수 있도록 설정했습니다.
// 또, TextArea 배경색상 기본이 흰색이기 때문에 RGB(255, 255, 255)에 맞도록
// 초기값을 255로 잡아줬습니다.
//
// 스크롤바 마지막값 355를 356으로 바꾸고 가장 오른쪽으로 스크롤바를 밀면
// RGB 각 항목의 최대값인 255를 넘어서기 때문에
// IllegalArgumentException이 발생하는 것을 확인할 수 있습니다.
// 초기값인 0을 0보다 작은 값, 음수로 바꾸어도 마찬가지입니다.
scbR = new Scrollbar(Scrollbar.HORIZONTAL, 255, 100, 0, 355);
scbG = new Scrollbar(Scrollbar.HORIZONTAL, 255, 100, 0, 355);
scbB = new Scrollbar(Scrollbar.HORIZONTAL, 255, 100, 0, 355);
lblR.setBounds(10, 10, 15, 15);
lblG.setBounds(10, 25, 15, 15);
lblB.setBounds(10, 40, 15, 15);
scbR.setBounds(30, 10, 210, 15);
scbG.setBounds(30, 25, 210, 15);
scbB.setBounds(30, 40, 210, 15);
// 사용자 입력 텍스트
txtUser = new TextField();
Button btnSubmit = new Button("등록");
txtUser.setBounds(10, 10, 530, 20);
btnSubmit.setBounds(550, 10, 40, 20);
// 결과 출력 텍스트에어리어
txtResult = new TextArea();
txtResult.setEditable(false); // setEditable(false) : 임의의 내용수정을 막음.
txtResult.setBackground(Color.white);
txtResult.setBounds(10, 10, 580, 270);
// 패널 구분을 돕기 위한 백그라운드컬러
// pFontColor.setBackground(Color.yellow); // 주석에 써놓은 것 처럼
// pFontSize.setBackground(Color.blue); // 패널 디자인시 각 패널의 위치를
// pFontType.setBackground(Color.orange); // 확인하기 위해 임시로 설정한
// pBgColor.setBackground(Color.cyan); // 각 패널들의 배경색상입니다.
// pInputText.setBackground(Color.green);
// pText.setBackground(Color.magenta);
//
// lblFontColor.setBackground(Color.pink);
// chFontColor.setBackground(Color.cyan);
// 패널에 등록 // 위에서 생성한 개체들을 각 패널에 맞게 등록합니다.
pFontColor.add(lblFontColor);
pFontColor.add(chFontColor);
pFontSize.add(lblFontSize);
pFontSize.add(chFontSize);
pFontType.add(cbxBold);
pFontType.add(cbxItalic);
pBgColor.add(lblR);
pBgColor.add(lblG);
pBgColor.add(lblB);
pBgColor.add(scbR);
pBgColor.add(scbG);
pBgColor.add(scbB);
pInputText.add(txtUser);
pInputText.add(btnSubmit);
pText.add(txtResult);
// 프레임에 등록 // 패널들을 전체 프레임 안에 등록합니다.
add(pFontColor);
add(pFontSize);
add(pFontType);
add(pBgColor);
add(pInputText);
add(pText);
add(pTmp);
// 리스너 등록 // 이벤트 처리를 위해 각 개체 타입에 맞게 리스너등록을 합니다.
chFontColor.addItemListener(this);
chFontSize.addItemListener(this);
cbxBold.addItemListener(this);
cbxItalic.addItemListener(this);
scbR.addAdjustmentListener(this);
scbG.addAdjustmentListener(this);
scbB.addAdjustmentListener(this);
btnSubmit.addActionListener(this);
}
public void adjustmentValueChanged(AdjustmentEvent e) {
txtResult.setBackground(
new Color(scbR.getValue(), scbG.getValue(), scbB.getValue()) );
}
public void actionPerformed(ActionEvent e) {
// btnSubmit 버튼을 클릭했을 때의 이벤트 처리입니다.
// TextField(txtUser)의 getText() 메서드로 txtUser에 있는 내용을 읽어온 뒤
// 행바꿈문자(\n)를 추가합니다.
// TextArea(txtResult)의 append() 메서드를 사용해서 내용을 추가합니다.
txtResult.append(txtUser.getText() + "\n");
txtUser.setText(""); // txtUser의 내용을 빈문자열("")로 초기화합니다.
}
public void itemStateChanged(ItemEvent e) {
// 글자 스타일 이벤트 처리
try {
// e.getSource()는 이벤트가 발생한 객체를 Object로 반환합니다.
// e.getSource()로 받아온 객체를 Checkbox 자료형으로 강제형변환을 한 뒤
// Checkbox 자료형으로 선언된 obj에 대입합니다.
//
// 이 때 자료형이 일치하지 않으면 ClassCastException 에러가 발생하기 때문에
// try ~ catch 로 예외처리를 해서 자료형이 일치할 때만 동작하도록 해줍니다.
Checkbox obj = (Checkbox)e.getSource();
// txtResult에 설정되어 있는 글꼴정보를 Font자료형 f에 getFont()로 읽어옴.
Font f = txtResult.getFont();
if (obj == cbxBold) { // obj, 즉 이벤트가 발생한 객체가 cbxBold라면,
if (cbxBold.getState()) // cbxBold가 체크되어있으면(true),
// new Font(String, int, int)
// String : 글꼴이름 / int : 글꼴타입 / int : 글꼴크기
// 글꼴 타입은 Font.BOLD, Font.ITALIC 등으로 표현가능합니다.
txtResult.setFont(new Font(
// f : Font f = txtResult.getFont();
// 즉, f는 txtResult의 글꼴 정보를 저장한 변수(자료형은 Font)
//
// f.getFontName() : 현재 txtResult에 설정되어 있는 글꼴이름
// f.getStyle() : 현재 txtResult에 설정되어 있는 글꼴타입
// f.getSize() : 현재 txtResult에 설정되어 있는 글꼴크기
//
// 글꼴타입의 경우, 숫자로 표현하기 때문에 '+'와 '-'를 통해
// 값을 추가, 삭제할 수 있습니다.
//
// 참고로, Font.BOLD는 Font클래스의 static 변수 BOLD를 뜻함.
f.getFontName(), f.getStyle() + Font.BOLD, f.getSize() ));
else // cbxBold가 체크되어 있지 않으면(false)
txtResult.setFont(new Font(
f.getFontName(), f.getStyle() - Font.BOLD, f.getSize() ));
}
if (obj == cbxItalic) {
if (cbxItalic.getState())
txtResult.setFont(new Font(
f.getFontName(), f.getStyle() + Font.ITALIC, f.getSize() ));
else
txtResult.setFont(new Font(
f.getFontName(), f.getStyle() - Font.ITALIC, f.getSize() ));
}
} catch (ClassCastException ce) { }
// 글자 색상, 사이즈 이벤트 처리
try {
Choice obj = (Choice)e.getSource();
if (obj == chFontColor)
txtResult.setForeground(colorList[chFontColor.getSelectedIndex()]);
if (obj == chFontSize) {
Font f = txtResult.getFont();
txtResult.setFont(new Font(
f.getFontName(),
f.getStyle(),
Integer.parseInt(chFontSize.getSelectedItem()) ));
}
} catch (ClassCastException ce) { }
}
// 윈도우 X 버튼을 눌렀을 때 창을 닫아주도록 하는 부분입니다.
class WindowHandler extends WindowAdapter {
public void windowClosing(WindowEvent e) { System.exit(0); }
}
public static void main(String[] args) {
new AWTNotepad("AWT NotePad");
}
}
