본문 바로가기

Swing/Page Navigation

Page Navigation Links example

리스트를 보여주는 페이지 하단의 네비게이션 링크를 출력할 때 계산하는 예


페이지 하단에 보여주는 내비게이션 링크의 한가지 형태

    << 5 6 7 8 9 >>


문제

페이지 하단에 페이지 링크를 10개씩 보여주고 그 이상의 페이지가 존재한다면 '>>' 등의 기호를 사용하여 다음에 존재하는 링크 10개를 보여주려고 한다

현재 7 페이지가 화면에 출력되어 있는 상태에서 이용자가 '>>' 버튼을 눌러서 다음 링크를 보고자 한다면 어떻게 다음 10개의 링크를 구성하는 번호를 계산해야 하는가?


해결

현재 페이지 번호를 이용하여 다음 네비게이션 링크의 시작번호를 계산한다


현재 화면에 출력된 페이지: 7

현재 페이지 번호를 기반으로, (7-1)/10+1 = 1 으로 계산해보면 1은 1번째 네비게이션 그룹을 의미한다

이 상태에서 이용자가 '>>' 버튼을 눌러서 다음 네비게이션 링크를 요청하면 2번째 네비게이션 그룹을 요청한 것이므로 (7-1)/10+1, 이식의 결과 값에 1을 더하면 다음 네비게이션 그룹의 순번이 (7-1)/10+1+1=2 으로 계산된다

2*10=20 이므로 이용자에게 보여주어야 할 다음 네비게이션 그룹의 마지막 링크는 20이 된다.

그러므로 보여주어야 할 링크의 시작 번호는 20-10+1=11 으로 계산할 수 있다.


결론

한 페이지에 보여줄 네비게이션 링크수 : 10

현재 보여지고 있는 페이지 번호: 7

이 상태에서 이용자가 '>>' 를 눌러 다음 네비게이션 그룹을 요청한 경우,

다음에 보여져야 할 네비게이션 순번: (7-1)/10+1+1=2

보여줄 네비게이션 링크의 마지막 링크: 2*10=20

보여줄 네비게이션 링크의 시작 링크: 20-10+1=11


package org.kdea.swing.pagenavigation;
import java.sql.*;
import java.util.*;

public class PageNavSvc {

	public static void main(String[] args) {
		PageNavSvc nav = new PageNavSvc();
		List<EmpVO> list = nav.getList(1);
		NavigationVO nvo = nav.getNavVO();
	}
	
	private Connection conn;
	private PreparedStatement pstmt;
	private ResultSet rs;
	
	private String jdbc_driver = "oracle.jdbc.OracleDriver";
	private String db_url = "jdbc:oracle:thin:@localhost:1521:xe";
	private String usrId = "scott";
	private String pwd = "TIGER";
	
	private boolean DEBUG = true;
	private boolean leftMore;
	private boolean rightMore;
	private int pg = 1;
	private static int rowsPerPage = 3;
	private static int numsPerPage = 3;
	//private HttpServletRequest request;
	
	public List<EmpVO> getList(int page) {
        this.pg = page;
		conn = getConn();
		String sql = 
		"SELECT * FROM "+
		"( "+
		   "SELECT t1.*, TRUNC((ROWNUM-1)/3)+1 page FROM "+
		   "( "+
			  "SELECT empno, "+
              "LPAD(' ', (LEVEL-1)*4,' ') || DECODE(LEVEL,1,'','┕ ')||ename as ename, "+
			  "hiredate, sal, deptno FROM emp "+
              "START WITH ename='KING' "+
			  "CONNECT BY PRIOR empno=mgr "+
              "order siblings by empno "+
           ") t1 "+
        ") "+
        "WHERE page=?";
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, page);
			rs = pstmt.executeQuery();
			List<EmpVO> list = new ArrayList<EmpVO>();
			while(rs.next()) {
				EmpVO emp = new EmpVO();
				emp.setEmpno(rs.getInt("EMPNO"));
				emp.setEname(rs.getString("ENAME"));
				emp.setHiredate(rs.getDate("HIREDATE"));
				list.add(emp);
			}
			return list;
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			closeAll();
		}
		return null;
	}
	/** 
	 * 위의 getList()를 호출하여 리스트를 구한 다음, getNavVO()를 호출하여 네비게이션 링크를 구하면 된다
     */
	public NavigationVO getNavVO() {
		NavigationVO nav = new NavigationVO();
		nav.setCurrPage(pg);
		nav.setLinks(getNavLinks(pg, rowsPerPage, numsPerPage));
		nav.setLeftMore(leftMore);
		nav.setRightMore(rightMore);
		return nav;
	}

	/**
	 * 화면에 리스트를 출력할 때 하단에 보여줄 페이지 네비게이션 링크를 계산하여 정수배열로 리턴함
	 * @param page 현재 화면에 보여지고 있는 페이지 번호
	 * @param rowsPerPage 한 화면(한 페이지)에 보여줄 리스트의 행수
	 * @param numsPerPage 한 화면(한 페이지)에 보여줄 페이지 네비게이션 링크 수
	 * @return 해당 페이지에 보여줄 페이지 네비게이션 링크 배열(정수배열)
	 */
	private int[] getNavLinks(int page, int rowsPerPage, int numsPerPage) {
		conn = getConn();
		String sql = "SELECT count(*) FROM EMP";
		int totalRows = 0;
		try {
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();
			if(rs.next()) {
				totalRows = rs.getInt(1);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}  finally {
			closeAll();
		}
		int totalPages = (totalRows-1)/rowsPerPage+1;
		System.out.printf("%d행씩 총페이지 수:%d \n", rowsPerPage, totalPages);
		
		int tmp = (page-1)/numsPerPage+1; // 몇번째 링크그룹에 속하는가?
		int end = tmp*numsPerPage;
		int start = (tmp-1)*numsPerPage+1;
		
		if(start==1) leftMore = false; // << 왼쪽 이동 출력여부
		else leftMore = true;
		if(end>=totalPages) {		 // >> 오른쪽 이동 출력여부
			end = totalPages;
			rightMore = false;
		}else rightMore = true;
		//System.out.printf("START:%d~END:%d \n",start, end);
		
		int[] links = new int[end-start+1];
		for(int num=start,i=0;num<=end;num++,i++) {
			links[i] = num;
		}
		if(DEBUG) printLinks(links);
		return links;
	}
	
	// 디버깅 출력용
	private void printLinks(int[] links) {
		if(leftMore) System.out.print("<< ");
		for(int i=0;i<links.length;i++) {
			System.out.printf("%d ", links[i]);
		}
		if(rightMore) System.out.print(" >>");
		System.out.println();
	}
	
	private Connection getConn() {
		try {
			Class.forName(jdbc_driver);
			conn = DriverManager.getConnection(db_url,"scott","TIGER");
			return conn;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	private void closeAll() {
		try {
			if(conn!=null) conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

class EmpVO {
	
	private int empno;
	private String ename;
	private java.sql.Date hiredate;
	
	public int getEmpno() {
		return empno;
	}
	public void setEmpno(int empno) {
		this.empno = empno;
	}
	public String getEname() {
		return ename;
	}
	public void setEname(String ename) {
		this.ename = ename;
	}
	public java.sql.Date getHiredate() {
		return hiredate;
	}
	public void setHiredate(java.sql.Date hiredate) {
		this.hiredate = hiredate;
	}
}

public class NavigationVO {

	private int currPage;
	private int[] links;
	private boolean leftMore;
	private boolean rightMore;

	public int getCurrPage() {
		return currPage;
	}
	public void setCurrPage(int currPage) {
		this.currPage = currPage;
	}
	public int[] getLinks() {
		return links;
	}
	public void setLinks(int[] links) {
		this.links = links;
	}
	public boolean isLeftMore() {
		return leftMore;
	}
	public void setLeftMore(boolean leftMore) {
		this.leftMore = leftMore;
	}
	public boolean isRightMore() {
		return rightMore;
	}
	public void setRightMore(boolean rightMore) {
		this.rightMore = rightMore;
	}
}