명품 JAVA Essential 1
2 학습목표 1. 자바의이벤트기반 GUI 프로그램구조이해 2. 이벤트와이벤트객체 3. 이벤트리스너작성 4. 어댑터클래스로리스너작성 5. Key 이벤트로키입력받기 6. Mouse 이벤트로마우스동작인식
이벤트기반프로그래밍 3 이벤트기반프로그래밍 (Event Driven Programming) 이벤트의발생에의해프로그램흐름이결정되는방식 이벤트가발생하면이벤트를처리하는루틴 ( 이벤트리스너 ) 실행 실행될코드는이벤트의발생에의해전적으로결정반대되는개념 : 배치실행 (batch programming) 프로그램의개발자가프로그램의흐름을결정하는방식이벤트종류 사용자의입력 : 마우스드래그, 마우스클릭, 키보드누름등 센서로부터의입력, 네트워크로부터데이터송수신 다른응용프로그램이나다른스레드로부터의메시지 이벤트기반응용프로그램의구조 각이벤트마다처리하는리스너코드보유 GUI 응용프로그램은이벤트기반프로그래밍으로작성됨 GUI 라이브러리종류 C++ 의 MFC, C# GUI, Visual Basic, X Window, Android 등 자바의 AWT와 Swing
스윙응용프로그램의이벤트의실제예 4 마우스로메뉴선택 (Mouse Event, Action Event) 마우스로버튼클릭 (Mouse Event, Action Event) 마우스로윈도우크기조절 (Mouse Event, Container Event) 키보드입력 (Key Event) 키보드로메뉴선택 (Key Event, Action Event)
자바스윙프로그램에서이벤트처리과정 5 이벤트가처리되는과정 이벤트발생 예 : 마우스의움직임혹은키보드입력 이벤트객체생성 현재발생한이벤트에대한정보를가진객체 응용프로그램에작성된이벤트리스너찾기 이벤트리스너실행 리스너에이벤트객체전달 리스너코드실행
6 자바의이벤트기반스윙응용프로그램의구조와이벤트처리과정
이벤트객체 7 이벤트객체 발생한이벤트에관한정보를가진객체이벤트리스너에전달됨 이벤트리스너코드가발생한이벤트에대한상황을파악할수있게함 이벤트객체가포함하는정보 이벤트종류와이벤트소스이벤트가발생한화면좌표및컴포넌트내좌표이벤트가발생한버튼이나메뉴아이템의문자열클릭된마우스버튼번호및마우스의클릭횟수키의코드값과문자값체크박스, 라디오버튼등과같은컴포넌트에이벤트가발생하였다면체크상태 이벤트소스를알아내는메소드 Object getsource() 발생한이벤트의소스컴포넌트리턴 Object 타입으로리턴하므로캐스팅하여사용 모든이벤트객체에대해적용
이벤트객체와이벤트정보를리턴하는메소드 8 EventObject Object getsource() AWTEvent ActionEvent String getactioncommand() ComponentEvent InputEvent int getmodifiers() ItemEvent Object getitem() int getstatechange() MouseEvent int getbutton() int getclickcount() Point getpoint() int getx() int gety() KeyEvent char getkeychar() int getkeycode() String getkeytext()
9 이벤트객체, 이벤트소스, 발생하는경우
리스너인터페이스 10 이벤트리스너 이벤트를처리하는자바프로그램코드, 클래스로작성 자바는다양한리스너인터페이스제공 예 ) ActionListener 인터페이스 버튼클릭이벤트를처리하기위한인터페이스 interface ActionListener { // 아래메소드를개발자가구현해야함 public void actionperformed(actionevent e); // Action 이벤트발생시호출됨 예 ) MouseListener 인터페이스 마우스조작에따른이벤트를처리하기위한인터페이스 interface MouseListener { // 아래의 5 개메소드를개발자가구현해야함 public void mousepressed(mouseevent e); // 마우스버튼이눌러지는순간호출 public void mousereleased(mouseevent e); // 눌러진마우스버튼이떼어지는순간호출 public void mouseclicked(mouseevent e); // 마우스가클릭되는순간호출 public void mouseentered(mouseevent e); // 마우스가컴포넌트위에올라가는순간호출 public void mouseexited(mouseevent e); // 마우스가컴포넌트위에서내려오는순간호출 사용자의이벤트리스너작성 자바의리스너인터페이스 (interface) 를상속받아구현리스너인터페이스의모든추상메소드구현
11 자바에서제공하는이벤트리스너인터페이스
이벤트리스너작성과정사례 12 1. 이벤트와이벤트리스너선택 버튼클릭을처리하고자하는경우 이벤트 : Action 이벤트, 이벤트리스너 : ActionListener 2. 이벤트리스너클래스작성 : ActionListener 인터페이스구현 class MyActionListener implements ActionListener { public void actionperformed(actionevent e) { // 버튼이클릭될때호출되는메소드 JButton b = (JButton)e.getSource(); // 사용자가클릭한버튼알아내기 if(b.gettext().equals("action")) // 버튼의문자열이 "Action" 인지비교 b.settext(" 액션 "); // JButton의 settext() 호출. 문자열변경 else b.settext("action"); // JButton의 settext() 호출. 문자열변경 3. 이벤트리스너등록 이벤트를받아처리하고자하는컴포넌트에이벤트리스너등록 component.addxxxlistener(listener) xxx : 이벤트명, listener : 이벤트리스너객체 MyActionListener listener = new MyActionListener(); // 리스너인스턴스생성 btn.addactionlistener(listener); // 리스너등록
이벤트리스너작성방법 13 3 가지방법 독립클래스로작성 이벤트리스너를완전한클래스로작성 이벤트리스너를여러곳에서사용할때적합 내부클래스 (inner class) 로작성 클래스안에멤버처럼클래스작성 이벤트리스너를특정클래스에서만사용할때적합 익명클래스 (anonymous class) 로작성 클래스의이름없이간단히리스너작성 클래스조차만들필요없이리스너코드가간단한경우에적합
예제 9-1 : 독립클래스로 Action 이벤트리스너만들기 import java.awt.*; import java.awt.event.*; import javax.swing.*; 14 버튼클릭 독립된클래스로 Action 이벤트리스너작성 이클래스를별도의 MyActionListener.java 파일로작성하여도됨 public class IndepClassListener extends JFrame { IndepClassListener() { settitle("action 이벤트리스너예제 "); setdefaultcloseoperation(jframe.exit_on_close); Container c = getcontentpane(); c.setlayout(new FlowLayout()); JButton btn = new JButton("Action"); btn.addactionlistener(new MyActionListener()); c.add(btn); setsize(250, 120); setvisible(true); public static void main(string [] args) { new IndepClassListener(); Action 이벤트리스너등록 Action 이벤트리스너구현 // 독립된클래스로이벤트리스너를작성한다. class MyActionListener implements ActionListener { public void actionperformed(actionevent e) { JButton b = (JButton)e.getSource(); if(b.gettext().equals("action")) b.settext(" 액션 "); else b.settext("action");
예제 9-2 : 내부클래스로 Action 이벤트리스너만들기 15 버튼의문자열을타이틀에출력 Action 이벤트리스너를내부클래스로작성 private 으로선언하여외부에서사용할수없게함 리스너에서 InnerClassListener 와 JFrame 멤버에대한접근용이 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class IndepClassListener extends JFrame { IndepClassListener() { settitle("action 이벤트리스너예제 "); setdefaultcloseoperation(jframe.exit_on_close); Container c = getcontentpane(); c.setlayout(new FlowLayout()); JButton btn = new JButton("Action"); btn.addactionlistener(new MyActionListener()); c.add(btn); setsize(250, 120); setvisible(true); // 내부클래스로 Action 리스너를작성한다. private class MyActionListener implements ActionListener { public void actionperformed(actionevent e) { JButton b = (JButton)e.getSource(); if(b.gettext().equals("action")) b.settext(" 액션 "); else b.settext("action"); // InnerClassListener나 JFrame의멤버호출가능 settitle(b.gettext()); // 프레임타이틀에버튼문자열출력 public static void main(string [] args) { new IndepClassListener();
익명클래스로이벤트리스너작성 16 익명클래스 (anonymous class) : 이름없는클래스 ( 클래스선언 + 인스턴스생성 ) 을한번에달성 new 익명클래스의슈퍼클래스이름 ( 생성자인자들 ) {... 익명클래스의멤버구현... ; 간단한리스너의경우익명클래스사용추천 메소드의개수가 1, 2 개인리스너 (ActionListener, ItemListener) 에대해주로사용 ActionListener 를구현하는익명의이벤트리스너작성예 class MyActionListener implements ActionListener { public void actionperformed(actionevent e) {... 메소드구현... b.addactionlistener(new MyActionListener ()); (a) 이름을가진클래스를작성하고클래스인스턴스를생성하는경우 익명클래스작성 ( 클래스선언과인스턴스생성을동시에 ) 익명클래스 b.addactionlistener(new ActionListener() { public void actionperformed(actionevent e) {... 메소드구현... ); (b) ActionListener 를상속받아메소드를작성하는동시에 new 로인스턴스를생성하는경우
예제 9-3 : 익명클래스로 Action 이벤트리스너만들기 익명클래스로 ActionListener 리스너작성 btn.addactionlistener(new ActionListener() { public void actionperformed(actionevent e) { JButton b = (JButton)e.getSource(); if(b.gettext().equals("action")) b.settext(" 액션 "); else b.settext("action"); // AnonymousClassListener 나 // JFrame 의멤버를호출가능 settitle(b.gettext()); ); import java.awt.*; import java.awt.event.*; import javax.swing.*; public class IndepClassListener extends JFrame { IndepClassListener() { settitle("action 이벤트리스너예제 "); setdefaultcloseoperation(jframe.exit_on_close); Container c = getcontentpane(); c.setlayout(new FlowLayout()); JButton btn = new JButton("Action"); c.add(btn); setsize(250, 120); setvisible(true); // 내부클래스로 Action 리스너를작성한다. private class MyActionListener implements ActionListener { public void actionperformed(actionevent e) { JButton b = (JButton)e.getSource(); if(b.gettext().equals("action")) b.settext(" 액션 "); else b.settext("action"); 17 // InnerClassListener나 JFrame의멤버를호출가능 settitle(b.gettext()); // 프레임타이틀에버튼문자열출력 public static void main(string [] args) { new IndepClassListener();
18 예제 9-4 : 마우스이벤트리스너작성연습 - 마우스로문자열이동시키기 아래실행화면과같이프레임의임의의위치에마우스버튼을누르면마우스포인터가있는위치에 "Hello" 문자열을출력하는프로그램을작성하라. 초기화면마우스다른곳에클릭한경우마우스다른곳에클릭한경우 마우스버튼을누르면마우스가있는위치로 "Hello" 문자열을이동시킨다. 이벤트와리스너 : MouseEvent 와 MouseListener 이벤트소스 : 컨텐트팬 컨텐트팬의배치관리자 : 배치관리자삭제 구현할리스너의메소드 : mousepressed() "Hello" 문자열 : JLabel 컴포넌트이용
예제 9-4 의정답 19 import java.awt.*; import java.awt.event.*; import javax.swing.*; 마우스버튼이눌러진위치를알아내어 "Hello" 를옮긴다. MouseListener 의 5 개메소드를모두구현한다. public class MouseListenerEx extends JFrame { JLabel la = new JLabel("Hello"); // "Hello" 출력용레이블 MouseListenerEx() { settitle("mouse 이벤트예제 "); setdefaultcloseoperation(jframe.exit_on_close); Container c = getcontentpane(); c.addmouselistener(new MyMouseListener()); c.setlayout(null); la.setsize(50, 20); // 레이블의크기 50x20 설정 la.setlocation(30, 30); // 레이블의위치 (30,30) 으로설정 c.add(la); setsize(200, 200); setvisible(true); class MyMouseListener implements MouseListener { public void mousepressed(mouseevent e) { int x = e.getx(); // 마우스의클릭좌표 x int y = e.gety(); // 마우스의클릭좌표 y la.setlocation(x, y); // (x,y) 위치로레이블이동 public void mousereleased(mouseevent e) { public void mouseclicked(mouseevent e) { public void mouseentered(mouseevent e) { public void mouseexited(mouseevent e) { public static void main(string [] args) { new MouseListenerEx();
어댑터클래스 20 이벤트리스너구현에따른부담 리스너의추상메소드를모두구현해야하는부담 예 ) 마우스리스너에서마우스가눌러지는경우 (mousepressed()) 만처리하고자하는경우에도나머지 4 개의메소드를모두구현해야하는부담 어댑터클래스 (Adapter) 리스너의모든메소드를단순리턴하도록만든클래스 (JDK 에서제공 ) MouseAdapter 예 MouseListener 메소드 MouseMotionListener 메소드 MouseWheelListener 메소드 class MouseAdapter implements MouseListener, MouseMotionListener, MouseWheelListener { public void mousepressed(mouseevent e) { public void mousereleased(mouseevent e) { public void mouseclicked(mouseevent e) { public void mouseentered(mouseevent e) { public void mouseexited(mouseevent e) { public void mousedragged(mouseevent e) { public void mousemoved(mouseevent e) { public void mousewheelmoved(mousewheelevent e) { 추상메소드가하나뿐인리스너는어댑터없음 ActionAdapter, ItemAdapter 클래스는존재하지않음
MouseListener 대신 MouseAdapter 를사용한예 21 JLabel la; contentpane.addmouselistener(new MyMouseListener());.. class MyMouseListener implements MouseListener { public void mousepressed(mouseevent e) { int x = e.getx(); int y = e.gety(); la.setlocation(x, y); public void mousereleased(mouseevent e) { public void mouseclicked(mouseevent e) { public void mouseentered(mouseevent e) { public void mouseexited(mouseevent e) { JLabel la; contentpane.addmouselistener(new MyMouseAdapter());.. class MyMouseAdapter extends MouseAdapter { public void mousepressed(mouseevent e) { int x = e.getx(); int y = e.gety(); la.setlocation(x, y); MouseAdapter 를이용한경우 MouseListener 를이용한경우
22 JDK 에서제공하는어댑터클래스
예제 9-5 : MouseAdapter 로마우스리스너작성 23 MouseAdapter 를이용하여예제 9-4 를수정하라. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MouseAdapterEx extends JFrame { JLabel la = new JLabel("Hello"); // "Hello" 출력용레이블 MouseListenerEx() { settitle("mouse 이벤트예제 "); setdefaultcloseoperation(jframe.exit_on_close); Container c = getcontentpane(); c.addmouselistener(new MyMouseAdapter()); class MyMouseAdapter extends MouseAdapter { public void mousepressed(mouseevent e) { int x = e.getx(); int y = e.gety(); la.setlocation(x, y); public static void main(string [] args) { new MouseAdapterEx(); c.setlayout(null); la.setsize(50, 20); // 레이블의크기 50x20 설정 la.setlocation(30, 30); // 레이블의위치 (30,30) 으로설정 c.add(la); setsize(200, 200); setvisible(true);
Key 이벤트와포커스 24 키입력시, 다음세경우각각 Key 이벤트발생 키를누르는순간누른키를떼는순간 누른키를떼는순간 (Unicode 키의경우에만 ) 키이벤트를받을수있는조건 모든컴포넌트현재포커스 (focus) 를가진컴포넌트가키이벤트독점 포커스 (focus) 컴포넌트나응용프로그램이키이벤트를독점하는권한컴포넌트에포커스설정방법 component.requestfocus(); // component 가키이벤트를받을수있게함
KeyListener 25 응용프로그램에서 KeyListener 를상속받아키리스너구현 KeyListener 의 3 개메소드 키리스너 (KeyListener) void keypressed(keyevent e) { // 이벤트처리루틴 키를누르는순간 누른키를떼는순간 누른키를떼는순간, Unicode 키가경우 void keyreleased(keyevent e) { // 이벤트처리루틴 void keytyped(keyevent e) { // 이벤트처리루틴 실행되는순서 : 컴포넌트에키이벤트리스너달기 component.addkeylistener(mykeylistener);
유니코드 (Unicode) 키 26 유니코드키의특징 국제산업표준 전세계의문자를컴퓨터에서일관되게표현하기위한코드체계 문자들에대해서만키코드값정의 A~Z, a~z, 0~9,!, @, & 등 문자가아닌키경우에는표준화된키코드값없음 <Function> 키, <Home> 키, <Up> 키,<Delete> 키, <Control> 키, <Shift> 키, <Alt> 등은플랫폼에따라키코드값이다를수있음 유니코드키가입력되는경우 keypressed(), keytyped(), keyreleased() 가순서대로호출 유니코드키가아닌경우 keypressed(), keyreleased() 만호출됨
가상키와입력된키판별 27 KeyEvent 객체 입력된키정보를가진이벤트객체 KeyEvent 객체의메소드로입력된키판별 KeyEvent 객체의메소드로입력된키판별 char KeyEvent.getKeyChar() 키의유니코드문자값리턴 Unicode 문자키인경우에만의미있음 입력된키를판별하기위해문자값과비교하면됨 public void keypressed(keyevent e) { if(e.getkeychar() == 'q') System.exit(0); q 키가누르면프로그램종료 int KeyEvent.getKeyCode() 유니코드키포함 모든키에대한정수형키코드리턴 입력된키를판별하기위해가상키 (Virtual Key) 값과비교하여야함 가상키값은 KeyEvent 클래스에상수로선언 public void keypressed(keyevent e) { if(e.getkeycode() == KeyEvent.VK_F5) System.exit(0); F5 키를누르면프로그램종료
가상키 (Virtual Key) 28 가상키는 KeyEvent 클래스에상수로선언 가상키의일부소개
예제 9-6 : KeyListener 활용 입력된문자키판별 29 컨텐트팬에 <Enter> 키를입력할때마다배경색을랜덤하게바꾸고, 'q' 키를입력하면프로그램을종료시켜라. 'q' 키를입력하면프로그램종료 컨텐트팬에키리스너를달고, 포커스를주어, 키입력을받도록해야한다. 색은 new Color(int r, int g, int b) 로생성한다. r(red), g(green), b(blue) 는색의 3 요소로서 0~255 사이의값이다.
예제 9-6 정답 30 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class KeyCharEx extends JFrame { JLabel la = new JLabel("<Enter> 키로배경색이바뀝니다 "); KeyCharEx() { super("keylistener 의문자키입력예제 "); setdefaultcloseoperation(jframe.exit_on_close); Container c = getcontentpane(); c.setlayout(new FlowLayout()); c.add(la); c.addkeylistener(new MyKeyListener()); setsize(250, 150); setvisible(true); c.requestfocus(); // 컨텐트팬에포커스설정 class MyKeyListener extends KeyAdapter { public void keypressed(keyevent e) { // 임의의색을만들기위해랜덤하게 r, g, b 성분생성 int r = (int) (Math.random() * 256); // red 성분 int g = (int) (Math.random() * 256); // green 성분 int b = (int) (Math.random() * 256); // blue 성분 switch(e.getkeychar()) { // 입력된키문자 case '\n': // <Enter> 키입력 la.settext("r=" + r + ", g=" + g + ", b=" + b); getcontentpane().setbackground( new Color(r, g, b)); break; case 'q': System.exit(0); public static void main(string[] args) { new KeyCharEx();
31 예제 9-7 : KeyListener 활용 상 ( ), 하 ( ), 좌 ( ), 우 ( ) 키로문자열움직이기 상 ( ), 하 ( ), 좌 ( ), 우 ( ) 키를입력하면, 다음그림과같이 "HELLO" 문자열이 10 픽셀씩이동하는프로그램을작성하라. (50,50) 초기상태 상, 하, 좌, 우키를여러번입력하여 "HELLO" 를움직인상태 상, 하, 좌, 우키를움직이면한번에 10 픽셀씩 "HELLO" 텍스트는상, 하, 좌, 우로이동한다. 이텍스트는프레임의영역을벗어나서움직일수있다.
예제 9-7 정답 32 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class FlyingTextEx extends JFrame { JPanel contentpane = new JPanel(); JLabel la = new JLabel("HELLO"); FlyingTextEx() { super(" 상, 하, 좌, 우키를이용하여텍스트움직이기 "); setdefaultcloseoperation(jframe.exit_on_close); setcontentpane(contentpane); contentpane.setlayout(null); contentpane.addkeylistener(new MyKeyListener()); la.setlocation(50, 50); la.setsize(100, 20); contentpane.add(la); setsize(200, 200); setvisible(true); class MyKeyListener extends KeyAdapter { public void keypressed(keyevent e) { int keycode = e.getkeycode(); // 입력된키코드 switch(keycode) { case KeyEvent.VK_UP: la.setlocation(la.getx(), la.gety() - 10); break; case KeyEvent.VK_DOWN: la.setlocation(la.getx(), la.gety() + 10); break; case KeyEvent.VK_LEFT: la.setlocation(la.getx() - 10, la.gety()); break; case KeyEvent.VK_RIGHT: la.setlocation(la.getx() + 10, la.gety()); break; public static void main(string [] args) { new FlyingTextEx(); contentpane.requestfocus(); // 포커스지정
Mouse 이벤트와 MouseListener, MouseMotionListener 33 Mouse 이벤트 : 사용자의마우스조작에따라발생하는이벤트 mouseclicked() : 마우스가눌러진위치에서그대로떼어질때호출 mousereleased() : 마우스가눌러진위치에서그대로떼어지든아니든항상호출 mousedragged(): 마우스가드래그되는동안계속여러번호출 마우스가눌러진위치에서떼어지는경우메소드호출순서 책과다른부분입니다. mousepressed(), mousereleased(), mouseclicked() 마우스가드래그될때호출되는메소드호출순서 mousepressed(), mousedragged(), mousedragged(),..., mousedragged(), mousereleased(), mouseclicked()
마우스리스너달기와 MouseEvent 객체활용 34 마우스리스너달기 마우스리스너는컴포넌트에다음과같이등록 component.addmouselistener(mymouselistener); 컴포넌트가마우스무브 (mousemoved()) 나마우스드래깅 (mousedraggecd()) 을함께처리하고자하면, MouseMotion 리스너따로등록 component.addmousemotionlistener(mymousemotionlistener); MouseEvent 객체활용 마우스포인터의위치, 컴포넌트내상대위치 int getx(), int gety() 마우스클릭횟수 int getclickcount() public void mousepressed(mouseevent e) { int x = e.getx(); // 마우스가눌러진 x 좌표 int y = e.gety(); // 마우스가눌러진 y 좌표 public void mouseclicked(mouseevent e) { if(e.getclickcount() == 2) {... // 더블클릭처리루틴
마우스이벤트처리예 : MouseListener 와 MouseMotionListener import javax.swing.*; import java.awt.event.*; import java.awt.*; public class MouseEventAllEx extends JFrame { JLabel la = new JLabel(" Move Me"); 35 MouseEventAllEx() { settitle("mouselistener 와 MouseMotionListener 예제 "); setdefaultcloseoperation(jframe.exit_on_close); Container c = getcontentpane(); MyMouseListener listener = new MyMouseListener(); c.addmouselistener(listener); c.addmousemotionlistener(listener); c.setlayout(null); la.setsize(80,20); la.setlocation(100,80); c.add(la); // 레이블컴포넌트삽입 setsize(300,200); setvisible(true); class MyMouseListener implements MouseListener, MouseMotionListener { public void mousepressed(mouseevent e) { la.setlocation(e.getx(), e.gety()); settitle("mousepressed("+e.getx()+","+e.gety()+")"); public void mousereleased(mouseevent e) { la.setlocation(e.getx(), e.gety()); settitle("mousereleased("+e.getx()+","+e.gety()+")"); public void mouseclicked(mouseevent e) { public void mouseentered(mouseevent e) { Component comp = (Component)e.getSource(); comp.setbackground(color.cyan); public void mouseexited(mouseevent e) { Component comp = (Component)e.getSource(); comp.setbackground(color.yellow); public void mousedragged(mouseevent e) { la.setlocation(e.getx(), e.gety()); settitle("mousedragged("+e.getx()+","+e.gety()+")"); public void mousemoved(mouseevent e) { la.setlocation(e.getx(), e.gety()); settitle("mousemoved ("+e.getx()+","+e.gety()+")"); public static void main(string [] args) { new MouseEventAllEx();
마우스이벤트처리실행 36 마우스좌표와이벤트처리메소드 (10,10) (198,94) 초기화면 mouseentered() 에의해배경색변경. 마우스버튼이눌러진순간 눌러진마우스버튼이떼어진순간 (88,96) (103,90) 마우스가컨텐트팬위에드래깅하는동안 마우스가컨텐트팬위에이동하는동안 마우스가컨텐트팬을벗어나면 mouseexited() 에의해배경색변경