미니 네트워크 프로젝트 (2) : 기능 구현하기

부트캠프(END)/Java|2022. 6. 24. 21:50

Function과 in, out

Function 클래스를 만들어서 이 프로그램의 내부 프로토콜을 만들어 준다.

클라이언트가 어떤 요청을 보낼 때, 이 클래스에 정의된 프로토콜에 의해 응답을 할 것이다~ 라는 약속!

Function.java

package doodoo.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 END=900;//남아 있는 사람 처리
	public static final int MYEND=910;//나가는 사람 처리
}

 

BufferedReader와 InputStreamReader로 클라이언트가 보낸 요청을 읽어 오고,

(빠르게, 더 다양한 종류의 요청을 읽어 오기 위해 Reader)

OutputStream으로 클라이언트의 요청을 서버로 보낸다.

 

Server.java

package doodoo.server;
import java.io.*; //통신 -> io 하나만 있으면 메모리/파일/네트워크 입출력이 가능하다.
import java.util.*; //StringTokenizer 쓰려고
import doodoo.common.Function;

import java.net.*; //네트워크
public class Server implements Runnable {
  /*
   * 접속만 담당하는 교환 소켓 
   * -> 1개만 생성해도 OK -> 접속시 클라이언트의 정보(IP,PORT)를 저장해야 연결이 시작된다.
   * 통신만 담당하는 통신 소켓 
   * -> 접속할 클라이언트 개수만큼 생성해야 함 -> 여러 개를 동시에 돌려야하기 때문에 스레드가 필요
   * 클라이언트 정보를 공유해야 하기 때문에 내부 클래스를 사용한다.
   */
  private ServerSocket ss; //접속담당소켓(연결기기)
  private final int PORT = 3355;
  private Vector < Client > waitVc = //클라이언트의 정보를 저장(IP, PORT, ID 등등)
    new Vector < Client > (); //원래라면 Server.Client 해야하지만 같은 클래스 내이기 때문에 생략이 가능하다.

  //서버 구동
  public Server() {
    try {
      ss = new ServerSocket(PORT);
      System.out.println("Server Start!");
    } catch (Exception ex) {}
  }

  public void run() {
    //클라이언트가 접속할 때마다 처리해 준다.
    try {
      while (true) {
        Socket s = ss.accept(); //클라이언트가 접속시 호출
        //s가 클라이언트에 대한 정보를 가져온다.
        //s를 스레드에 넘겨 주고 통신할 수 있게 만들어 주어야 한다.
        Client client = new Client(s);
        client.start();
      }
    } catch (Exception ex) {}
  }

  class Client extends Thread { //통신을 담당!,내부 클래스
    String id, name, sex;
    Socket s; //클라이언트 접속 정보.
    BufferedReader in ;
    OutputStream out;

    public Client(Socket s) {
      try {
        this.s = s; in = 
                new BufferedReader(new InputStreamReader(s.getInputStream()));
        out = s.getOutputStream();
        //서버는 클라이언트 정보를 알고 있어야 하고, 클라이언트는 서버의 정보를 알고 있어야 한다.

      } catch (Exception ex) {}
    }
    //실제 통신시 Thread가 동작하는데 호출시에 start()가 되고 자동으로 run()이 호출된다.
    public void run() {
      try {
        while (true) {
          //클라이언트의 요구사항 받기
          String msg = in.readLine();
          //어떤 요구사항인지 확인
          StringTokenizer st = new StringTokenizer(msg, "|");
          int protocol = Integer.parseInt(st.nextToken());
          switch (protocol) {
          case Function.LOGIN: //로그인 처리
          {
            id = st.nextToken();
            name = st.nextToken();
            sex = st.nextToken();
            //로그인한 사람의 정보를 접속한 모두에게 전달
            messageAll(Function.LOGIN + "|" + id + "|" + name + "|" + sex);
            //저장
            waitVc.add(this);
            //지금 로그인 하는 사람 처리
            messageTo(Function.MYLOG + "|" + id + "|" + name); //로그인창은 닫고 메인창을 출력
            for (Client client: waitVc) {
              messageTo(Function.LOGIN + "|" +
                client.id + "|" + client.name + "|" + client.sex);
            }
          }
          break;
          case Function.CHAT: {
            //채팅 처리
            messageAll(Function.CHAT + "|[" + name + "]님의 말:" + st.nextToken());
          }
          break;
          case Function.END: {
            //나가기
            messageAll(Function.END + "|" + id);
            for (int i = 0; i < waitVc.size(); i++) {
              Client c = waitVc.get(i);
              if (id.equals(c.id)) {
                messageTo(Function.MYEND + "|");
                waitVc.remove(i); in .close();
                out.close();
                break;
              }
            }
          }
          break;
          }
        }

      } catch (Exception ex) {}
    }
    //개인적으로 메시지를 보낼 때
    public void messageTo(String msg) {
      try {
        out.write((msg + "\n").getBytes());
      } catch (Exception ex) {}
    }
    //전체 접속자에게 메시지를 보낼 때
    public void messageAll(String msg) {
      try {
        for (Client client: waitVc) {
          client.messageTo(msg);
        }
      } catch (Exception ex) {}
    }
  }
  public static void main(String[] args) {
    Server server = new Server(); //서버 구동
    new Thread(server).start(); //누군가 접속할때까지 기다림
  }
}

 

NetworkMain.java

package doodoo.main;
import doodoo.client.*;
import doodoo.common.Function;
import doodoo.data.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;

import javax.swing.*;
public class NetworkMain extends JFrame implements ActionListener, Runnable {
  ControllerPanel cp = new ControllerPanel();
  MenuForm menu = new MenuForm();
  WaitForm wr = new WaitForm();
  LoginForm lf = new LoginForm();
  public HomeForm hf;
  public DetailForm df;
  public MovieFindForm mf = new MovieFindForm();
  public ChatForm cf = new ChatForm();

  int curpage = 1; //current page
  int totalpage = 0;
  int cno = 1;
  //서버와 관련된 클래스
  Socket s;
  BufferedReader in ; //Thread가 씀(일반 유저가 값을 보내면 스레드가 읽음)
  OutputStream out; //클라이언트가 씀

  public NetworkMain() {
    setTitle("무비챗");
    setLayout(null); //사용자 정의 = 직접배치
    cp.setBounds(10, 15, 850, 850);
    add(cp);
    wr.setBounds(980, 15, 250, 700);
    add(wr);

    setSize(1250, 900);
    //X버튼 누르면 종료되도록
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    
    //버튼을 누르면 어떻게 해야 한다=이벤트 등록
    cp.hf.m1.addActionListener(this); //current movie
    cp.hf.m2.addActionListener(this); //pre movie
    cp.hf.b1.addActionListener(this); //이전
    cp.hf.b2.addActionListener(this); //다음

    //로그인 처리
    lf.b1.addActionListener(this);
    lf.b2.addActionListener(this);

    //채팅 텍스트필드에 입력 후 엔터를 누르면 넘어가게 할 것임.
    cp.cf.tf.addActionListener(this);

    //메뉴 버튼
    menu.chatBtn.addActionListener(this);
    menu.exitBtn.addActionListener(this);
    menu.homeBtn.addActionListener(this);
    menu.movieBtn.addActionListener(this);

    cp.mf.btn.addActionListener(this); //movieFind 찾기버튼

    totalpage = MovieSystem.movieTotalPage(cno);
    cp.hf.pagLa.setText(curpage + "page/" + totalpage + "pages");
  }

  public static Image getImage(ImageIcon ii, int width, int height) {
    Image deimg 
        = ii.getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH);
    return deimg;
  }

  //버튼 클릭시 처리해 주는 부분 -> 클릭시 자동 시스템(JVM)에 의해 자동 호출된다.
  @Override
  public void actionPerformed(ActionEvent e) {
    if (e.getSource() == cp.hf.b1) {
      //이전버튼 눌렀을시
      if (curpage > 1) {
        curpage--;
        ArrayList < MovieVO > list = cp.hf.ms.movieListData(cno, curpage);
        cp.hf.mm.cardInit(list);
        cp.hf.mm.cardPrint(list);
        cp.hf.pagLa.setText(curpage + "page/" + totalpage + "pages");
      }
    } else if (e.getSource() == cp.hf.b2) {
      //다음버튼 눌렀을시
      if (curpage < totalpage) {
        curpage++;
        ArrayList < MovieVO > list = cp.hf.ms.movieListData(cno, curpage);
        cp.hf.mm.cardInit(list);
        cp.hf.mm.cardPrint(list);
        cp.hf.pagLa.setText(curpage + "page/" + totalpage + "pages");
      }
    } else if (e.getSource() == menu.chatBtn) {
      cp.card.show(cp, "CF");
    } else if (e.getSource() == menu.exitBtn) {
      try {
        out.write((Function.END + "|\n").getBytes());
      } catch (Exception ex) {}
    } else if (e.getSource() == menu.movieBtn) {
      cp.card.show(cp, "MF");
    } else if (e.getSource() == menu.homeBtn) {
      cp.card.show(cp, "HF");
    } else if (e.getSource() == cp.cf.tf) {
      //채팅창에 입력한 문자열을 읽어 온다.
      String msg = cp.cf.tf.getText();
      if (msg.length() < 1) //입력하지 않은경우
        return; //아무 반응하지 않는다.
      try {
        out.write((Function.CHAT + "|" + msg + "\n").getBytes()); //내용 전송
      } catch (Exception ex) {}
      cp.cf.tf.setText(""); //메시지 보내고 난 후 채팅창 공백 초기화
    } else if (e.getSource() == cp.cf.b2) {
      JOptionPane.showMessageDialog(this, "이름:김지윤\n성별:여자\nID:kim");
    }
    //로그인 버튼
    else if (e.getSource() == lf.b1) {
      //id
      String id = lf.tf1.getText();
      if (id.length() < 1) {
        JOptionPane.showMessageDialog(this, "ID를 입력하세요.");
        lf.tf1.requestFocus();
        return;
      }
      //name->반드시 입력해야함(유효성 검사)
      String name = lf.tf2.getText();
      if (name.length() < 1) {
        JOptionPane.showMessageDialog(this, "이름을 입력하세요.");
        lf.tf2.requestFocus();
        return;
      }
      String sex = "";
      if (lf.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();
    } else if (e.getSource() == lf.b2) {
      System.exit(0);
    }
    //검색 버튼 눌렀을 때!
    else if (e.getSource() == cp.mf.btn) {
      //입력값을 가져온다.
      String fd = cp.mf.tf.getText();
      if (fd.length() < 1) { //입력이 안됐다면
        JOptionPane.showMessageDialog(this, "검색어를 입력하세요.");
        cp.mf.tf.requestFocus(); //딱 그 창에 포커스시킨다.
        return;
      }
      ArrayList < MovieVO > fList = MovieSystem.movieFind(fd);
      for (int i = cp.mf.model.getRowCount() - 1; i >= 0; i--) {
        cp.mf.model.removeRow(i); //밑에서부터 지움
      }
      try {
        for (MovieVO m: fList) {
          URL url = new URL(m.getPoster());
          Image img = getImage(new ImageIcon(url), 30, 30);
          Object[] data = {
            new ImageIcon(img),
            m.getTitle(),
            m.getDirector()
          };
          cp.mf.model.addRow(data);
        }
      } catch (Exception ex) {}
    }

    if (e.getSource() == cp.hf.m1) {
      //상영중
      curpage = 1;
      cno = 1;
      totalpage = MovieSystem.movieTotalPage(cno);
      ArrayList < MovieVO > list = cp.hf.ms.movieListData(cno, curpage);
      cp.hf.mm.cardInit(list);
      cp.hf.mm.cardPrint(list);
      cp.hf.pagLa.setText(curpage + "page/" + totalpage + "pages");
    }
    if (e.getSource() == cp.hf.m2) {
      //개봉예정
      curpage = 1;
      cno = 2;
      totalpage = MovieSystem.movieTotalPage(cno);
      ArrayList < MovieVO > list = cp.hf.ms.movieListData(cno, curpage);
      cp.hf.mm.cardInit(list);
      cp.hf.mm.cardPrint(list);
      cp.hf.pagLa.setText(curpage + "page/" + totalpage + "pages");
    }
  }
  //서버로부터 실시간 데이터를 읽어 오는 부분
  @Override
  public void run() {
    try {
      while (true) {
        //서버에서 보내주는 데이터를 받는다.
        String msg = in .readLine();
        System.out.println(msg);
        StringTokenizer st = new StringTokenizer(msg, "|");
        int protocol = Integer.parseInt(st.nextToken());
        switch (protocol) {
        case Function.LOGIN: {
          String[] data = {
            st.nextToken(), //ID
            st.nextToken(), //NAME
            st.nextToken() //SEX
          };
          cp.cf.model.addRow(data);
        }
        break;
        case Function.MYLOG: {
          lf.setVisible(false); //로그인창은 끄고
          setVisible(true); //메인창은 띄운다.
        }
        break;
        case Function.CHAT: {
          //채팅내용을 받아 온다.
          cp.cf.ta.append(st.nextToken() + "\n");
          //그리고 서버에서 값을 보내줄 것임.
        }
        break;
        case Function.END: {
          //나가기처리(남아있는 사람)
          String myId = st.nextToken();
          for (int i = 0; i < cp.cf.model.getRowCount(); i++) {
            String you = cp.cf.model.getValueAt(i, 0).toString();
            if (myId.equals(you)) {
              cp.cf.model.removeRow(i);
              break;
            }
          }
        }
        break;
        case Function.MYEND: {
          //나가기처리(나가는 사람)
          System.exit(0);
        }
        break;
        }
      }
    } catch (Exception ex) {}
  }

  public static void main(String[] args) {
    try {
      UIManager.setLookAndFeel("com.jtattoo.plaf.noire.NoireLookAndFeel");
    } catch (Exception ex) {}
    new NetworkMain();
  }
}

 

 

버튼이 작동하는 방법

 

MovieSystem.java

package doodoo.data;

import java.util.ArrayList;
import java.io.*;
public class MovieSystem {

	public static ArrayList<MovieVO> getList() {
		return list;
	}
	
	private static ArrayList<MovieVO> list = new ArrayList<MovieVO>();
	//초기화
	static {
		try {//파일을 읽어올 것임
			FileInputStream fis = new FileInputStream("c:\\java_data\\movie.txt");
			ObjectInputStream ois = new ObjectInputStream(fis);
			list = (ArrayList<MovieVO>)ois.readObject(); //데이터 넣기 끝~
			ois.close(); //꼭 닫아줘~
			fis.close();
		}catch(Exception ex) {ex.printStackTrace();}
	}
	
	public static ArrayList<MovieVO> movieListData(int cno, int page) {
		ArrayList<MovieVO> cList = new ArrayList<MovieVO>();
		int j = 0;
		int pagecnt = page*6-6;
		for(int i=0; i<list.size(); i++) {
			MovieVO m = list.get(i);
				if(j<6 && i>=(pagecnt+((cno-1)*100))) {
					cList.add(m);
					j++;
				}
		}
		return cList;
	}
	
	public static ArrayList<MovieVO> movie10(){
		ArrayList<MovieVO> tList = new ArrayList<MovieVO>();
		for(int i=0; i<10; i++) {
			int a = (int)(Math.random()*100)+1;
			MovieVO m = list.get(a);
			tList.add(m);
		}
		return tList;
	}
	
	public static int movieTotalPage(int cno) {
		//총 페이지 수를 미리 계산한다.
		if(cno==1) {//상영중 데이터 109
			return (int)(Math.ceil(109/6.0));
		}
		else if(cno==2) { //개봉예정 데이터 61
			return (int)(Math.ceil(48/6.0));
		}
		return 0;

	}
	
	public static ArrayList<MovieVO> movieFind(String fd){
		ArrayList<MovieVO> fList = new ArrayList<MovieVO>();
		for(MovieVO m:list) {
			if(m.getTitle().contains(fd))
				fList.add(m);
		}
		return fList;
	}
	
	public static void main(String[] args) {
//		테스트용 코드
//		ArrayList<MovieVO> list = movieListData(1,1);
//		for(MovieVO m:list) {
//			System.out.println(m.getMno()+"."+m.getTitle());
//		}
	}
}

 

MovieManager.java

package doodoo.client;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import doodoo.data.*;
import doodoo.main.NetworkMain;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;
import java.util.ArrayList;

public class MovieManager extends JPanel implements MouseListener {
   public PosterCard[] movies = new PosterCard[15];
   public JPanel p = new JPanel();
   public ControllerPanel cp;
   public MovieManager(ControllerPanel cp) {
      this.cp = cp; //같은 cp 를 넘겨주기 위함
   }

   public void cardPrint(ArrayList < MovieVO > list) {
      setLayout(null);
      //영화 목록 패널
      p.setLayout(new GridLayout(2, 3));
      int i = 0;
      for(MovieVO m: list) {
         movies[i] = new PosterCard(m);
         p.add(movies[i]);
         i++;
      }
      p.setBounds(10, 55, 900, 800);
      p.setVisible(true);
      add(p);

      for(int j = 0; j < movies.length; j++) {
         try {
            movies[j].addMouseListener(this);
         } catch (Exception ex) {} //포스터 없는 데이터도 있음
      }
   }

   public void cardInit(ArrayList < MovieVO > list) {
      for(int i = 0; i < list.size(); i++) {
         movies[i].poster.setIcon(null);
         movies[i].regdate.setText("");
         movies[i].title.setText("");
         movies[i].genre.setText("");
      }
      p.removeAll();
      p.validate();
   }
   @Override
   public void mouseClicked(MouseEvent e) {
      for(int i = 0; i < movies.length; i++) {
         if(e.getSource() == movies[i]) {
            //영화 포스터를 클릭할 때 상세페이지
            String title = movies[i].title.getText();
            for(int j = 0; j < MovieSystem.getList().size(); j++) {
               MovieVO m = MovieSystem.getList().get(j);
               if(m.getTitle().equals(title)) {
                  cp.df.genre.setText("장르|" + m.getGenre());
                  cp.df.title.setText("제목|" + m.getTitle());
                  cp.df.director.setText("감독|" + m.getDirector());
                  cp.df.regdate.setText("개봉일|" + m.getRegdate());
                  if(m.getActor().length() > 20)
                     cp.df.actor.setText("출연|" +
                        m.getActor().substring(0, 20) + "...");
                  if(m.getActor().length() < 20)
                     cp.df.actor.setText("출연|" + m.getActor());
                  cp.df.time.setText("러닝타임|" + m.getTime());
                  String s = "";

                  cp.df.video.setText(m.getKey());
                  try {
                     URL url = new URL(m.getPoster());
                     Image img
                        = NetworkMain.getImage(new ImageIcon(url), 250, 400);
                     cp.df.posterLa.setIcon(new ImageIcon(img));

                  } catch (Exception ex) {}
                  break;
               }
            }
            cp.tab.setSelectedIndex(2);
         }
      }
   }
}
더보기

HomeForm.java

 

package doodoo.client;
import java.util.*;
import java.awt.*;
import javax.swing.*;

import doodoo.data.*;

public class HomeForm extends JPanel{
	public JButton b1, b2; //이전, 다음 버튼이 될 것임
	public JButton m1, m2; //NetworkMain에서 접근할 수 있도록!
	//(개인정보같은게 아니라서 굳이 캡슐화는 필요없다.)
	public MovieManager mm;
	public MovieSystem ms = new MovieSystem();
	public JLabel pagLa = new JLabel("0 page/0 pages");
	public HomeForm(ControllerPanel cp) {
		mm = new MovieManager(cp); //같은 cp 를 넘겨주기 위함
		
		//상단 메뉴바(카테고리)
		JPanel p = new JPanel();
		m1 = new JButton("상영중");
		m2 = new JButton("개봉예정");
		
		//배치
		setLayout(null);
		p.setBounds(0,0,840,35);
		p.add(m1);
		p.add(m2);
		add(p);
		mm.setBounds(0,0,840,780);
		add(mm);
		
		//하단 메뉴바(페이지)
		JPanel p1 = new JPanel();
		b1 = new JButton("이전");
		b2 = new JButton("다음");
		p1.add(b1);
		p1.add(pagLa);
		p1.add(b2);
		p1.setBounds(0, 790, 840, 30);
		add(p1);
		
		//시작과 동시에 데이터를 받아 와야 함.
		ArrayList<MovieVO> list = MovieSystem.movieListData(1, 1);
		mm.cardPrint(list);
	}
	
}

 

LoginForm.java

 

package doodoo.client;
import java.awt.*;
import javax.swing.*;

public class LoginForm extends JFrame{
	public JLabel la1, la2, la3;
	public JTextField tf1, tf2; //ID, PW입력창
	public JRadioButton rb1, rb2; //남/녀
	public JButton b1; //로그인
	public JButton b2;
	public LoginForm() {
		la1 = new JLabel("ID");
		la2 = new JLabel("이름");
		la3 = new JLabel("성별");
		
		tf1 = new JTextField();
		tf2 = new JTextField();
		
		rb1 = new JRadioButton("M");
		rb2 = new JRadioButton("F");
		rb1.setSelected(true);
		ButtonGroup bg = new ButtonGroup(); 
		//라디오버튼은 무조건 하나로 묶어줘야함. 하나만 선택할 수 있게 할려면
		bg.add(rb1); bg.add(rb2);
		
		b1 = new JButton("LOGIN");
		b2 = new JButton("CANCEL");
		
		//배치해봅시다이
		setLayout(null);
		//ID입력
		la1.setBounds(10,15,40,30); 
		tf1.setBounds(55, 15, 150, 30);
		//이름입력
		la2.setBounds(10,50,40,30);
		tf2.setBounds(55,50,150,30);
		//성별 선택
		la3.setBounds(10,85,40,30);
		rb1.setBounds(55, 85, 70, 30);
		rb2.setBounds(130, 85, 70, 30);
		
		JPanel p = new JPanel();
		p.add(b1); p.add(b2);
		p.setBounds(10,125,205,35);
		
		//추가
		add(la1); add(tf1);
		add(la2); add(tf2);
		add(la3); add(rb1); add(rb2);
		add(p);
		
		setSize(230,200);
		setVisible(true);
	}
}

 

MenuForm.java

 

package doodoo.client;
import java.awt.*;
import javax.swing.*;

public class MenuForm extends JPanel{
	public JButton homeBtn;
	public JButton movieBtn;
	public JButton chatBtn;
	public JButton exitBtn;
	//초기화는 생성자에서 한다.
	public MenuForm() {
//		setLayout(new GridLayout(4,1,5,5));
		setLayout(new FlowLayout());
		homeBtn = new JButton("HOME");
		movieBtn = new JButton("MOVIE");
		chatBtn = new JButton("CHAT");
		exitBtn = new JButton("CLOSE");
		
		add(homeBtn);
		add(movieBtn);
		add(chatBtn);
		add(exitBtn);
	}
}

 

PosterCard.java

영화 목록 출력시 포스터와 영화제목 등 간단한 정보를 구성하는 하나하나의 영화 출력 요소를 정의한다.

package doodoo.client;
import java.awt.*;
import javax.swing.*;
import java.net.*;

import doodoo.data.MovieVO;
import doodoo.main.NetworkMain;
public class PosterCard extends JPanel { //윈도우 위에 올리려면 JPanel을 상속
	JLabel poster = new JLabel();
	JLabel title = new JLabel();
	JLabel genre = new JLabel(); //이 세가지를 하나로 묶어서 한 번에 출력하려는 것.
	JLabel regdate = new JLabel();
	
	public PosterCard(MovieVO m) {
		setLayout(null);
		poster.setBounds(5,5,200,270);
		
		try {
			URL url = new URL(m.getPoster());
			Image img = NetworkMain.getImage(new ImageIcon(url), 200, 300);
			poster.setIcon(new ImageIcon(img));
		}catch(Exception ex) {}
		
		title.setBounds(5,285,168,15);
		title.setText(m.getTitle());
		
		regdate.setBounds(5,305,168,15);
		regdate.setText(m.getRegdate());
		
		add(poster);
		add(title);
		add(regdate);
	}
}

 

DetailForm.java

 

package doodoo.client;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class DetailForm extends JPanel implements ActionListener{
	public ControllerPanel cp;
	JLabel posterLa = new JLabel();
	JLabel title = new JLabel();
	JLabel director = new JLabel();
	JLabel genre = new JLabel();
	JLabel regdate = new JLabel();
	JLabel grade = new JLabel();
	JLabel showuser = new JLabel();
	JLabel time = new JLabel();
	JLabel actor = new JLabel();
	JLabel story = new JLabel();
	JLabel video = new JLabel();
	JButton b1, b2;
	
	public DetailForm(ControllerPanel cp) {
		b1 = new JButton("목록");
		b2 = new JButton("예고편");
		this.cp = cp;
//		setBackground(Color.cyan);//영역 확인용
		//배치
		setLayout(null);
		posterLa.setBounds(10, 0,250,450);
		title.setBounds(285, 50, 400, 35);
		director.setBounds(285, 90, 400, 35);
		genre.setBounds(285, 130, 400, 35);
//		grade.setBounds(350,170,400,35);
		regdate.setBounds(285, 170, 400, 35);
		time.setBounds(285, 210, 400, 35);
		actor.setBounds(285, 250, 400, 35);
		showuser.setBounds(285,290,400,35);
		story.setBounds(285,330,400,35);
		
		//목록, 예고편 버튼 있는 패널
		JPanel p = new JPanel();
		p.add(b1); //목록으로 돌아가기
		p.add(b2); //예고편 유튜브영상
		p.setBounds(285,300,120,40);
		
		add(posterLa); add(title);
		add(director); add(genre);
		add(actor); add(story);
		add(regdate); add(p); add(time);
		
		b1.addActionListener(this);
		b2.addActionListener(this);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		//"목록"버튼을 눌렀을 때 홈으로 돌아가게 한다.
		if(e.getSource()==b1) {
			cp.card.show(cp,"HF");
		}else if(e.getSource()==b2) {
			try {
				Runtime.getRuntime().exec("C:\\Program Files\\Google\\
				Chrome\\Application\\chrome.exe "
				+"http://youtube.com/embed/"+video.getText());
			}catch(Exception ex) {}
		}
	}
}

 

ChatForm.java

 

package doodoo.client;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

public class ChatForm extends JPanel{
	public JTable table;
	public DefaultTableModel model;
	public JTextArea ta;
	public JTextField tf;
	public JButton b1, b2;
	public ChatForm() {
		//초기화
		ta = new JTextArea();
		JScrollPane js1 = new JScrollPane(ta);
		ta.setEditable(false);
		
		tf = new JTextField();
		b1 = new JButton("쪽지보내기");
		b2 = new JButton("정보 보기");
		
		String[] col = {"ID","NAME","SEX"};
		String[][] row = new String[0][3];
		model = new DefaultTableModel(row,col) {
			@Override
			public boolean isCellEditable(int row, int column) {
				return false;//편집불가하도록
			}
		};
		table = new JTable(model);
		JScrollPane js2 = new JScrollPane(table);
		
		//배치
		setLayout(null);
		js1.setBounds(10,15,500,500);
		tf.setBounds(10, 520, 500, 30);
		js2.setBounds(515, 15, 300, 470);
		
		JPanel p = new JPanel();
		p.add(b1); p.add(b2);
		p.setBounds(515,490,300,35);
		add(p);
		
		add(js1); add(tf); add(js2);
	}
}

 

MovieFindForm.java

 

package doodoo.client;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

import java.awt.*;
/*
 * Container(윈도우창) 
 * 1) JFrame : 일반 윈도우
 * 2) JPanel : 단독 실행이 불가능(JFrame, JDialog 위에 올라가야 함) 
 *   -> 변경되는 화면을 구현시에 사용
 * 3) JWindow : 타이틀바가 없는 창
 * 4) JDialog : 팝업창
 * Component(기능이 한개인 윈도우, 단독 실행이 불가능하다. JFrame, JPanel 위에)
 * 1) Button : JButton, JRadioButton, JCheckBox
 * 2) 입력창 : 한줄입력(JTextField, JPasswordField), 여러줄입력(JTextArea)
 * JTextArea를 좀 더 발전시킨것이 JTextPane. 
 * 3) JLabel : 보여만 준다(이미지 등 출력에 사용)
 * 4) JTable : 목록 출력
 */
public class MovieFindForm extends JPanel{
	public JTextField tf;
	public JButton btn;
	public JTable table;
	public DefaultTableModel model;
	//초기화&배치~
	public MovieFindForm() {
		tf = new JTextField();
		btn = new JButton("검색");
		String[] col = {"","영화제목","감독"};
		Object[][] row = new Object[0][3]; //이미지, 문자열 등 다양한 걸 다 받아줄 수 있음
		model = new DefaultTableModel(row,col) {
			//익명 클래스 = 생성자 안에서 상속 없이 오버라이딩할 때 사용
			@Override
			public boolean isCellEditable(int row, int column) {
				return false; //편집 방지
			}
			@Override
			public Class<?> getColumnClass(int columnIndex) {
				return getValueAt(0,columnIndex).getClass();
			}
		};
		
		table = new JTable(model);
		table.setRowHeight(40); //html에서 <tr height=40>과 같음.
		table.setShowGrid(false);
		table.setShowHorizontalLines(true);
		table.getTableHeader().setReorderingAllowed(false);//
		
		JScrollPane js = new JScrollPane(table);
		setLayout(null);
		tf.setBounds(10,15,200,30);
		btn.setBounds(215,15,100,30);
		js.setBounds(10,55,800,500);
		
		add(tf);
		add(btn);
		add(js);
	}
	
}

 

WaitForm.java

 

package doodoo.client;

import java.awt.*;
import java.net.URL;
import java.util.ArrayList;

import javax.swing.*;
import javax.swing.table.*;

import doodoo.data.MovieSystem;
import doodoo.data.MovieVO;
import doodoo.main.NetworkMain;
public class WaitForm extends JPanel{
	JTable table;
	DefaultTableModel model;
	JTextArea ta;
	JTextField tf;
	JButton b1, b2;
	JLabel label;
	
	public WaitForm() {//WaitForm이 아니라 영화 목록 보여줄것임.
//		setBackground(Color.cyan);//영역확인
		String[] col = {"포스터","영화 제목"};
		String[][] row = new String[0][2];
		model = new DefaultTableModel(row,col){
			//익명 클래스(생성자 안에서 재정의, 상속 없이 오버라이딩)
			@Override
			public boolean isCellEditable(int row, int column) {
				return false;
			}
			@Override //입력된 클래스가 컬럼으로 추가되도록 함
			public Class<?> getColumnClass(int columnIndex){
				return getValueAt(0,columnIndex).getClass();
			}
		};
		
		table = new JTable(model);
		table.setRowHeight(50);
		JScrollPane js1 = new JScrollPane(table);
		label = new JLabel("랜덤 영화 10선");
		setLayout(null); // 사용자 정의 배치
		label.setBounds(0,80,250,20);
		label.setFont(new Font("돋움",Font.BOLD,15));
		js1.setBounds(0,100,250,450);
		add("center",label);
		add(js1);
		

		try {
			ArrayList<MovieVO> list = MovieSystem.movie10();
			for(MovieVO m:list) {
				URL url = new URL(m.getPoster());
				Image img = NetworkMain.getImage(new ImageIcon(url),50,45);
				Object[] data = {
					new ImageIcon(img), m.getTitle()	
				};
				model.addRow(data);
			}
		}catch(Exception ex) {}
	}
	
}

 

결과물

0123

댓글()