정확히는 Call by Value of Reference지만,
편의상 (그리고 콜바이레퍼런스처럼 보이니)
Call by Reference로 부르겠음

콜바이레퍼런스를 회원가입폼, 채팅 구현예제로 경험해보자!

회원가입 Form 구현

✅ 유효성 체크

	public void checkForm(){
		//각 항목을 입력하지 않은 경우. 경고!
		if(t_id.getText().length() <1){
			System.out.println("아이디를 입력하세요");
		}else if(t_pwd.getText().length() <1){
			System.out.println("비밀번호를 입력하세요");
		}else if(t_name.getText().length() <1){
			System.out.println("이름을 입력하세요");
		}
	}

✅ 입력값이 비어 있는지 확인하는 방법

1️⃣ 빈 문자열인지 확인 equals("")
""과 내용이 정확히 같은지 비교

"".equals("")true  
" ".equals("")false  
"abc".equals("")false

2️⃣ 문자열의 길이가 0인지 확인 length() < 1
(문자열의 길이가 0 == 아무 글자도 없는 경우)

"".length() < 1true  
" ".length() < 1false  
"abc".length() < 1false

⚠ 둘 다 공백 " "이 들어가 있으면 false
앞에 .trim()을 쓰면 " " (공백만 있는 경우)도 빈 문자열로 간주, 실제로 아무것도 입력되지 않았는지 판별할 때 자주 사용

t_name.getText().trim().length() < 1 이렇게

✅ Dimension

(자꾸 까먹음)

  • Dimension : Java AWT 에서 컴포넌트의 너비와 높이(폭과 높이)를 하나의 객체로 다룰 수 있도록 만들어진 클래스

  • setPreferredSize() : 컴포넌트의 선호 크기(preferred size)를 설정할 때 사용하는 메서드
    Dimension 객체를 인자로 받음

		Dimension d=new Dimension(110, 25);
		la_id.setPreferredSize(d);
		t_id.setPreferredSize(d);
		la_pwd.setPreferredSize(d);
		t_pwd.setPreferredSize(d);
		la_name.setPreferredSize(d);
		t_name.setPreferredSize(d);

✅ 배경색

  • setBackground(Color color) : Java AWT에서 컴포넌트의 배경색을 설정할 때 사용하는 메서드
		la_title.setBackground(Color.PINK); //PINK는 상수
		t_id.setBackground(Color.PINK);
		t_pwd.setBackground(Color.PINK);
		t_name.setBackground(Color.PINK);

동기화된 채팅기능 구현하기

ChatA의 열기 버튼을 누르면 ChatB창이 열리고,
ChatA와 ChatB 각각의 TextField에 채팅입력 후, 엔터를 누르면
ChatA와 ChatB의 TextArea에 채팅내용이 누적출력되게 구현

ChatA 클래스


package gui.chat;

import java.awt.Frame;
import java.awt.Button;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;

public class ChatA extends Frame implements ActionListener, KeyListener {
    TextArea area;            // 채팅 내용 출력 영역
    Panel p_south;            // 하단 입력 패널
    TextField t_input;        // 메시지 입력 필드
    Button bt_open;           // 친구 창 열기 버튼
    ChatB chatB = null;       // 친구 창 참조 변수

    public ChatA() {
        area = new TextArea();
        p_south = new Panel();
        t_input = new TextField(30);
        bt_open = new Button("열기");

        area.setBackground(Color.YELLOW);

        add(area);
        add(p_south, BorderLayout.SOUTH);
        p_south.add(t_input);
        p_south.add(bt_open);

        bt_open.addActionListener(this);   // 버튼과 리스너 연결
        t_input.addKeyListener(this);      // 텍스트필드와 리스너 연결

        setSize(300, 400);
        setVisible(true);
    }

    // 버튼 클릭 시 친구 창 열기
    public void actionPerformed(ActionEvent e) {
        chatB = new ChatB(this);  // ⭐️ ChatA의 참조를 ChatB에 전달
    }

    // 사용하지 않는 메서드 (KeyListener의 메서드 필수 오버라이딩)
    public void keyTyped(KeyEvent e) {}
    public void keyPressed(KeyEvent e) {}

    // 엔터 키 입력 시 메시지 전송
    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            String message = t_input.getText();
            area.append(message + "\n");
            chatB.area.append(message + "\n");
            t_input.setText("");  // 입력 필드 초기화
        }
    }

    public static void main(String[] args) {
        new ChatA();
    }
}

ChatB 클래스


package gui.chat;

import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;

public class ChatB extends Frame implements KeyListener {
    TextArea area;            // 채팅 출력 영역
    Panel p_south;            // 하단 입력 패널
    TextField t_input;        // 메시지 입력 필드
    ChatA chatA = null;       // ChatA 인스턴스 참조 (상호작용용)

    // ChatA의 참조를 생성자에서 받아 저장
    public ChatB(ChatA chatA) {
        area = new TextArea();
        p_south = new Panel();
        t_input = new TextField(30);
        this.chatA = chatA;  // ChatA 인스턴스를 받아와 저장

        t_input.addKeyListener(this);

        add(area);
        add(p_south, BorderLayout.SOUTH);
        p_south.add(t_input);

        area.setBackground(Color.PINK);

        setSize(300, 400);
        setVisible(true);
    }

    public void keyTyped(KeyEvent e) {}
    public void keyPressed(KeyEvent e) {}

    // 엔터 키 입력 시 메시지 전송
    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            // chatB에서 채팅할 땐 chatA 입력 필드에 아무것도 없음
            // ➡ chatA 입력필드의 텍스트값 얻어올 필요 없음

            // ChatB에서 입력한 메시지 처리
            String message = t_input.getText();
            area.append(message + "\n");
            chatA.area.append(message + "\n");

            t_input.setText("");  // 입력 필드 초기화
        }
    }
}

✅ 체크포인트

this를 넘기는 이유?
→ ChatB에서 ChatA를 참조해서 데이터를 주고받기 위함 (콜바이레퍼런스)
(ChatA에서 ChatB를 참조하는 것도 동일)

this : 인스턴스가 자기 자신을 가리키는 레퍼런스 변수

KeyEvent.VK_ENTER는 왜 사용하는가?
→ 매직넘버(10)를 쓰는 대신 의미 있는 상수를 사용하는 게
가독성, 유지보수에 좋음

✅ Listener 간단하게 만드는 법

→ Frame이자 Listener로 만들기

항목내용
implements xxxListener프레임 클래스 선언부에 명시
addxxxListener(this)이벤트 소스에 리스너 등록 시 this 사용
@Override 메서드리스너에서 요구하는 메서드 구현
profile
아이들의 가능성을 믿었던 마음 그대로, 이제는 나의 가능성을 믿고 나아가는 중입니다.🌱

0개의 댓글