본문 바로가기
국비학원/수업기록

국비 지원 개발자 과정_Day30

by 루팽 2023. 1. 6.

오라클 계정과 권한

계정 SYS

Oracle DB관리자로 Super user이다

시스템의 총 관리자로 SYSDBA권한을 갖는다

 

계정 SYSTEM

SYS와 유사한 권한을 갖지만, DB 생성과 삭제는 불가능

운영을 위한 권한을 갖는다

 

권한 SYSOPER

데이터베이스를 운영, 관리하기 위한 권한으로 SYSTEM계정이 갖는다

데이터베이스 자체를 생성, 삭제하거나 다른 유저 소유의 데이터에는 접근할 수 없다

 

권한 SYSDBA

SYSOPER의 권한뿐 아니라 데이터베이스의 생성, 삭제, Oracle 시스템에서 모든 권한이 가능하고 SYS계정이 갖는다

 

--PK라 인덱스가 있어서 오름차순 정렬되어있음(ctrl+e로 실행계획 확인)
SELECT empno FROM emp;

--정렬되어있지 않음
SELECT ename FROM emp;

--인덱스를 만들어도 위의 것은 정렬X
CREATE INDEX i_ename
ON emp(ename asc);

--하지만 where문을 넣으면 정렬이 됨
--인덱스는 조건이 있어야 사용 가능하다
SELECT ename FROM emp
WHERE ename IS NOT NULL;

--정렬X
SELECT ename FROM emp
WHERE NVL(ename, '') != '';

--정렬X
SELECT ename FROM emp
WHERE NVL(ename, '') IS NOT NULL;

--정렬은 됐지만 인덱스사용X, 정렬을 한 후 다시 테이블을 읽는다
SELECT ename FROM emp
ORDER BY ename asc;

--힌트문을 넣었지만 인덱스가 사용되지 않음
SELECT /*+index_desc(emp i_ename*/ ename
FROM emp;

--조건을 달아주면 인덱스 정렬 사용
--인덱스가 존재하더라도 조건절에 사용되지 않으면 옵티마이저는 실행계획에 반영하지 않는다
SELECT /*+index_desc(emp i_ename)*/ ename
FROM emp
WHERE ename IS NOT NULL;

--PK는 오라클에서 기본적으로 인덱스를 제공한다
--게다가 유니크 인덱스이다
--어떠한 가공을 하더라도 실행계획에서 인덱스를 사용한 조회가 이루어진다
--
--사용자 정의 인덱스는 중복값이 허용되는 인덱스이다
--해당 컬럼을 가공하면 실행계획에서 인덱스 사용이 불가하다
--
--인덱스가 있으면 ORDER BY를 사용하지 않고 정렬이 된다
--디폴트는 오름차순이다

--unique인덱스는 어떤 조건이 오든,
--해당 컬러멩 함수를 사용하더라도 무조건 인덱스를 사용한 실행계획으로 처리한다
SELECT empno FROM emp
WHERE NVL(empno, 0) > 0;

SELECT empno FROM emp
WHERE DEOCDE(empno, 0, null, empno) > 0;

SELECT empno FROM emp
WHERE empno IS NOT NULL;

 

/* Formatted on 2023/01/06 오전 11:38:25 (QP5 v5.215.12089.38647) */
SELECT * FROM employee;

--insert문 안쓰고 편하기 편집하기
EDIT employee;

--부서번호가 d9 혹은 d6이면서 급여가 3천 이상인 사람
SELECT emp_name,
       emp_no,
       email,
       dept_code,
       salary,
       bonus
  FROM employee
 WHERE dept_code = 'D9' AND salary >= 30000000 OR dept_code = 'D6';

--or문을 쓸 때 ()를 안붙이면 조건 설정이 어긋남(AND이 우선처리)
SELECT emp_name,
       emp_no,
       email,
       dept_code,
       salary,
       bonus
  FROM employee
 WHERE dept_code = 'D9' OR dept_code = 'D6' AND salary >= 30000000;

--()를 넣어주면 원하는 조건대로 출력됨
SELECT emp_name,
       emp_no,
       email,
       dept_code,
       salary,
       bonus
  FROM employee
 WHERE (dept_code = 'D9' OR dept_code = 'D6') AND salary >= 30000000;

--or보다 in을 사용하는걸 권장
SELECT emp_name,
       emp_no,
       email,
       dept_code,
       salary,
       bonus
  FROM employee
 WHERE dept_code IN ('D9', 'D6') AND salary >= 30000000;

--SUBSTR(char, n)은 char의 n번째 자리부터 문자열 끝까지를 돌려준다.
--SUBSTR(char, n, m)은 char의 n번째 자리부터 m번째에 해당하는 문자열을 돌려준다.
--0과 1 시작은 차이가 없다
SELECT SUBSTR ('oracle', 0, 2),
       SUBSTR ('oracle', 1, 2),
       SUBSTR ('oracle', 2, 5),
       SUBSTR ('oracle', 0),
       SUBSTR ('oracle', 1)
  FROM DUAL;

SELECT SUBSTR ('오라클', 1, 3),
       SUBSTR ('오라클', 2),
       SUBSTR ('오라클', 1, 2)
  FROM DUAL;

--SUBSTRB(char, n, m)는 byte단위로 char의 n번째 자리부터 m번째에 해당하는 문자열을 돌려준다.
--한글은 2byte이지만 길이나 문자를 한 개로 인식하기때문에 이를 원래 길이인 2로 인식한다는 의미
SELECT SUBSTRB ('오라클', 1, 3),
       SUBSTRB ('오라클', 2),
       SUBSTRB ('오라클', 1, 2)
  FROM DUAL;

SELECT SUBSTR ('ORACLE PROJECT', 1, 3) substr1,
       SUBSTR ('ORACLE PROJECT', 4, 3) substr2,
       SUBSTR ('ORACLE PROJECT', 10) substr3
  FROM DUAL;

SELECT SUBSTRB ('오라클 PROJECT', 1, 2) substr1,
       SUBSTRB ('오라클 PROJECT', 4, 5) substr2,
       SUBSTRB ('오라클 PROJECT', 10) substr3
  FROM DUAL;

--주민번호로 여자, 남자 구별하기
SELECT SUBSTR ('860330-143456', 8, 1), SUBSTR ('860330-243456', 8, 1)
  FROM DUAL;
  
--주민번호 비교 다른 방법
SELECT emp_name, emp_no
  FROM employee
 WHERE emp_no LIKE '%-1%';

SELECT emp_name, emp_no
  FROM employee
 WHERE emp_no LIKE '%-2%';
 
 
--escape 사용해서 이메일 구별
--앞에 세자리 다음에 _가 있는 사람 찾기
SELECT emp_name, email
  FROM employee
 WHERE email LIKE '___#_%' ESCAPE '#';

--escape문자는 아무거나 사용 가능
SELECT emp_name, email
  FROM employee
 WHERE email LIKE '__@_%' ESCAPE '@';

 
--부서번호가 d9 혹은 d6이고, 연봉3천이상, 보너스가 있고 이메일 4번째자리가 _인 사람
SELECT emp_name,
       emp_no,
       email,
       dept_code,
       salary,
       bonus
  FROM employee
 WHERE     dept_code IN ('D9', 'D6')
       AND salary >= 30000000
       AND SUBSTR (emp_no, 8, 1) = 1
       AND bonus IS NOT NULL
       AND email LIKE '___#_%' ESCAPE '#';

 

package dev_java.basic3;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import dev_java.util.DBConnectionMgr;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;

public class ZipCodeSearchView extends JFrame implements ItemListener, FocusListener, ActionListener, MouseListener {
  // 선언부
  // 사용자가 선택한 zdo
  String zdo = null;
  // 사용자가 선택한 sigu
  String sigu = null;
  // 사용자가 선택한 dong
  String dong = null;

  // DB에서 가져온 zdos[]
  String[] zdos = null;
  // 사DB에서 가져온 sigus[]
  String[] sigus = null;
  // DB에서 가져온 dongs[]
  String[] dongs = null;
  // 중분휴(sigu), 소분류(dong)
  String totals[] = { "전체" };
  // 북쪽에 붙이는 속지 패널 - 콤보박스3개, JTextfield, JButton 붙임
  // FlowLayout-배치역할, 중앙에서 좌우로 펼쳐지면서 배치가 됨
  // JPanel jp_north = new JPanel(); // 디폴트 레이아웃이 FlowLayout
  JPanel jp_north = new JPanel(new FlowLayout(FlowLayout.LEFT)); // 생성자를 이용해 위치를 왼쪽으로 바꿈
  JComboBox jcb_zdo = null;
  JComboBox jcb_sigu = null;
  JComboBox jcb_dong = null;
  //////////////////// [[DB 연동 시작]] ////////////////////
  // 물리적으로 떨어져있는 오라클 서버에 접속하는데 필요한 공통 코드
  DBConnectionMgr dbMgr = new DBConnectionMgr(); // Driverclass, 커넥션정보가 들어있음
  Connection con = null; // 인터페이스
  PreparedStatement pstmt = null; // 인터페이스 - 동적쿼리처리
  ResultSet rs = null; // 오라클서버의 커서를 조작하는 인터페이스 - next(), previous() 제공
  //////////////////// [[DB 연동 끝]] ////////////////////

  // 동이름을 입력받는 텍스트필드와 조회버튼 추가
  // 생성자 파라미터 자리를 이용하면 추가적인 메소드 호출 없이도 해당화면에대한
  // 추가적인 초기화 작업이 가능하니까 코드의 양을 줄일 수 있다
  // 이른 인스턴스화이다
  JTextField jtf_search = new JTextField("동이름을 입력하세요", 20);
  JButton jbtn_search = new JButton("조회");

  // 테이블 생성
  String[] cols = { "우편번호", "주소" };
  String[][] data = new String[0][3];
  DefaultTableModel dtm_zipcode = new DefaultTableModel(data, cols);
  JTable jtb_zipcode = new JTable(dtm_zipcode);
  JTableHeader jth_zipcode = jtb_zipcode.getTableHeader();
  JScrollPane jsp_zipcode = new JScrollPane(jtb_zipcode, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
      JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

  // 멤버십 선언
  Membership membership = null;

  // 생성자
  public ZipCodeSearchView() {
    jtf_search.addFocusListener(this);
    jtf_search.addActionListener(this);
    jbtn_search.addActionListener(this);
    zdos = getZDOList();
    jcb_zdo = new JComboBox<>(zdos);
    jcb_sigu = new JComboBox<>(totals);
    jcb_dong = new JComboBox<>(totals);
    jcb_zdo.addItemListener(this);
    jcb_sigu.addItemListener(this);
    jcb_dong.addItemListener(this);
    jtb_zipcode.addMouseListener(this);
  }

  public ZipCodeSearchView(Membership membership) {
    // this 뒤에 괄호가 있으면 자기자신의 디폴트 생성자 호출
    this(); // 나 자신의 디폴트 생성자 호출
    this.membership = membership;
    this.initDisplay();
  }

  // 대분류 정보 초기화에 필요한 DB조회하기 구현
  public String[] getZDOList() {
    StringBuilder sql = new StringBuilder();
    sql.append("SELECT '전체' ZDO FROM DUAL ");
    sql.append("UNION ALL ");
    sql.append("SELECT zdo ");
    sql.append("  FROM (  SELECT DISTINCT (ZDO) ZDO ");
    sql.append("    FROM zipcode_t ");
    sql.append("    ORDER BY ZDO ASC)");
    try {
      // con의 주소번지가 확인되면 오라클서버와 연결통로가 확보된 것
      con = dbMgr.getConnection();
      pstmt = con.prepareStatement(sql.toString());
      // 오라클에서 생성된 테이블의 커서 디폴트위치는 항상 isTop이다
      rs = pstmt.executeQuery();
      Vector<String> v = new Vector<>();
      while (rs.next()) {
        String zdo = rs.getString("zdo");
        v.add(zdo);
      }
      zdos = new String[v.size()];
      v.copyInto(zdos);
    } catch (SQLException se) {
      System.out.println(se.toString());
      System.out.println(sql.toString());
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        // 사용한 자원 반납하기 - 생성된 역순으로 할 것
        // 생략해도 언젠가 반납은 이루어짐, 명시적으로 반납처리 권장
        // 왜냐하면 오라킁 서버에서 커넥션을 강제로 종료시켜버리니까
        dbMgr.freeConnection(con, pstmt, rs);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    return zdos;
  } // end of getZDOList

  // 중분류 정보 초기화에 필요한 DB조회하기 구현
  public String[] getSIGUList(String zdo) {
    StringBuilder sql = new StringBuilder();
    sql.append("SELECT '전체' sigu FROM DUAL ");
    sql.append("UNION ALL ");
    sql.append("SELECT sigu ");
    sql.append("  FROM (  SELECT DISTINCT (sigu) sigu ");
    sql.append("    FROM zipcode_t ");
    sql.append("    WHERE zdo = ? ");
    sql.append("    ORDER BY sigu ASC)");
    try {
      con = dbMgr.getConnection();
      pstmt = con.prepareStatement(sql.toString());
      pstmt.setString(1, zdo);
      rs = pstmt.executeQuery();
      Vector<String> v = new Vector<>(); // copyInto() 사용하기위해 벡터사용
      while (rs.next()) {
        String sigu = rs.getString("sigu");
        v.add(sigu);
      }
      // sigu콤보박스에 들어갈 배열 생성하기
      sigus = new String[v.size()];
      // 벡터에 들어있는 값 String 배열에 복사하기
      v.copyInto(sigus);
    } catch (SQLException se) {
      System.out.println(se.toString());
      System.out.println(sql.toString());
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        dbMgr.freeConnection(con, pstmt, rs);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    return sigus;
  }

  // 소분류 정보 초기화에 필요한 DB조회하기 구현
  public String[] getDONGList(String sigu) {
    StringBuilder sql = new StringBuilder();
    sql.append("SELECT '전체' DONG FROM DUAL ");
    sql.append("UNION ALL ");
    sql.append("SELECT DONG ");
    sql.append("  FROM (  SELECT DISTINCT (DONG) DONG ");
    sql.append("    FROM zipcode_t ");
    sql.append("    WHERE sigu = ? ");
    sql.append("    ORDER BY DONG ASC) ");
    try {
      con = dbMgr.getConnection();
      pstmt = con.prepareStatement(sql.toString());
      pstmt.setString(1, sigu);
      rs = pstmt.executeQuery();
      Vector<String> v = new Vector<>();
      while (rs.next()) {
        String dong = rs.getString("dong");
        v.add(dong);
      }
      dongs = new String[v.size()];
      v.copyInto(dongs);
    } catch (SQLException se) {
      System.out.println(se.toString());
      System.out.println(sql.toString());
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        dbMgr.freeConnection(con, pstmt, rs);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    return dongs;
  }

  // 화면처리부
  public void initDisplay() {
    jth_zipcode.setBackground(Color.orange);
    jth_zipcode.setFont(new Font("맑은고딕", Font.BOLD, 15));
    jth_zipcode.getColumnModel().getColumn(0).setPreferredWidth(100); // 우편번호 간격
    jth_zipcode.getColumnModel().getColumn(1).setPreferredWidth(500); // 주소 간격
    // 그리드 색상 설정
    jtb_zipcode.setGridColor(Color.red);
    // 윈도우창 닫기 버튼 - 자원 회수하기
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jp_north.add(jcb_zdo);
    jp_north.add(jcb_sigu);
    jp_north.add(jcb_dong);
    jp_north.add(jtf_search);
    jp_north.add(jbtn_search);
    this.add("North", jp_north);
    this.add("Center", jsp_zipcode);
    this.setSize(630, 400);
    this.setVisible(false);
  }

  // 조회버튼 눌렀을 때 새로고침
  public void refreshData(String zdo, String dong) {
    System.out.println("refreshData 호출 성공");
    StringBuilder sql = new StringBuilder();
    sql.append("SELECT zipcode, address ");
    sql.append("  FROM zipcode_t ");
    sql.append("  WHERE 1 = 1 ");
    // zod가 존재할 경우
    if (zdo != null && zdo.length() > 0) { // 빈 문자열이 아닌 것도 필터링
      sql.append("    AND zdo = ? ");
    }
    // dong이 존재할 경우
    if (dong != null && dong.length() > 0) {
      sql.append("    AND dong LIKE ? || '%'");
    }
    int i = 1;
    try {
      con = dbMgr.getConnection(); // 오라클 서버와 연결
      // 들어있는 타입과 형전환이 잘못 선택되면 ClassCastingException 발생 가능
      pstmt = con.prepareStatement(sql.toString()); // 들어있는 타입이 String이니까 형변환 문제없음
      if (zdo != null && zdo.length() > 0) {
        pstmt.setString(i++, zdo);
      }
      if (dong != null && dong.length() > 0) {
        pstmt.setString(i++, dong);
      }
      // 입력, 수정, 삭제인 경우에는 executeUpdate()를 사용하고 리턴타입은 int
      // 조회인 경우에는 executeQuery()를 사용하고 리턴타입은 ResultSet
      // 테이블을 생성할 때는 execute()를 사용함
      // 업무가 바뀌더라도 변하는 건 테이블명과 컬럼명만 변함 -> 다른건 그대로 재사용가능
      // -> ORM솔루션(myBatis) -> JPA기술(Hibernate-쿼리문이 없음) 출현, 활용
      rs = pstmt.executeQuery();
      List<Map<String, Object>> zipList = new ArrayList<>();
      Map<String, Object> rMap = null;
      while (rs.next()) {
        rMap = new HashMap<>();
        rMap.put("zipcode", rs.getString("zipcode"));
        rMap.put("address", rs.getString("address"));
        zipList.add(rMap);
      }
      // 컬렉션에서 제공하는 클래스는 주소번지를 출력하더라도 그 구조안에 있는 값들이 출력됨
      System.out.println(zipList);
      // 화면 처리하기 - 테이블 새로고침하기
      // 조회결과가 나온 경우
      if (zipList.size() > 0) {
        // 조회를 연속하여 요청할 경우 기존에 조회된 화면은 지워주기
        while (dtm_zipcode.getRowCount() > 0) { // JTable은 양식일 뿐, 실제데이터는 DefaultTableModel
          dtm_zipcode.removeRow(0);
        } // end of while
        // 새로 조회된 결과 출력
        for (int x = 0; x < zipList.size(); x++) {
          Map<String, Object> rMap2 = zipList.get(x);
          Vector<String> oneRow = new Vector<>();
          oneRow.add(0, rMap2.get("zipcode").toString());
          oneRow.add(1, rMap2.get("address").toString());
          dtm_zipcode.addRow(oneRow);
        } // end of for
      }
    } catch (SQLException se) {
      System.out.println(se.toString());
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      // 사용한 자원은 반드시 명시적으로 반납할 것(안하면 JVM이 언젠가는 해줌)
      // 그 시간을 앞당기는 코드
      dbMgr.freeConnection(con, pstmt, rs);
    }
  } // end of refreshData()

  // 메인메소드
  public static void main(String[] args) {
    JFrame.setDefaultLookAndFeelDecorated(true);
    ZipCodeSearchView zcsv = new ZipCodeSearchView();
    zcsv.initDisplay();
  }

  @Override
  public void itemStateChanged(ItemEvent ie) {
    // 이벤트가 감지되는 소스 가져오기
    Object obj = ie.getSource();
    // ZDO 콤보박스인지 확인
    if (obj == jcb_zdo) {
      if (ie.getStateChange() == ItemEvent.SELECTED) {
        System.out.println("선택한 ZDO: " + zdos[jcb_zdo.getSelectedIndex()]);
        zdo = zdos[jcb_zdo.getSelectedIndex()];
        sigus = getSIGUList(zdo);
        // 대분류가 경정이 되었을 때 sigus를 초기화 해줘야 함
        // 기존에 디폴트로 전체 상수값을 널어두었으니 이것을 삭제하고
        // 새로운 DB서버에서 읽어온 값으로 아이템을 추가해야한다.
        jcb_sigu.removeAllItems();
        for (int i = 0; i < sigus.length; i++) {
          jcb_sigu.addItem(sigus[i]);
        }
      }
    }
    // sigu 콤보박스인지 확인
    else if (obj == jcb_sigu) {
      if (ie.getStateChange() == ItemEvent.SELECTED) {
        System.out.println("선택한 SIGU: " + sigus[jcb_sigu.getSelectedIndex()]);
        sigu = sigus[jcb_sigu.getSelectedIndex()];
        dongs = getDONGList(sigu);
        jcb_dong.removeAllItems();
        for (int i = 0; i < dongs.length; i++) {
          jcb_dong.addItem(dongs[i]);
        }
      }
    }
    // dong 콤보박스인지 확인
    else if (obj == jcb_dong) {
      if (ie.getStateChange() == ItemEvent.SELECTED) {
        System.out.println("선택한 DONG: " + dongs[jcb_dong.getSelectedIndex()]);
        if (!"전체".equals(dongs[jcb_dong.getSelectedIndex()])) {
          jtf_search.setText(dongs[jcb_dong.getSelectedIndex()]);
        }
      }
    }
  }

  @Override
  public void focusGained(FocusEvent e) {
    if (e.getSource() == jtf_search) {
      jtf_search.setText("");
    }
  }

  // 아래의 메소드는 구현할 필요가 없지만 지우면 에러 발생 -> 추상메소드니까
  // 인터페이스를 implements하면 반드시 구현체 클래스가 되어야하므로
  // 인터페이스가 소지한 모든 추상메소드를 구현해야한다.
  @Override
  public void focusLost(FocusEvent e) {
    // JVM은 중괄호로만 묶여있어도 구현으로 본다
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    Object obj = e.getSource();
    // 조회버튼을 눌렀을 때
    if (jbtn_search == obj || jtf_search == obj) {
      String myDong = jtf_search.getText();
      refreshData(zdo, myDong);
    }
  }

  @Override
  public void mouseClicked(MouseEvent e) {
    // TODO Auto-generated method stub
  }

  @Override
  public void mousePressed(MouseEvent e) {
    // 더블클릭을 했을 때
    if (e.getClickCount() == 2) {
      // JTable에서 사용자가 선택한 로우의 index값을 담기
      int index = jtb_zipcode.getSelectedRow(); // 한 개 선택
      // int[] index = jtb_zipcode.getSelectedRows(); // 여러 개 선택
      for (int i = 0; i < dtm_zipcode.getRowCount(); i++) {
        if (jtb_zipcode.isRowSelected(i)) {
          String address = dtm_zipcode.getValueAt(i, 1).toString();
          membership.jtf_zipcode.setText(String.valueOf(dtm_zipcode.getValueAt(i, 0)));
          membership.jtf_address.setText(address);
        }
      }
      dispose();
    }
  }

  @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
  }
}

 

package dev_java.basic3;

import javax.swing.JFrame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.awt.Image;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.Container;

public class Membership extends JFrame implements ActionListener {
  JPanel jp_center = new JPanel();
  JFileChooser myFileChooser = new JFileChooser();
  // 우편번호 화면 추가
  JLabel jlb_zipcode = new JLabel("우편번호");
  JLabel jlb_address = new JLabel("주소");
  JTextField jtf_zipcode = new JTextField(6);
  JTextField jtf_address = new JTextField(30);
  JButton jbtn_zipcode = new JButton("우편번호");

  JButton jbtn_file = new JButton("파일찾기");
  JTextField jtf_file = new JTextField(45);
  JLabel jlb_img = new JLabel("이미지");
  Container cont = this.getContentPane();
  ZipCodeSearchView zsView = new ZipCodeSearchView(this);

  public void initDisplay() {
    jbtn_file.addActionListener(this);
    jbtn_zipcode.addActionListener(this);
    // 윈도우창에서 x버튼 눌렀을 때 창 닫기 구현
    // 윈도우 리스너 설정
    this.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent evt) {
        System.out.println("윈도우 종료");
        System.exit(0);
      }
    });
    jp_center.setLayout(null);
    jlb_zipcode.setBounds(20, 20, 100, 20);
    jtf_zipcode.setBounds(120, 20, 100, 20);
    jbtn_zipcode.setBounds(230, 20, 100, 20);
    jlb_address.setBounds(20, 45, 100, 20);
    jtf_address.setBounds(120, 45, 250, 20);
    jbtn_file.setBounds(20, 70, 90, 20);
    jtf_file.setBounds(120, 70, 350, 20);
    jlb_img.setBorder(BorderFactory.createEtchedBorder());
    jlb_img.setBounds(120, 95, 200, 270);
    jp_center.add(jlb_zipcode);
    jp_center.add(jlb_address);
    jp_center.add(jtf_zipcode);
    jp_center.add(jtf_address);
    jp_center.add(jbtn_zipcode);
    jp_center.add(jbtn_file);
    jp_center.add(jtf_file);
    jp_center.add(jlb_img);
    this.add("Center", jp_center);
    this.setTitle("이미지 미리보기");
    this.setSize(500, 580);
    this.setVisible(true);
  }

  public static void main(String[] args) {
    Membership ir = new Membership();
    ir.initDisplay();
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    Object obj = e.getSource();
    if (jbtn_file == obj) {
      // [열기] 대화상자를 오픈한다
      myFileChooser
          .setCurrentDirectory(new File("D:\\\\vscode_java\\\\dev_java\\\\app\\\\src\\\\main\\\\java\\\\dev_java\\\\images\\\\book\\\\"));
      int intRet = myFileChooser.showOpenDialog(Membership.this);
      // yes 혹은 ok 버튼이 눌린 경우
      if (intRet == JFileChooser.APPROVE_OPTION) {
        // 파일을 여는 처리를 수행한다
        try {
          // 읽어들이기용 String 객체
          String strLine;
          // FileChooser로 선택된 파일을 File 객체에 대입
          File myFile = myFileChooser.getSelectedFile();

          // 선택된 파일의 절대 경로를 지정하여
          // BufferedReader 객체를 작성
          BufferedReader myReader = new BufferedReader(new FileReader(myFile.getAbsolutePath()));
          System.out.println("myFile.getAbsolutePath():" + myFile.getAbsolutePath());
          String cpath = "";
          cpath = myFile.getAbsolutePath();
          jtf_file.setText(myFile.getAbsolutePath());
          /////////////////////// 이미지 미리보기 시작 //////////////////////
          ImageIcon originIcon = new ImageIcon(cpath);
          // ImageIcon에서 Image를 추출
          Image originImg = originIcon.getImage();
          // 추출된 Image의 크기를 조절하여 새로운 Image객체 생성
          Image changedImg = originImg.getScaledInstance(200, 270, Image.SCALE_SMOOTH);
          // 새로운 Image로 ImageIcon객체를 생성
          ImageIcon Icon = new ImageIcon(changedImg);
          jlb_img.setIcon(Icon);
          /*
           * revalidate새 구성 요소가 추가되거나 이전 구성 요소가 제거되면 컨테이너에서 호출됩니다. 이 호출은 레이아웃 관리자에게 새 구성
           * 요소 목록을 기반으로 재설정하도록 지시하는 명령입니다.
           */
          cont.revalidate();
          /////////////////////// 이미지 미리보기 끝 //////////////////////
        } catch (IOException ie) {
        }
      } ///////// end of if
    }
    // 우편번호 찾기 버튼을 눌렀을 때
    else if (jbtn_zipcode == obj) {
      if (zsView.jtf_search != null || zsView.jtb_zipcode != null) {
        zsView.jtf_search.setText("");
        while (zsView.dtm_zipcode.getRowCount() > 0) { // JTable은 양식일 뿐, 실제데이터는 DefaultTableModel
          zsView.dtm_zipcode.removeRow(0);
        }
        zsView.jcb_zdo.setSelectedIndex(0);
      }
      zsView.setVisible(true);
    }
  }
}

댓글