728x90
채팅 서버를 만들기 위해서는 서버측과 클라이언트 측 을 만들어 줘야하는데 두개의 코딩은 다음과 같습니다.
서버코드
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
public class ChatServer extends JFrame implements ActionListener {
private BufferedReader in = null;
private BufferedWriter out = null;
private ServerSocket listener = null;
private Socket socket = null;
private Receiver receiver; // JTextArea를 상속받고 Runnable 인터페이스를 구현한 클래스로서 받은 정보를 담는 객체
private JTextField sender; // JTextField 객체로서 보내는 정보를 담는 객체
private MyDialog dialog;
private JTextField tf = new JTextField(10);
public JButton nameBtn = new JButton("이름변경");
private boolean valid = false;
public String mynameText;
public String clnameText;
public ChatServer() {
setTitle("서버 채팅 창"); // 프레임 타이틀
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //프레임 종료 버튼(X)을 클릭하면 프로그램 종료
Container c = getContentPane();
c.setLayout(new BorderLayout()); //BorderLayout 배치관리자의 사용
receiver = new Receiver(); // 클라이언트에서 받은 메시지를 출력할 컴퍼넌트
receiver.setEditable(false); // 편집 불가
sender = new JTextField();
sender.addActionListener(this);
nameBtn.setBounds(400, 0, 100, 50);
add(nameBtn);
nameBtn.setVisible(true);
dialog = new MyDialog(this,"Test Dialog",true);
nameBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// dialog.setVisible(true);
do {
try {
mynameText = String.valueOf(JOptionPane.showInputDialog("변경할 이름을 적으세요"));
valid = true;
} catch (NumberFormatException e3) {}
} while(!valid);
}
});
add(new JScrollPane(receiver),BorderLayout.CENTER); // 스크롤바를 위해 ScrollPane 이용
add(sender,BorderLayout.SOUTH);
setSize(500, 500); // 폭 400 픽셀, 높이 200 픽셀의 크기로 프레임 크기 설정
setVisible(true); // 프레임이 화면에 나타나도록 설정
try {
setupConnection();
} catch (IOException e) {
handleError(e.getMessage());
}
Thread th = new Thread(receiver); // 상대로부터 메시지 수신을 위한 스레드 생성
th.start();
}
private void setupConnection() throws IOException {
listener = new ServerSocket(9999); // 서버 소켓 생성
socket = listener.accept(); // 클라이언트로부터 연결 요청 대기
//System.out.println("연결됨");
receiver.append("클라이언트로부터 연결 완료");
int pos = receiver.getText().length();
receiver.setCaretPosition(pos); // caret 포지션을 가장 마지막으로 이동
in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 클라이언트로부터의 입력 스트림
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // 클라이언트로의 출력 스트림
}
private static void handleError(String string) {
System.out.println(string);
System.exit(1);
}
private class Receiver extends JTextArea implements Runnable {
@Override
public void run() {
String msg = null;
while (true) {
try {
msg = in.readLine(); // 상대로부터 한 행의 문자열 받기
} catch (IOException e) {
handleError(e.getMessage());
}
this.append("\n " + msg); // 받은 문자열을 JTextArea에 출력
int pos = this.getText().length();
this.setCaretPosition(pos); // caret 포지션을 가장 마지막으로 이동
}
}
}
@Override
public void actionPerformed(ActionEvent e) { // JTextField에 <Enter> 키 처리
if (e.getSource() == sender) {
String msg = sender.getText(); // 텍스트 필드에서 문자열 얻어옴
try {
out.write(mynameText+" : "+msg+"\n"); // 문자열 전송
out.flush();
receiver.append("\n" +mynameText+" : "+ msg);// JTextArea에 출력
int pos = receiver.getText().length();
receiver.setCaretPosition(pos); // caret 포지션을 가장 마지막으로 이동
sender.setText(null); // 입력창의 문자열 지움
} catch (IOException e1) {
handleError(e1.getMessage());
}
}
}
class MyDialog extends JDialog{
public MyDialog(JFrame frame, String title, boolean modal) {
super(frame,title,modal);
setLayout(new FlowLayout());
add(tf);
setSize(20,100);
}
}
public class DialogEx extends JFrame{
public DialogEx(){
super("DialogEx 예제프레임");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btn = new JButton("show Dialog");
dialog = new MyDialog(this,"Test Dialog",true);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.setVisible(true);
}
});
getContentPane().add(btn);//컨테이너를 꼭 구할 필요는 없음 그냥 add만써도 가능 컨테이너를 안 구하면 프레임 자체에 배경색을 넣을 수 없음, 그래서 보통 패널을 올린다음에 패널에 색을 많이 칠함
setSize(400,200);
setVisible(true);
}
}
public static void main(String[] args) {
new ChatServer();
}
}
클라이언트 코드
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ChatClient extends JFrame implements ActionListener {
private BufferedReader in = null;
private BufferedWriter out = null;
private Socket socket = null;
private Receiver receiver = null; // JTextArea를 상속받고 Runnable 인터페이스를 구현한 클래스로서 받은 정보를 담는 객체
private JTextField sender = null; // JTextField 객체로서 보내는 정보를 담는 객체
private MyDialog dialog;
private JTextField tf = new JTextField(10);
private JButton nameBtn2 = new JButton("이름변경");
private boolean valid = false;
public String clnameText;
public String mynameText;
public ChatClient() {
setTitle("클라이언트 채팅 창"); // 프레임 타이틀
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //프레임 종료 버튼(X)을 클릭하면 프로그램 종료
Container c = getContentPane();
c.setLayout(new BorderLayout()); //BorderLayout 배치관리자의 사용
receiver = new Receiver(); // 서버에서 받은 메시지를 출력할 컴퍼넌트
receiver.setEditable(false); // 편집 불가
sender = new JTextField();
sender.addActionListener(this);
nameBtn2.setBounds(400, 0, 100, 50);
add(nameBtn2);
nameBtn2.setVisible(true);
dialog = new MyDialog(this,"Test Dialog",true);
nameBtn2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
do {
try {
clnameText = String.valueOf(JOptionPane.showInputDialog("변경할 이름을 적으세요"));
valid = true;
} catch (NumberFormatException e3) {}
} while(!valid);
}
});
c.add(new JScrollPane(receiver),BorderLayout.CENTER); // 스크롤바를 위해 ScrollPane 이용
c.add(sender,BorderLayout.SOUTH);
setSize(500, 500); // 폭 400 픽셀, 높이 200 픽셀의 크기로 프레임 크기 설정
setVisible(true); // 프레임이 화면에 나타나도록 설정
try {
setupConnection();
} catch (IOException e) {
handleError(e.getMessage());
}
Thread th = new Thread(receiver); // 상대로부터 메시지 수신을 위한 스레드 생성
th.start();
}
private void setupConnection() throws IOException {
socket = new Socket("localhost", 9999); // 클라이언트 소켓 생성
// System.out.println("연결됨");
receiver.append("서버에 연결 완료");
int pos = receiver.getText().length();
receiver.setCaretPosition(pos); // caret 포지션을 가장 마지막으로 이동
in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 클라이언트로부터의 입력 스트림
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // 클라이언트로의 출력 스트림
}
private static void handleError(String string) {
System.out.println(string);
System.exit(1);
}
private class Receiver extends JTextArea implements Runnable {
@Override
public void run() {
String msg = null;
while (true) {
try {
msg = in.readLine(); // 상대로부터 한 행의 문자열 받기
} catch (IOException e) {
handleError(e.getMessage());
}
this.append("\n " + msg); // 받은 문자열을 JTextArea에 출력
int pos = this.getText().length();
this.setCaretPosition(pos); // caret(커서)을 가장 마지막으로 이동
}
}
}
@Override
public void actionPerformed(ActionEvent e) { // JTextField에 <Enter> 키 처리
if (e.getSource() == sender) {
String msg = sender.getText(); // 텍스트 필드에 사용자가 입력한 문자열
try {
out.write(clnameText+" : "+msg+"\n"); // 문자열 전송
out.flush();
receiver.append("\n "+clnameText+" : "+ msg); // JTextArea에 출력
int pos = receiver.getText().length();
receiver.setCaretPosition(pos); // caret 포지션을 가장 마지막으로 이동
sender.setText(null); // 입력창의 문자열 지움
} catch (IOException e1) {
handleError(e1.getMessage());
}
}
}
class MyDialog extends JDialog{
public MyDialog(JFrame frame, String title, boolean modal) {
super(frame,title,modal);
setLayout(new FlowLayout());
add(tf);
setSize(20,100);
}
}
public class DialogEx extends JFrame{
public DialogEx(){
super("DialogEx 예제프레임");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btn = new JButton("show Dialog");
dialog = new MyDialog(this,"Test Dialog",true);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.setVisible(true);
}
});
getContentPane().add(btn);//컨테이너를 꼭 구할 필요는 없음 그냥 add만써도 가능 컨테이너를 안 구하면 프레임 자체에 배경색을 넣을 수 없음, 그래서 보통 패널을 올린다음에 패널에 색을 많이 칠함
setSize(400,200);
setVisible(true);
}
}
public static void main(String[] args) {
new ChatClient();
}
}
위의 코드 중 다이어로그를 생성하는 코드들은 다음과 같습니다.
클라이언트 코드와 서버측 코드와 동일 합니다.
private MyDialog dialog;
private JTextField tf = new JTextField(10);
private JButton nameBtn2 = new JButton("이름변경");
private boolean valid = false;
public String clnameText;
public String mynameText;
//ChatClient() 클래스
nameBtn2.setBounds(400, 0, 100, 50);
add(nameBtn2);
nameBtn2.setVisible(true);
dialog = new MyDialog(this,"Test Dialog",true);
nameBtn2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
do {
try {
clnameText = String.valueOf(JOptionPane.showInputDialog("변경할 이름을 적으세요"));
valid = true;
} catch (NumberFormatException e3) {}
} while(!valid);
}
});
//다이어로그를 만드는 클래스들
class MyDialog extends JDialog{
public MyDialog(JFrame frame, String title, boolean modal) {
super(frame,title,modal);
setLayout(new FlowLayout());
add(tf);
setSize(20,100);
}
}
public class DialogEx extends JFrame{
public DialogEx(){
super("DialogEx 예제프레임");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btn = new JButton("show Dialog");
dialog = new MyDialog(this,"Test Dialog",true);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.setVisible(true);
}
});
getContentPane().add(btn);//컨테이너를 꼭 구할 필요는 없음 그냥 add만써도 가능 컨테이너를 안 구하면 프레임 자체에 배경색을 넣을 수 없음, 그래서 보통 패널을 올린다음에 패널에 색을 많이 칠함
setSize(400,200);
setVisible(true);
}
}728x90
'Programming > Java' 카테고리의 다른 글
| [Java] Builder pattern -이해 및 사용방법 (0) | 2023.08.31 |
|---|---|
| JSP Servlet :: DAO, DTO, Controller 이용한 MVC패턴 CRUD 메모장 만들기 (1) (0) | 2023.08.08 |
| Java JPanel 이용한 막대차트, 꺾은선그래프, 파이차트 만들기 (0) | 2023.07.13 |
| Java StringTokenizer (0) | 2023.07.07 |
| Java 스트링버퍼(StringBuffer) (0) | 2023.07.07 |