10장_자바의 이벤트 처리

IkSun·2023년 5월 30일

CHAPTER 10 자바의 이벤트 처리

10.1 이벤트 기반 프로그래밍(Event Driven Programming)
10.2 이벤트 객체
10.3 이벤트 리스너
10.4 어댑터(Adapter) 클래스
10.5 KeyEvent와 KeyListener
10.6 MouseEvent와 MouseListener, MouseMotionListener, MouseWheelListener


이벤트 기반 프로그래밍

  • 이벤트 기반 프로그래밍
    • 이벤트의 발생에 의해서 프로그램 흐름이 결정되는 방식
    • ex) 컴포넌트를 화면에 내보냈는데, "클릭", "텍스트 입력"과 같은것들을 어떻게 처리할 것인지가 이벤트 프로그래밍
      • 이벤트가 발생하면 이벤트를 처리하는 루틴(이벤트 리스너)실행
      • 프로그램 내의 어떤 코드가 언제 실행될 지 아무도 모름, 이벤트 발생에 의해 전적으로 결정
    • 반대되는 개념 : 배치 실행 (batch programming)
      • 프로그램의 개발자가 프로그램의 흐름을 결정하는 방식. (실행되는 순서가 정해져 있다)
  • 이벤트 종류 : 다른 응용 프로그램이나 다른 스레드로부터의 메세지 등..
  • 이벤트 기반 프로그램의 구조
  • 이벤트 처리 순서

자바의 이벤트 기반 GUI 응용프로그램 구성

  1. 화면상의 new 버튼에 마우스 클릭
  2. 이벤트 분배 스레드를 통해서 어디서 발생한 것인지에 대한 것을 찾고
  3. 그 정보를 AcionEvnent 하는 객체를 만들어 이벤트 리스너 e 로 전달

<그림으로 흐름 파악하기>


이벤트 관련 용어

  • 이벤트 소스
    • 이벤트를 발생시킨 GUI 컴포넌트 (JButton)
  • 이벤트 객체
    • 발생한 이벤트에 대한 정보 (ActionEvent)
      • 예) 이벤트 종류, 이벤트 소스, 화면 좌표, 마우스 버튼 종류, 눌러진 키
  • 이벤트 리스너
    • 이벤트를 처리하는 코드 (이벤트 리스너4)
    • 컴포넌트에 등록되어야 작동 가능
  • 이벤트 분배 스레드
    • 동작
      • JVM 으로부터 이벤트의 발생을 통지 받음
      • 이벤트 소스와 이벤트 종류 결정
      • 적절한 이벤트 객체 생성, 이벤트 리스너를 찾아 호출
    • 무한 루프를 실행하는 스레드

이벤트 객체

  • 이벤트 객체란?
    • 이벤트가 발생하면 발생한 이벤트에 관한 정보를 가진 객체
    • 이벤트 리스너에 전달됨
      • 이벤트 객체에서 이벤트가 발생한 여러 상황을 파악할 수 있게함
  • 이벤트 객체 종류
    • 컴포넌트들은 관련한 이벤트가 이미 다 지정되어있다, 어떤 컴포넌트는 여러개의 이벤트가 존재할 수 있다.

이벤트 객체 포함된 정보

  • 이벤트 객체가 포함하는 정보
    • 이벤트 종류
    • 이벤트 소스
    • 이벤트가 발생한 화면 좌표
    • 이벤트가 발생한 컴포넌트 내 좌표
    • 버튼이나 메뉴 아이템에 이벤트가 발생한 경우 버튼이나 메뉴 아이템의 문자열
    • 클릭된 마우스 버튼 번호
    • 마우스의 클릭 횟수
    • 키가 눌러졌다면 키의 코드 값 과 문자 값
    • 체크박스, 라디오버튼 등과 같은 컴포넌트에 이벤트가 발생하였다면 체크 상태
  • 이벤트에 따라 조금씩 다른 정보 포함
    • ActionEvent 객체 : 액션 문자열
    • MouseEvent객체 : 마우스의 위치 정보, 마우스 버튼, 함께 눌러진 키 정보 등
    • ItemEvent 객체 : 아이템의 체크 상태
  • 이벤트 소스 알아내기
    • object EventObject.getSource()
      • 발생한 이벤트의 소스 컴포넌트 리턴
      • Object 타입으로 리턴하므로 캐스팅하여 사용
      • 모든이벤트객체에대해적용

이벤트 객체의 메소드

이벤트 객체와 이벤트 소스

  • 체크박스에서 발생한 ItemEvent 객체
  • Component 이벤트 소스에서 발생한 FocusEvent 객체
  • 이렇게 미리 지정한 이벤트 객체가 지정한다.
  • 이런 이벤트 객체를 처리하는 것을 이벤트 리스너라고 한다.

이벤트 리스너

  • 이벤트 리스너란?
    • 이벤트를 처리하는 핸들러 코드
    • 클래스로 작성해야 함.
  • JDK 에서 이벤트 리스너 작성을 위한 인터페이스(interface) 제공
    • 개발자 리스너 인터페이스의 모든 추상 메소드를 구현해야 함
    • 이벤트가 발생하면 이미 약속된 (해당 이벤트와 연결된) 메소드 호출
    • 예) ActionListener 인터페이스 \to ActionEvent 가 발생하면 자동 호출됨!
      interface ActionListener { //포함된 메소드를 개발자가 상속 받아서 구현해야 한다.
          //Action 이벤트 발생시 자동 호출됨
          public void actionPerformed(ActionEvent e); 
      }
    • 예) MouseListener 인터페이스
      interface MouserListener { //아래의 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); //마우사가 컴포넌트 위애서 내려오는 순간 호출
       }
       //이벤트 소스가 여러개라면, 여러개의 객체를 생성해야하는데? 다음과 같이 인터페이스로 구현한다.
       //이미 다 지정이 다 되어있어서 해당 인터페이스에 맞는 메소드가 각 순간에 호출된다.

이벤트 리스너 등록

  • 이벤트 리스너 등록
    • 이벤트를 받아 처리하고자 하는 컴포넌트에 이벤트 리스너 등록
  • 이벤트 리스너 등록 메소드
    • Component.addXXXListener(listener)
      • XXX : 이벤트 명
      • listener : 이벤트 리스너 객체
      • 예) addMouseListener(), addActionListener() 등
  • 이벤트 리스너가 등록된 컴포넌트에만 이벤트 전달
    • 이벤트 리스너가 등록된 컴포넌트만 이벤트 리스너 코드 작동
  • Tip. 리스너 등록 메소드가 addXXXListener 인 이유?
    • 한 컴포넌트는 서로 다른 이벤트에 대한 리스너를 동시애 여러개 가질 수 있다
      JButton.addActionListener();  //Action 리스너
       JButton.addKeyListener();  //Key 리스너
       JButton.addFocusListener();  //Focus 리스너
    • 한 컴포넌트는 한 이벤트에 대해 여러 개의 리스너를 동시에 가질 수 있다.
      JButton.addActionListener(new MyButtonListener1());
       JButton.addActionListener(new MyButtonListener2());
       JButton.addActionListener(new MyButtonListener3());
       //이때, 리스너는 등록된 반대 순으로 모두 실행된다.

리스너 인터페이스와 메소드

이벤트 리스너 작성 방법

  • 3가지 방법
    • 독립된 클래스로 작성
      • 이벤트 리스너를 완전한 클래스로 작성
      • 이벤트 리스너를 여러 곳에서 사용할 때 적합
    • 내부 클래스(Inner class)로 작성
      • 클래스 안에 멤버처럼 클래스 작성
      • 이벤트 리스너를 특정 클래스에서만 사용할 때 적합
    • 익명 클래스(anonymous class)로 작성
      • 클래스의 이름 없이 간단한 리스너 작성
      • 클래스 조차 만들 필요 없이 리스너 코드가 간단한 경우에 적합

예제 10-1 : 독립 클래스로 Action 이벤트의 리스너 작성

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class IndepClassListener extends JFrame {
	public IndepClassListener(){  //초기값 정보 설정
		setTitle("Action 이벤트 리스너 예제");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Container c = getContentPane();  //기본적인 컨텐트 팬 설정(<- 컴포넌트를 등록하기 위해)
		c.setLayout(new FlowLayout());  //레이아웃 설정
		JButton btn = new JButton("Action"); //버튼 관리
		btn.addActionListener(new MyActionListener()); //Action 이벤트 리스너 달기
        //-> 각 컴포넌트가 가지고 있는 전용 이벤트를 처리히해줄 리스너(메소드)를 안내
        //-> 
		c.add(btn);  //컨텐트 팬에 버튼을 등록 시킴
		
		setSize(350, 150);  //화면을 조정하여 처음 보여줌
		setVisible(true);
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new IndepClassListener();
	}
} 


//독립된 클래스로 이벤트 리스너()를 작성한다.
class MyActionListener implements ActionListener {
	public void actionPerformed(ActionEvent e) {  //버튼에 클릭이 발생했다라고 하는 정보(발생시간, 좌표 등등..) 가 e 에게 제공됨
		JButton b = (JButton)e.getSource();  //이벤트 소스 버튼 알아내기(이벤트가 어디서 발생한 버튼 인지를 알아오고 그것에 b로 접근)
		if(b.getText().equals("Action")) //버튼의 문자열이 영문 "Action" 인지 비교
			b.setText("액션");  // 버튼의 문자열을 "액션"으로 변경 
		else
			b.setText("Action"); //버튼의 문자열을 "Action" 으로 변경
	}
}


예제 10-2 : 내부 클래스로 Action 이벤트 리스너 만들기

  • 내부 클래스로 만들었기 때문에 타이틀을 변경할 수 있다.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class InnerClassListener extends JFrame {
    InnerClassListener() {
    	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(350, 150);
		setVisible(true);
	}
    //Action 이벤트 리스너를 내부 클래스로 작성
    //private 으로 선언하여 InnerClassListener 외부에서 사용할 수 없게 함
    private class MyActionListener implements ActionListener {
    	public void actionPerformed(ActionEvent e) {
    		JButton b = (JButton)e.getSource(); //이벤트가 발생했을 때 버튼에 대한 접근 참조변수 b 로 
    		if(b.getText().equals("Action")) //버튼의 문자열이 "Action" 인지 비교
    			b.setText("액션");  // 버튼의 문자열을 "액션"으로 변경 
    		else
    			b.setText("Action"); //버튼의 문자열을 "Action" 으로 변경
    		
            //이 코드가 하나 더 추가됨
            //InnerClassListener 의 멤버나 JFrame 의 멤버를 호출할 수 있음
            //프레임 타이틀에 버튼 문자열을 출력한다.
    		InnerClassListener.this.setTitle(b.getText());
    	}
	}
    
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new InnerClassListener();
	}	
}


익명 클래스로 리스너 작성

  • 익명 클래스란?
    • (클래스 정의 + 인스턴스 생성)을 한번에 작성
      new 익명클래스의수퍼클래스이름(생성자의 인자들)----
           클래스 정의
           ----
      }
    • ActionListener를 구현하는 익명의 이벤트 리스너 작성 예

예제 10-4 : 마우스로 문자열 이동시키기 - 마우스 이벤트 연습

컨텐트팬의 아무 위치에 마우스 버튼을 누르면 마우스 포인트가 있는 위치로 "hello" 문자열을 옮기는 스윙 응용프로그램을 작성하라.

  • 마우스 버튼을 누르면 마우스가 있는 위치로 “hello” 문자열을 이동시킨다.
  • 이벤트와 리스너 : MouseEvent와 MouseListener
  • 이벤트 소스 : JPanel
  • 구현할 리스너의 메소드 : mousePressed() 하나
  • “hello” 문자열 : JLabel 컴포넌트 이용
  • 컨텐트 팬 : JPanel로 교체, 배치관리자 null로 설정
    • 내가 원하는 위치에 배치해야하니까 레이아웃 널로 설정

응용프로그램에 마우스 클릭이라는 이벤트가 발생을 처리해주는 코드 추가

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class MouseListenerEx extends JFrame {
	private JLabel la = new JLabel("Hello"); /생성자와 내부 클래스 외부에 레이블을 미리 만들어놓음
	
	public MouseListenerEx() {
    	setTitle("Mouse 이벤트 리스너 예제");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Container c = getContentPane();  //지금 응용프로그램의 기본적인 패널 정보를 불러오기 - 그래야 부착이 가능하니까
		c.addMouseListener(new MyMouseListener());
        // -> 내 컨텐츠 팬에 마우스가 눌러졌을때의 그 이벤트를 어떻게 처리할지 제공
        // 미리 5가지 정보를 정의 부분에 제공됨
        // 나는 눌러졌을 떄의 정보만 제공해줄 것이기 때문에 
        // 일단 다 호출하고 그 중 mousePressed 호출
        
		c.setLayout(null);  //레이아웃을 아무것도 쓰지 않기
		la.setSize(50, 20);  //헬로 문자열의 위치
		la.setLocation(30,30);
		c.add(la);  //패널에 부착시켜서 눈에 보이도록 하기
		
		setSize(250, 250);  //윈도우의 크기 값
		setVisible(true);
	}
    
    //마우스 버튼이 눌러진 위치를 알아내어 la("Hello" 문자열)를 그 위치로 옮긴다.  
	class MyMouseListener implements MouseListener {
		public void mousePressed(MouseEvent e) {  //이벤트를 e 로 받고
			int x = e.getX();  //객체의 x,y 정보를 얻어와서 x,y 에 보관
			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) {}
		
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new MouseListenerEx();
	}	
}

어댑터 클래스

  • 인터페이스를 묶어서 어댑터라는 정보를 제공 (인터페이스들을 구현을 하는 마우스 어댑터 클래스)
  • 필요한 정보만 작성하면 된다.

  • 메소드가 하나 있는것은 굳이 ㅇ댑터를 사용할 필요 없음
    • actionPerfomed() 는 어댑터 만들 필요 없음

어댑터 사용 예

  • 어댑터를 상속받아서 MyMouserAdapter 라는 클래스를 만들때 내가 작성하고 싶은 mousePressed 를 오버라이딩 한다.
    • 즉, 어댑터를 상속을 받아서 코딩한 예제 전 예제와 똑같은 코드 -> 말로만 설명

예제 10-5 : MouseAdapter 사용하기

패스


key 이벤트와 포커스

  • 눌렀다, 떨어졌다, 떼는순간 유니코드인 경우 이렇게 3가지의 키 이벤트 발생

  • 키 입력은 화면상의 변화가 아니기 때문에 포커스를 받아야지만 키 입력이 가능

  • 키 입력을 가지고 포커를 가진 컴포넌트가 그걸 받아서 무언가 할수 있다.

  • 컨텐츠 팬에 포커스를 강제로 지정해서 그 정보를 활용해서 타입핑한것이 반영하도록 다음 코드가 반드시 필요

  • 가상키를 활용해서 유니코드값이 없는 키 문제 해결

    • 화살표, 홈페이지를 이해시키기위해 가상키(KeyEvent 클래스에 상수로 정의되어있음) 사용

예제 10-6 : 다양한 KeyEvent 와 KeyListener 활용

  • Home 키
    • 키코드 36
    • 대응하는 유니코드가 없음
    • Home 키의 키보드에 표시된 이름 문자열
  • 포커스 추가 설정 이유
    • 포커스 추가 설정을 하지 않으면 입력이 안되는 경우 발생
    • 이를 방지하기 위하여 추가로 설정
  • JComponent 컴포넌트에 바탕색을 지정하기 위해서는 사전에 컴포넌트가 불투명하게 지정하여야 한다.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class KeyListenerEx extends JFrame {
	private JLabel [] keyMessage;  //3개의 메세지를 출력할 레이블 컴포넌트 배열
	
	public KeyListenerEx() {
    	setTitle("KeyListener 예제");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		Container c = getContentPane();
		c.setLayout(new FlowLayout());
		c.addKeyListener(new MyKeyListener());
			
        // 레이블 배열을 3개 생성하고 각 레이블 컴포넌트 생성    
		keyMessage = new JLabel[3]; //레이블 배열 생성
		keyMessage[0] = new JLabel("getKeyCode() ");
		keyMessage[1] = new JLabel("getKeyChar() ");
		keyMessage[2] = new JLabel("getKeyText() ");
        
		// 3개의 레이블 컴포넌트를 컨텐츠 팬에 부착
		for(int i = 0; i<keyMessage.length; i++) {
			c.add(keyMessage[i]);
            // 배경색이 보이도록 불투명 속성 강제 설정
			keyMessage[i].setOpaque(true);
			// 배경색 CYAN 색으로 변경
            keyMessage[i].setBackground(Color.YELLOW);
		}
		
		setSize(300, 150);
		setVisible(true);
		
        // 컨텐츠 팬이 키 입력을 받을 수 있도록 포커스 강제 지정 (꼭 필요한 코드)
		c.setFocusable(true);
		c.requestFocus();
	}
	//key 리스너 구현
	class MyKeyListener extends KeyAdapter {
		public void keyPressed(KeyEvent e) {
			int keyCode = e.getKeyCode();  //지금 눌러진 키 코드 알아내기
			char keyChar = e.getKeyChar(); //지금 눌러진 키 문자 값 알아내기
			
			//키 코드 출력			
    		keyMessage[0].setText(Integer.toString(keyCode));
			//키 문자 출력 -> 유니코드가 없으면 그냥 사각형이 나온다.			
            keyMessage[1].setText(Character.toString(keyChar));
            //키 이름 문자열 출력
			keyMessage[2].setText(KeyEvent.getKeyText(keyCode));
			
			System.out.println("KeyPressed"); //콘솔 : keyPressed 출력
		}
		
		public void keyReleased(KeyEvent e) {
			System.out.println("KeyReleased"); //콘솔 : keyReleased 출력
		}
		public void keyTyped(KeyEvent e) {
			System.out.println("KeyTyped"); //콘솔 : keyTyped 출력
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new KeyListenerEx();
	}
}

유니코드가 있는 경우

유니코드가 없는 경우

예제 10-7 : <F1> 키를 입력받으면 컨텐트팬의 배경을 초록색으로, % 키를 입력받으면 노란색으로 변경

import javax.swing.*; 
import java.awt.event.*; 
import java.awt.*;

public class KeyCodeEx extends JFrame { // 빈 레이블 컴포넌트 생성
	private JLabel la = new JLabel();
	
	public KeyCodeEx() {
			setTitle("Key Code 예제 : F1키:초록색, % 키 노란색"); 
			setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			Container c = getContentPane(); 
			c.addKeyListener( new MyKeyListener( ) ); 
			c.add(la);
			setSize(300,150);
			setVisible(true);
			// 컨텐트팬이 키 입력을 받을 수 있도록 포커스 강제 지정 
			c.setFocusable(true);
			c.requestFocus();
	}
	//Key 리스너 구현
	class MyKeyListener extends KeyAdapter {
		public void keyPressed(KeyEvent e) {
			Container contentPane = (Container)e.getSource();
			
			//la에 입력된 키의 키 이름 문자열을 출력하여 사용자에게 보고함 
			la.setText(KeyEvent.getKeyText(e.getKeyCode())+"키가 입력되었음");
			
			if(e.getKeyChar() == '%') // 입력된 키가 % 인 경우 
				contentPane.setBackground(Color.YELLOW);
			else if(e.getKeyCode() == KeyEvent.VK_F1) // <F1> 확인 
				contentPane.setBackground(Color.GREEN);
		}
	}
	public static void main(String [] args) { 
		new KeyCodeEx();
	}
}

shift + 5 -> 노란색
f1 -> 초록색

예제 10-8 : 상, 하, 좌, 우 키로 "HELLO" 문자열 움직이기

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class FlyingTextEx extends JFrame {
	private final int FLYING_UINT = 10;  //10픽셀 단위 이동
	private JLabel la = new JLabel("HELLO"); //레이블 컴포넌트
	
	public FlyingTextEx() {  
		setTitle("상, 하, 좌, 우 키를 이용하여 텍스트 움직이기");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		Container c = getContentPane();
		c.setLayout(null);  //컨텐트팬의 배치관리자 삭제
        //컨텐트팬에 key 리스너 달기
		c.addKeyListener(new MyKeyListener());  //키보드와 관련한 일은 MyKeyListener 에게 일을 시킴
		la.setLocation(50,50);  //la 초기 위치는 (50,50)
		la.setSize(100,20);
		c.add(la);
		setSize(300,300);
		setVisible(true);
		
		c.setFocusable(true); //컨텐트팬이 키 입력을 받을 수 있도록 포커스 강제 지정
		c.requestFocus(); //컨텐트팬에 포커스를 잏은 경우 마우스를 
        			// 클릭하면 다시 포커스를 얻게 함
		
        //익명 클래스로 작성
		c.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
           	    //마우스가 클릭된 컴포넌트
				Component c =(Component)e.getSource();
                //혹시 모르니까 이코드를 하나 더 추가해줌.
				c.setFocusable(true);
				c.requestFocus(); //컴포넌트에게 포커스 설정
			}
        });
	}
	
    //key 리스너 구현
	class MyKeyListener extends KeyAdapter {
		public void keyPressed(KeyEvent e) {
        	//입력된 키의 키코드를 알아낸다.
			int keyCode = e.getKeyCode();
			
            // 키 코드 값에 따라 상,하,좌,우 키를 판별하고
            // la의 위치를 이동시킨다.
			switch(keyCode) {
			case KeyEvent.VK_UP:  //위로 10픽셀 이동
				la.setLocation(la.getX(), la.getY() - FLYING_UINT);
				break;
			case KeyEvent.VK_DOWN:
				la.setLocation(la.getX(), la.getY() + FLYING_UINT);
				break;
			case KeyEvent.VK_LEFT:
				la.setLocation(la.getX() - FLYING_UINT, la.getY());
				break;
			case KeyEvent.VK_RIGHT:
				la.setLocation(la.getX() + FLYING_UINT, la.getY());
				break;
			}
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new FlyingTextEx();
	}

}

마우스 이벤트와 마우스 관련 리스너

  • Mouse 이벤트
    • 사용자가 마우스 조작에 따라 발생하는 이벤트
    • 마우스 드래그, 움직이는, 휠 구르는 이벤트
      • MouseMotionListener 라는 리스너가 처리해준다.
  • 마우스가 눌러진 위치에서 떼어지는 경우 메소드 호출 순서
mousePressed(), mouseReleased(), mouseClicked()
  • 마우스가 클릭되어 드래그 되는 동안 호출되는 메소드 순서
//드래그는 한픽셀이 이동할떄마다 계속적으로 발생
mousePressed(), mouseDragged(), mouseDragged(), ..., mouseReleased() 

마우스 리스너 달기

//<-- MouseListener의 5개의 이벤트를 처리하는 경우 -->
mouseEntered(), mouseExited(), mousePressed(), mouseReleased()., mouseClicked()

//마우스 리스너 등록
component.addMouseListener(myMouseListener);

//<-- MouseMotionListener의 이벤트도 함께 처리하고자 하는 경우 -->
mouseDragged(), mouseMoved()

//마우스 모션 리스너 등록 필요
component.addMouseMotionListener(myMouseMotionListener);

MouseEvent 객체로부터 얻을 수 있는 정보

//마우스 포인터의 위치
public void mousePressed(MouseEvent e) {
	int x = e.getX();
    int y = e.getY();
}

//입력된 마우스 버튼
public void mousePressed(MouseEvent e) {
	if(e.getButton() == MouseEvent.BUTTON1)
    	System.out.println("Left Button Pressed");
}
//BUTTON1 -> 왼쪽 마우스 버튼
//BUTTON3 -> 오른쪽 마우스 버튼 (wheel 버튼이 있으면)
//BUTTON2 -> wheel 마우스 버튼

//마우스 클릭 횟수
public void mouseClicked(MouseEvent e) {
	if(e.getClickCount() == 2) {
       //더블 클릭을 처리하는 루틴
    }
}

//팝업 메뉴 클릭
boolean isPopupTrigger();

예제 10-9 : 마우스와 마우스 모션 이벤트 활용

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class MouseListenerAllEx extends JFrame {
	//메세지 출력 레이블 컴포넌트
	private JLabel la = new JLabel("No Mouse Event");
	
	public MouseListenerAllEx() {
		setTitle("MouseListener와 MouseMotionListener 예제");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		Container c = getContentPane();
		c.setLayout(new FlowLayout());
		//리스너 객체 생성
		MyMouseListener listener = new MyMouseListener();
		//MouseListener 리스너 등록
		c.addMouseListener(listener);
		//MouseMotionListener 리스너 등록		
		c.addMouseMotionListener(listener);
		
		c.add(la);
		setSize(300, 200);
		setVisible(true);
	}
	//Mouse 리스너와 MouseMotion 리스너를 모두 가진 리스너 작성
	class MyMouseListener implements MouseListener, MouseMotionListener {
    	// MouseListener 의 5개 메소드 구현
		public void mousePressed(MouseEvent e) {
			la.setText("MousePressed (" + e.getX()+ ","+ e.getY() + ")");
		} //마우스가 눌러진 위치 (x,y) 점을 출력
		public void mouseReleased(MouseEvent e) {
			la.setText("MouseReleased (" + e.getX()+ ","+ e.getY() + ")");
		} //마우스가 뗴어진 위치 (x,y) 점을 출력
		public void mouseClicked(MouseEvent e) {}
		public void mouseEntered(MouseEvent e) { //마우스가 올라간
			Component c = (Component)e.getSource(); //컴포넌트를 알아낸다.
			c.setBackground(Color.CYAN);
		}
		public void mouseExited(MouseEvent e) { //마우스가 내려간
			Component c = (Component)e.getSource(); //컴포넌트를 알아낸다.
			c.setBackground(Color.YELLOW);
		}
        // MouseMotionListener 의 2개 메소드 구현
		public void mouseDragged(MouseEvent e) {
			la.setText("MouseDragged (" + e.getX()+ ","+ e.getY() + ")");
		} //마우스가 드래깅되는 동안 계속 호출
		public void mouseMoved(MouseEvent e) {
			la.setText("MouseMoved (" + e.getX()+ "," +e.getY() + ")");
		} //마우스가 움직이는 동안 계속 호출
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new MouseListenerAllEx();

	}

}

예제 10-10 : 더블 클릭 시 컨텐트팬의 배경색 변경

  • 마우스가 몇번 눌려졌는지 내부적으로 카운팅을 해서 2회가 되면 더블클릭으로 인식을 해서 해당하는 내부 색상 정보를 랜덤하게 설정.
  • 그 랜덤 색상 정보를 가지고 백그라운드 색상 정보 변경
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class ClickAndDoubleClickEx extends JFrame {
	
	public ClickAndDoubleClickEx() {
		setTitle("Click and DoubleClick 예제");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		Container c = getContentPane();
		c.addMouseListener(new MyMouseListener()); //Mouse 리스너 달기
		setSize(300, 200);
		setVisible(true);
	}
    // MouseAdapter 를 상속받아 Mouse 리스너 구현
	class MyMouseListener extends MouseAdapter {
		public void mouseClicked(MouseEvent e) {
			if(e.getClickCount() == 2) { //더블 클릭의 경우
            	//[0,255] 사이의 랜덤한 r,g,b 정수 값 얻기
				int r = (int)(Math.random()*256);
				int g = (int)(Math.random()*256);
				int b = (int)(Math.random()*256);
				
				Component c = (Component)e.getSource(); //클릭한 컴포넌트를 알아낸다.
				c.setBackground(new Color(r,g,b)); //컴포넌트의 배경을 r,g,b 색으로 칠한다.
			}
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new ClickAndDoubleClickEx();
	}

}

MouseWheelEvent 와 MouseWheelListener

  • 마우스 휠 이벤트
    • 마우스 휠이 구를 때마다 발생하는 이벤트
      • 이벤트 발생심다ㅏ MouseWheelEvent 객체 생성
  • MouseWheelListener
    • 마우스 휠 이벤트 리스너
    • 마우스 휠 이벤트가 발생할 때마다 호출되는 메소드
      • public void mouseWheelMoved(MouseWheelEvent e)
  • 마우스 휠 리스너 구현
component.addMouseWheelListener(new MouseWheelListener)) {
   public void mouseWheelMoved(MouseWheelEvent e) {
      //마우스 휠의 구르는 방향에 따라 이벤트를 처리한다.
   }
}
profile
공부한 것 기록용

0개의 댓글