반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- php
- 리액트
- 리액트네이티브
- 정보처리기사
- 타입스크립트
- 자바스크립트
- 정보처리기사실기요약
- 이안의평일코딩
- javascript
- Java의정석
- Oracle
- 국비코딩
- 오라클
- 정보처리기사정리
- 자스코테
- 정보처리기사실기정리
- CSS
- react
- 코딩테스트
- typescript
- 자바스크립트 코딩테스트
- 정보처리기사요약
- 자바의정석
- spring
- 스프링
- 정보처리기사실기
- 평일코딩
- ReactNative
- 국비IT
- VUE
Archives
- Today
- Total
이안의 평일코딩
JAVA - 채팅 프로그램 본문
반응형
2020.08.03(월)
com.sist.client
ClientMainFrame
package com.sist.client;
// 윈도우 => JFrame
// 윈도우와 관련된 클래스를 읽어온다
import javax.swing.*;
import javax.swing.text.Document;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import com.sist.common.Function;
import java.awt.*; // Color,Layout
import java.awt.event.*;// interface
/*
* 재사용
* = 상속 (is-a) : 기존의 클래스를 변경해서 사용
* public class ClientMainFrame extends JFrame
* ===============
* JFrame의 기능을 전체 가지고 온다
* class A
* {
* O X W
* }
* class B extends A
* {
* O X W
* }
* = 포함 (has-a) : 기존의 클래스를 변경없이 사용
* public class ClientMainFrame
* {
* JFrame f=new JFrame();
* }
*
*/
import java.io.*;
import java.net.*;
import java.util.*;
/*
* 1. 사용자가 서버에 요청
* 2. 서버에서 들어오는 응답을 받아서 출력 (쓰레드) => 자동화
*/
public class ClientMainFrame extends JFrame implements ActionListener,
MouseListener,Runnable{
// 윈도우 크기 결정 => 생성자에서 사용 ==> 291 page
JLabel title=new JLabel("영화 예매 & 추천 프로그램",JLabel.CENTER);
MenuForm mf=new MenuForm();
ChatForm cf=new ChatForm();
DetailForm df=new DetailForm();
Login login=new Login();
ControllPanel cp;
int curpage=1;
int totalpage=16;
// 네트워크 관련 프로그램
Socket s; // 연결 기계
OutputStream out; // 서버로 요청값 전송 => 로그인,채팅 문자열 , 종료 ....
BufferedReader in; // 서버로부터 값을 받아오는 클래스 ==> 쓰레드
public ClientMainFrame()
{
cp=new ControllPanel(this);
// 새로운 창 => 현재 실행중인 윈도우창을 전송
/*
* 클래스에서 생성자 사용 => 선언이 아니라 => 구현할때
* 예)
* 데이터베이스 : 오라클연결
* 네트워크 : 셋팅 => IP,PORT => 핸드폰 (개통)
* 웹 : 쿠키에서 값읽기 => 지동로그인
*/
title.setFont(new Font("굴림체",Font.BOLD,55));
//title.setOpaque(true);
//title.setBackground(Color.magenta);
setLayout(null);// JFrame (BorderLayout) 사용자 정의로 배치 => null
title.setBounds(10, 15, 1570, 100);
// 추가 => add()
add(title);
// 메뉴 배치
mf.setBounds(10, 120, 100, 300 );
add(mf);
// 채팅폼
cf.setBounds(115, 760, 1465, 200);
add(cf);
// 출력화면
cp.setBounds(115, 120, 1465, 635);
add(cp);
setSize(1600, 1000);
//setVisible(true);
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);// X버튼 클릭시 종료
mf.b1.addActionListener(this);
mf.b2.addActionListener(this);
mf.b5.addActionListener(this);
cp.ff.b1.addActionListener(this);// 이전
cp.ff.b2.addActionListener(this);// 다음
df.b2.addActionListener(this);// 목록
cp.lf.b1.addActionListener(this);
cp.lf.b2.addActionListener(this);
cp.lf.b3.addActionListener(this);
cp.lf.b4.addActionListener(this);
cp.lf.b5.addActionListener(this);
cp.lf.b6.addActionListener(this);
cp.lf.tf.addActionListener(this);
// 로그인 처리
login.b1.addActionListener(this);
login.b2.addActionListener(this);
// 종료
mf.b7.addActionListener(this);
// 채팅
cf.tf.addActionListener(this);
/*
* for(int i=0;i<10;i++) { cp.ff.mc[i].addMouseListener(this); }
*/
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
// 생성자는 호출시에 반드시 => new 생성자()
UIManager.setLookAndFeel("com.jtattoo.plaf.mcwin.McWinLookAndFeel");
new ClientMainFrame();
}
public static Image getImage(ImageIcon ii,int w,int h)
{
Image dimg = ii.getImage().getScaledInstance(w, h,
Image.SCALE_SMOOTH);
return dimg;
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource()==mf.b1)
{
cp.card.show(cp, "FF");
}
else if(e.getSource()==mf.b2)
{
cp.card.show(cp, "LF");
}
else if(e.getSource()==mf.b5)
{
cp.card.show(cp, "NF");
}
else if(e.getSource()==df.b2)
{
cp.card.show(cp, "FF");
}
else if(e.getSource()==cp.ff.b1)// 이전버튼
{
if(curpage>1)
{
curpage--;
cp.ff.p.removeAll();// JPanel의 모든 기능을 삭제
cp.ff.moviePrint(curpage);
cp.ff.repaint();
cp.ff.p.validate();//JPanel의 원래 기능을 재배치
}
}
else if(e.getSource()==cp.ff.b2)// 다음버튼
{
if(curpage<totalpage)
{
curpage++;
cp.ff.p.removeAll();
cp.ff.moviePrint(curpage);
cp.ff.repaint();
cp.ff.p.validate();
}
}
else if(e.getSource()==cp.lf.b1)
{
cp.lf.movieAllData(1);
}
else if(e.getSource()==cp.lf.b2)
{
cp.lf.movieAllData(2);
}
else if(e.getSource()==cp.lf.b3)
{
cp.lf.movieAllData(3);
}
else if(e.getSource()==cp.lf.b4)
{
cp.lf.movieAllData(4);
}
else if(e.getSource()==cp.lf.b5)
{
cp.lf.movieAllData(5);
}
else if(e.getSource()==cp.lf.b6 || e.getSource()==cp.lf.tf)
{
// 1. 입력된 값 읽기
String ss=cp.lf.tf.getText();
if(ss.length()<1)
{
JOptionPane.showMessageDialog(this, "검색어를 입력하세요");
cp.lf.tf.requestFocus();
return; // 메소드 종료
}
cp.lf.movieFindData(ss);
}
else if(e.getSource()==login.b1)
{
String id=login.tf1.getText();
if(id.length()<1)// ID가 입력하지 않을 경우
{
JOptionPane.showMessageDialog(this, "아이디를 입력하세요");
login.tf1.requestFocus();
return;
}
String name=login.tf2.getText();
if(name.length()<1)
{
JOptionPane.showMessageDialog(this, "대화명을 입력하세요");
login.tf2.requestFocus();
return;
}
String sex="";
if(login.rb1.isSelected())
sex="남자";
else
sex="여자";
// 서버로 입력받은 데이터 전송
try
{
// 연결 => 서버에 대한 정보를 가지고 있다
s=new Socket("localhost",3355);
// 송수신 위치 확인
in=new BufferedReader(new InputStreamReader(s.getInputStream()));
out=s.getOutputStream();
// 로그인 요청 (서버로 전송되는 부분)
out.write((Function.LOGIN+"|"+id+"|"+name+"|"+sex+"\n").getBytes());
}catch(Exception ex){}
//서버에서 전송하는 데이터를 읽어서 출력
new Thread(this).start();
// run()의 위치 확인 ==> 자신의 클래스안에 존재 => (this)
}
else if(e.getSource()==login.b2)
{
System.exit(0);
}
else if(e.getSource()==cf.tf)// 채팅
{
String color=cf.box.getSelectedItem().toString();
String msg=cf.tf.getText();
if(msg.length()<1)
return;
// 데이터를 서버로 전송
try
{
out.write((Function.CHAT+"|"+msg+"|"+color+"\n").getBytes());
}catch(Exception ex){}
cf.tf.setText("");
}
else if(e.getSource()==mf.b7)
{
try
{
out.write((Function.EXIT+"|\n").getBytes());
}catch(Exception ex) {}
}
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
for(int i=0;i<10;i++)
{
if(e.getSource()==cp.ff.mc[i])
{
if(e.getClickCount()==2)
{
int a=(i+1)+((curpage*10)-10);
//JOptionPane.showMessageDialog(this, "mno="+a);
//System.out.println(a);
df.detailPrint(a);
//cp.card.show(cp,"DF");
df.setVisible(true);
break;
}
}
}
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void run() {
// TODO Auto-generated method stub
// 서버에서 들어오는 데이터를 받아서 처리
try
{
while(true)
{
String msg=in.readLine();
System.out.println("server=>"+msg);
StringTokenizer st=
new StringTokenizer(msg,"|");
int protocol=Integer.parseInt(st.nextToken());
switch(protocol)
{
case Function.MYLOG:
{
setTitle(st.nextToken());
login.setVisible(false);// 로그인창
setVisible(true);// 영화창 (Main)
}
break;
case Function.LOGIN:
{
// 테이블에 출력
String[] data= {
st.nextToken(), // id
st.nextToken(), // name
st.nextToken() // sex
};
cf.model.addRow(data);
}
break;
case Function.CHAT:
{
initStyle();
append(st.nextToken(),st.nextToken());
}
break;
case Function.EXIT:
{
String id=st.nextToken();
for(int i=0;i<cf.model.getRowCount();i++)
{
String mid=cf.model.getValueAt(i,0).toString();
if(id.equals(mid))
{
cf.model.removeRow(i);
break;
}
}
}
break;
case Function.MYEXIT:
{
dispose();// 윈도우 메모리 해제
System.exit(0);// 프로그램 종료
}
break;
}
}
}catch(Exception ex) {}
}
public void initStyle()
{
Style def=StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
Style red=cf.ta.addStyle("red", def);
StyleConstants.setForeground(red, Color.red);
Style blue=cf.ta.addStyle("blue", def);
StyleConstants.setForeground(blue, Color.blue);
Style green=cf.ta.addStyle("green", def);
StyleConstants.setForeground(green, Color.green);
Style yellow=cf.ta.addStyle("yellow", def);
StyleConstants.setForeground(yellow, Color.yellow);
Style gray=cf.ta.addStyle("gray", def);
StyleConstants.setForeground(gray, Color.gray);
Style cyan=cf.ta.addStyle("cyan", def);
StyleConstants.setForeground(cyan, Color.cyan);
}
public void append(String msg,String color)
{
try
{
Document doc=cf.ta.getDocument();
doc.insertString(doc.getLength(), msg+"\n", cf.ta.getStyle(color));
}catch(Exception ex) {}
}
}
ChatForm
package com.sist.client;
import java.awt.Color;
// 1465, 200
import javax.swing.*;
import javax.swing.table.*;
public class ChatForm extends JPanel{
JTextPane ta;
JTextField tf;
JComboBox box;
JTable table;
DefaultTableModel model;
JButton b1,b2;
public ChatForm()
{
//setBackground(Color.yellow);
setLayout(null);
ta=new JTextPane();
ta.setEditable(false);
JScrollPane js=new JScrollPane(ta);
js.setBounds(10, 15, 850, 140);
add(js);
tf=new JTextField();
tf.setBounds(10, 160, 740, 30);
add(tf);
box=new JComboBox();
box.addItem("black");
box.addItem("red");
box.addItem("blue");
box.addItem("green");
box.addItem("gray");
box.addItem("yellow");
box.addItem("cyan");
box.setBounds(755, 160, 105, 30);
add(box);
String[] col={"ID","대화명","성별"};
String[][] row=new String[0][3];
model=new DefaultTableModel(row,col);
table=new JTable(model);
JScrollPane js1=new JScrollPane(table);
js1.setBounds(865, 15, 500, 135);
add(js1);
JPanel p=new JPanel();
b1=new JButton("정보보기");
b2=new JButton("쪽지보내기");
p.add(b1);
p.add(b2);
p.setBounds(865, 155, 500, 35);
add(p);
}
}
Login
package com.sist.client;
import javax.swing.*;
import java.awt.*;
public class Login extends JFrame{
JLabel la1,la2,la3;
JTextField tf1,tf2;
JRadioButton rb1,rb2;
JButton b1,b2;
public Login()
{
la1=new JLabel("ID",JLabel.RIGHT);
la2=new JLabel("대화명",JLabel.RIGHT);
la3=new JLabel("성별",JLabel.RIGHT);
tf1=new JTextField();
tf2=new JTextField();
rb1=new JRadioButton("남자");
rb2=new JRadioButton("여자");
ButtonGroup bg=new ButtonGroup();
bg.add(rb1); bg.add(rb2);
rb1.setSelected(true);
b1=new JButton("로그인");
b2=new JButton("취소");
// 배치
setLayout(null);
la1.setBounds(10, 15, 60, 30);
tf1.setBounds(75, 15, 150, 30);
la2.setBounds(10, 50, 60, 30);
tf2.setBounds(75, 50, 150, 30);
la3.setBounds(10, 85, 60, 30);
rb1.setBounds(75, 85, 70, 30);
rb2.setBounds(150, 85, 70, 30);
JPanel p=new JPanel();
p.add(b1);p.add(b2);
p.setBounds(10, 120, 215, 35);
// 윈도우 추가
add(la1);add(tf1);
add(la2);add(tf2);
add(la3);add(rb1);add(rb2);
add(p);
// 윈도우 크기
setSize(250, 200);
setVisible(true);
}
/*
* public static void main(String[] args) { new Login(); }
*/
}
com.sist.common
Function
package com.sist.common;
public class Function {
public static final int LOGIN=100;// 로그인 된 사람
public static final int MYLOG=110;// 로그인 하는 사람
//로그인
public static final int CHAT=200;
//채팅
public static final int EXIT=300;// 남아 있는 사람
public static final int MYEXIT=310;// 나가는 사람 처리
//나가기
}
com.sist.server
Server
package com.sist.server;
import java.util.*;
import com.sist.common.Function;
import java.net.*;
import java.io.*;
public class Server implements Runnable{
// 서버에서 실행된 Scoket
ServerSocket ss;
final int PORT=3355;// 1024~65535
// 클라이언트 정보를 저장
Vector<Client> waitVc=new Vector<Client>();// ArrayList,LinkedList
// 서버 가동
public Server()
{
try
{
ss=new ServerSocket(PORT);
// bind(): 개통 listen(): 접속시까지 대기
System.out.println("Server Start...");
}catch(Exception ex){}
}
// 클라이언트가 접속시마다 처리 기능
public void run()
{
try
{
while(true)
{
Socket s=ss.accept();
// Socket => 발신자 정보를 가지고 있다 (IP,PORT)
/*
* 접속하면 => 쓰레드를 생성해서 클라이언트마다 통신을 다르게 할 수 있게 만든다
*/
// 쓰레드와 연결 => Socket만 연결하면 한사람하고만 통신이 가능
Client client=new Client(s);
client.start(); // 통신을 시작하라~~
}
}catch(Exception ex){}
}
// 통신이 가능하게 만든다
class Client extends Thread
{
// 클라이언트의 정보 수집
Socket s;
// 송신,수신
OutputStream out;
BufferedReader in;
// 클라이언트의 기본 정보
String id,name,sex;
public Client(Socket s)
{
// 변수는 지역변수 우선순위
// 변수명 ==> 지역변수,매개변수 => 멤버변수(멤버변수 사용 => this.변수명)
try
{
this.s=s; // Connection(오라클)
// 클라이언트와 연결
out=s.getOutputStream(); // PreparedStatement => SQL
// 클라이언트에 응답을 전송 (값)
in=new BufferedReader(new InputStreamReader(s.getInputStream()));
// 클라이언트의 요청값을 받을 경우에 사용 // ResultSet => 결과값 받기
/*
* out=s.getOutputStream(); => HttpServletResponse
* in=new BufferedReader => HttpServletRequest
*/
}catch(Exception ex){}
}
// 통신
public void run()
{
try
{
while(true)
{
String msg=in.readLine();
System.out.println("client=>"+msg);
// 클라이언트 요청한 데이터
StringTokenizer st=new StringTokenizer(msg,"|");
int protocol=Integer.parseInt(st.nextToken());
// 100|id|name|sex
switch(protocol)
{
case Function.LOGIN:
{
id=st.nextToken();
name=st.nextToken();
sex=st.nextToken();
messageAll(Function.LOGIN+"|"+id+"|"+name+"|"+sex);
// LOGIN 테이블에 출력
// 추가
waitVc.add(this);
// 화면 변경
// 로그인 ==> 대기실
messageTo(Function.MYLOG+"|"+id);
// MYLOG 로그인창을 종료 => 대기실을 실행
// 이미 접속한 사람들의 정보 받기
for(Client user:waitVc)
{
messageTo(Function.LOGIN+"|"
+user.id+"|"+user.name+"|"+user.sex);
}
}
break;
case Function.CHAT:
{
messageAll(Function.CHAT+"|["+name+"]"+st.nextToken()+"|"+st.nextToken());
}
break;
case Function.EXIT:
{
String mid=id;
messageAll(Function.EXIT+"|"+mid);
// EXIT => 대기실 테이블에서 id를 제거
// 제거
for(Client user:waitVc)
{
if(user.id.equals(id))
{
messageTo(Function.MYEXIT+"|");
waitVc.remove(user);
in.close();
out.close();
//통신을 중단한다
break;
}
}
}
break;
}
}
}catch(Exception ex) {}
}
// 전체적으로 메세지 전송
// synchronized 동기화 프로그램
public void messageAll(String msg)
{
for(Client user:waitVc)
{
try
{
user.messageTo(msg);
}catch(Exception ex)
{
waitVc.remove(user);
}
}
}
// 개인적으로 메세지 전송
public void messageTo(String msg)
{
try
{
out.write((msg+"\n").getBytes());
// 인코딩 ==> 디코딩 ==> UTF-8
}catch(Exception ex) {}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Server server=new Server();// 서버 가동
new Thread(server).start();// 접속시까지 기다려라
}
}
반응형
'Back-end > Java' 카테고리의 다른 글
JAVA의 정석 35일차 - 자바 마지막 예제 (0) | 2020.07.31 |
---|---|
JAVA의 정석 34일차 - 네트워크 (0) | 2020.07.30 |
JAVA의 정석 33일차 - 영화 정보 프로그램(2) (0) | 2020.07.29 |
JAVA의 정석 32일차 - 영화 정보 프로그램(1) (0) | 2020.07.28 |
JAVA의 정석 31일차 - 입출력 I/O (0) | 2020.07.27 |
Comments