Gxt , Ext Gwt강좌2011. 1. 6. 16:46
2011/01/06 - [Gxt , Ext Gwt강좌] - Ext Gwt[Gxt] 강좌06-BorderLayout을 이용한 화면프레임 구성하기

1. 우선 패키지를 하나 생성하자. com.hansol.gxtsmpl.client밑에 programs라는 패키지를 생성하자 우리는 이 패키지
     안에 새로 만들 프로그램을 추가할 것이다.

2. 패키지를 추가했다면 앞서 강좌05에서 생성한 화면의 중간에 들어갈 클래스를 생성해 보도록 하자.

3. 패키지명은 GridSmplTabItem.java로 생성하자.
     com.hansol.gxtsmpl.client.programs.GridSmplTabItem.java

4. 소스를 그대로 따라해보자. 우선 이 클래스는 TabPanel(강좌05에서 설명한 중간패널이(TabPanel이다.)에
     추가될 것이므로 TabItem을 상속 받도록 하자
public class GridSmplTabItem  extends TabItem {   
  public GridSmplTabItem() {   
    // 현재생성한 TabItem의 표기이름 지정   
    setText("Grid List");   
    // ViewPort를 탑재할 Container   
    LayoutContainer lc = new LayoutContainer();   
    // 실제 화면  UI를 탑재할 VerticalPanel    
    VerticalPanel vp = new VerticalPanel();   
    vp.setSpacing(10); // Margin   
    lc.add(vp); // LayoutContainer에 VerticalPanel을 추가한다.   
    lc.setLayout(new FlowLayout(10)); // LayoutContainer의 Layout지정   
     add(lc); // LayoutContainer를 TabItem에 추가한다.   
  }   
} 
5. GxtApp를 수정하여 위에서 생성한 클래스를 화면 중간에 삽입하고 GxtApp몯률을 실행해서 결과를 확인 해보자..
private void setTabitem() {   
  TabPanel tabPanel = new TabPanel();   
  tabPanel.setCloseContextMenu(true);   
  tabPanel.setBorderStyle(false);   
  tabPanel.setBodyBorder(false);   
  tabPanel.setTabScroll(true);   
  tabPanel.setAnimScroll(true);   
  GridSmplTabItem grid = new GridSmplTabItem(); // Grid Smpl   
  tabPanel.add(grid); // Grid Smpl을 TabPanel에 추가   
  centerPanel.add(tabPanel);   
}  
6. Grid를 추가할 패널을 생성해보자
ContentPanel downGridPanel; // Grid를 추가할 패널    
  
public void prepareService(){ //메소드를 추가하고   
  downGridPanel = new ContentPanel();   
  downGridPanel.setHeading("관리자 현황");   
  downGridPanel.setWidth(800);   
  downGridPanel.setHeight(400);   
}  
7. 생성자에 위의 메소드가 실행될 수 있도록 추가하자
public GridSmplTabItem() {   
    // 현재생성한 TabItem의 표기이름 지정   
    setText("Grid List");   
    // ViewPort를 탑재할 Container   
    LayoutContainer lc = new LayoutContainer();   
    // 실제 화면  UI를 탑재할 VerticalPanel    
    VerticalPanel vp = new VerticalPanel();   
    vp.setSpacing(10); // Margin   
    prepareService(); // 추가.   
    lc.add(vp); // LayoutContainer에 VerticalPanel을 추가한다.   
    lc.setLayout(new FlowLayout(10)); // LayoutContainer의 Layout지정   
     add(lc); // LayoutContainer를 TabItem에 추가한다.   
  }  
8. Grid를 만들기 전에 Grid에서 사용할 Entity Class를 만들도록 하자. 이 클래스는 Grid를 생성할 때 하나의 로우에 삽입되는 객체라고 생각하면 되겠다. com.hansol.gxtsmpl.client.model패키지를 추가하고 LoginUsesrInfo.java를 생성한다. 우선 아래와 같이 코딩하도록 하자
package com.hansol.gxtsmpl.client.model;   
import java.io.Serializable;   
import java.util.Date;   
import com.extjs.gxt.ui.client.data.BaseTreeModel;   
public class LoginUserInfo  extends BaseTreeModel implements Serializable {   
  public LoginUserInfo() {   
    // TODO Auto-generated constructor stub   
  }   
  public void setUserName(String userName){   set("userName", userName);   }   
  public void setUserSabun(String userSabun){   set("userSabun", userSabun);  }   
  public void setUserOrgOid(String userOrgOid){  set("userOrgOid", userOrgOid);  }   
  public void setUserOrgName(String userOrgName){  set("userOrgName", userOrgName); }   
  public void setUserTeamName(String userTeamName){ set("userTeamName", userTeamName); }   
  public void setUpdateDate(Date arg){    set("updateDate", arg);    }   
  public void setGroupId(String arg){     set("groupId", arg);    }   
  public void setInputDate(Date arg){     set("inputDate", arg);    }   
  public void setConfirmYnTmp(String arg){   set("confirmYnTmp", arg);    }   
  public void setConfirmYnName(String arg){   set("confirmYnName", arg);    }   
  public void setConfirmYn(Code arg){     set("confirmYn", arg);    }   
  
  public String getUserName(){      return (String)get("userName"); }   
  public String getUserSabun(){      return (String)get("userSabun"); }   
  public String getUserOrgOid(){      return (String)get("userOrgOid"); }   
  public String getUserOrgName(){      return (String)get("userOrgName"); }   
  public String getUserTeamOid(){      return (String)get("userTeamOid"); }   
  public String getUserTeamName(){     return (String)get("userTeamName"); }   
  public String getGroupId(){       return (String)get("groupId");  }   
  public Date getInputDate(){       return (Date)get("inputDate");  }   
  public Date getUpdateDate(){      return (Date)get("updateDate");  }   
  public String getConfirmYnTmp(){     return get("confirmYnTmp"); }   
  public String getConfirmYnName(){     return get("confirmYnName"); }   
} 
10. 이제 Grid에서 사용할 Entity객체를 생성하였으니 Grid를 통해 서버쪽 데이터를 받아올 수 있도록 Service와 Service와
연결하여 데이터를 주고 받을 수 있는 관련 객체들을 만들어보자.

11. 우선 RpcProxy가 필요하다. RpcProxy의 Rpc는 Remote Procedure Call의 약자이다. Ajax가 서버와 통신할 때
사용하는 프로토콜이라고 볼수 있다. 이 RpcProxy를 생성할 때는 서버에서 데이터를 받아올 때 사용 할 리스트객체인
(LoadResult)와 위의 8에서 정의한 Entity객체를 같이 정의해줘야한다. 소스 상단에 아래와 같이 선언하자
private RpcProxy> proxy; 
12. 다음은 Loader객체와 Store객체를를 선언한다. Loader는 Proxy와 함께 서버와 통신할수 있도 록 도와준다.
Store객체는 Loader로 부터 전달 받은 데이터를 담는 역할을 한다.
private RpcProxy> proxy;   
private BaseListLoader> loader;   
private ListStore store;
13. prepareService메소드를 수정하여 위에서 선언한 클래스를 생성하도록 하자.
public void prepareService(){   
  downGridPanel = new ContentPanel();   
  downGridPanel.setHeading("관리자 현황");   
  downGridPanel.setWidth(800);   
  downGridPanel.setHeight(400);   
  // 서버와 통신해서 가져올 데이터를 위한 객체 생성   
  proxy = new RpcProxy>() {   
  @Override  
  public void load(Object loadConfig, AsyncCallback> callback) {   
    // 나중에 구현하자    
 }   
  };   
  loader = new BaseListLoader>(proxy);   
  loader.setRemoteSort(true);   
  store = new ListStore(loader);   
  store.setMonitorChanges(true);   
}  
14.이제 Grid를 만들어보자. 우선 Grid를 만들 메소드를 하나 정의하자. 이 메소드에 Grid에 관련된 코딩을 해주자.
public void createGrid(){   
  // Column정의    
  List columns = new ArrayList();   
  columns.add(new ColumnConfig("userSabun", "사번", 75));   
  columns.add(new ColumnConfig("userName", "성명", 65));   
  columns.add(new ColumnConfig("userOrgName", "회사명", 150));   
  ColumnConfig userOrgOid = new ColumnConfig("userOrgOid", "회사코드", 120);   
  userOrgOid.setHidden(true);   
  columns.add(userOrgOid);   
  columns.add(new ColumnConfig("userTeamName", "팀명", 80));   
  ColumnConfig inputDate = new ColumnConfig("inputDate", "입력일", 70);   
  inputDate.setDateTimeFormat(DateTimeFormat.getFormat("yyyy.MM.dd"));   
  columns.add(inputDate);   
     
  ColumnConfig updateDate = new ColumnConfig("updateDate", "수정일", 70);   
  updateDate.setDateTimeFormat(DateTimeFormat.getFormat("yyyy.MM.dd"));   
  columns.add(updateDate);   
    
  ColumnConfig confirmYn = new ColumnConfig("confirmYnName", "승인여부", 70);   
  confirmYn.setHidden(true);   
  columns.add(confirmYn);   
  // 정의된 컬럼을 이용해 컬럼모델을 생성한다.    
  ColumnModel cm = new ColumnModel(columns);   
  // Store객체와 컬럼모델을 통해 Grid를 생성한다.   
  Grid grid = new Grid(store, cm);   
  grid.setStateId("-");   
  grid.setStateful(true);   
  // Grid가 보여질때 이벤트 처리   
  grid.addListener(Events.Attach, new Listener>() {   
    public void handleEvent(GridEvent be) {   
 // Grid가 Attach될 때Loader를 통해 서버에서 데이터를 가져오도록 명령한다.    
     loader.load();   
    }   
  });   
  // 보여질 Grid의 로우를 하나를 선택할 것인지 복수개를 선택할 것인지 설정.   
  grid.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);   
  grid.setLoadMask(true);   
  grid.setBorders(true);   
  // 컬럼좌우폭에 대해 가변적으로 늘어나고 줄어들고 할 컬럼을 정해준다. 필수 사항암.   
  grid.setAutoExpandColumn("userTeamName");   
  grid.setStateful(false);   
  grid.setHeight(400); // Grid의 높이를 지정해준다.   
  // ContentPanel에 그리드를 추가한다.   
  downGridPanel.add(grid);   
}  
15. 생성자 GridSmplTabItem()에 위의 메소드가 실행될 수 있도록 수정하고 실행해보도록 하자.
public GridSmplTabItem() {   
  setText("Grid List");   
  LayoutContainer lc = new LayoutContainer();   
  VerticalPanel vp = new VerticalPanel();   
  vp.setSpacing(10);   
    
  prepareService();   
  // Grid관련 정의 메소드   
  createGrid();   
  vp.add(downGridPanel);   
    
  lc.add(vp);   
  lc.setLayout(new FlowLayout(10));   
  add(lc);   
}  
16. 이하 실행된 화면을 보자 아직 서버에서 데이터를 가져오지 않고 있다. 해서 Grid에 컬럼만 보이고 내역은 보이지 않고 있다.

17.  이제 데이터를 가져올수 있도록 코드를 변경해 보자.  일단 서버와 데이터를 주고 받으려면 Service가 있어야 한다.
      Service는 화면에서 보여지는 UI가 데이터를 표현하기 위해 서버와 통신하는 수단이라고 할 수 있다. Service를 하나
      생성 해 보자.  Service생성 시에는 모듈의 Client 패키지를 선택하고 생성해야 한다.
      아래의 그림과 같이 GWT remote service를 클릭 한다.
 

 18.  ServiceName을 지정할 때는 보통 모듈명+Service로 사용하거나 다른 이름으로 하더라도
        XXXService처럼 뒤에 Service를 붙여주자.
        아래 그림은 이미 Service를 GxtSmplService로 생성한 상태라 "~already exists"
        이미 존재한다는 메시지가 나오므로 참고하시고...


19. 생성된 Service를 확인해 보자.  우리는 GxtSmplService라는 이름으로 Remote Service라는 이름으로 Service를
     생성하였다. 이 Service는 com.hansol.gxtsmpl패키지내에서  com.hansol.gxtsmpl.client아래 GxtSmplService.java,
     GxtSmplServiceAsync.java가 생성되었다.
     이 2개의 클래스는 Interface로 이 Interface의 구현은 com.hansol.gxtsmpl.server아래의  GxtSmplServiceImpl.java에
     구현해야 한다. 즉 client에 Service를 생성하고 Service에 메소드를 정의하면 Server쪽 XXXImpl.java클래스에
     구현하도록 해야한다.


20. 이제 Service롤 생성하므로서 2개의 클래스가 생성되어 총 3개의 Service관련 Class가 생성된 것을 확인했다.
     Service가 생성됨과 동시에 변경되는 것이 하나 있다. 바로 web.xml파일이다. 이 파일은 프로젝트 Root밑에 war폴더내
      의 WEB-INF아래에  존재한다.  내용을 확인 해보도록 하자.
  
  
    
    GxtSmplService  
    com.hansol.gxtsmpl.server.GxtSmplServiceImpl  
    
    
    GxtSmplService  
      /com.hansol.gxtsmpl.GxtSmpl/GxtSmplService  
      
  
21.위의 web.xml파일을 잘 살펴보면 servlet과 servlet-mapping이 추가된 것을 볼수 있는데 우리가 생성한 service가
    Servlet기반이라는 것을 알수 있다. 우선 servlet을 보면 우리가 생성한 service이름으로 servlet-name이 지정되어 있고
    sevlet-class가 명시되어 있다. 이것은 서비스가 이름이 무엇이고 클래스는 어떤 것인지 명시한 것이다. 그럼 그 아래
    servlet-mapping을 보자 이 servlet-mapping은 위에서 정의된 서블릿을 어떤모듈에서 사용할 수 있는지 명시하였다.
    GxtSmplService서비스를 com.hansol.gxtsmpl.GxtSmpl모듈에서 사용한다는 뜻이다. 그런데 우리는 GxtSmpl모듈은
    프로그램만 제공할 것이므로 GxtApp에서 GxtSmplService를 사용해야만 하는 상황이다. 그러므로 web.xml파일을 약간 
   수정하도록 하자. 수정은 servlet-mapping을 GxtApp모듈에서 사용할 수 있도록 servlet-mapping을 하나더 추가하도록
   하자.
  
  
    
    GxtSmplService  
    com.hansol.gxtsmpl.server.GxtSmplServiceImpl  
    
    
    GxtSmplService  
      /com.hansol.gxtsmpl.GxtSmpl/GxtSmplService  
      
    
    
    GxtSmplService  
      /gxtapp/GxtSmplService  
      
  
22. 수정 된 web.xml파일을 보면 "/gxtapp/GxtSmplService"라는 부분을 주목하자. 이렇게 쓴 이유는 GxtSmpl모듈에
     생성한 Service를 war밑에 있는 gxtapp모듈에서 사용하겠다는 의미로 해석하면 된다. 서블릿을 사용 해본 사람 에게는
     익숙한 Syntax라고 생각된다. 다음 강좌에서는 ClientUi에서 Server쪽 클래스에게 요청을 보내고 서버쪽 에서 요청에
     대한 응답을 어떻게 전달하는지 알아보자

2011/01/11 - [Gxt , Ext Gwt강좌] - Ext Gwt[Gxt] 강좌08-Client클래스와 서버클래스간 데이터를 주고 받자.
Posted by 1 베니94

댓글을 달아 주세요

  1. 감사합니다

    4번부터 막혔습니다.
    새로 생성된 곳의 소스인지 app.java에 새롭게 추가해 들어가는건지..
    예를들어 5번의 경우는 이미 작성된 부분이라 추가되는건 알겠고, 6번은 어디에 추가되는건지..
    7번은 4번에서 추가되는건지..
    즉 지금 작성중인 소스가 GxtApp.java인지 아니면 123번에서 새로 만든 파일인지..
    초보라 많이 헷갈리네요 여유되신다면 알려주시면 감사하겠습니다 ㅜㅜ

    2011.02.24 14:36 [ ADDR : EDIT/ DEL : REPLY ]
    • 안녕하세요
      블로그 오픈하구 질문다운 질문을 첨해주시네요 ㅋㅋ

      답변드릴께요.
      4번
      - package com.hansol.gxtsmpl.client.programs;
      - GridSmplTabItem.java입니다.
      이놈은 위의 패키지 아래에 생성된 놈입니다.
      내용은 별거 없죠. 걍 대강의 ui만 갖도록 만들었는데요.
      이 놈을 5번에서 실행시켜 5번 GetApp.java를 통해 보여주려고 하는 의도입니다.

      5번. GxtApp.java
      - 여기서 설명하는 것은 위의 4번에서 생성된 샘플클래스를 Tabitem을 통해 삽입하려고 하는거죠. 그래서 setTabitem()메소드는 GxtApp.java에 들어가면되겠죠.
      이걸 실행해 보면 GxtApp가 실행되고 탭에 4번이 보여진다는 겁니다.
      6번. GridSmplTabItem.java
      - 여기서는 4번을 수정해서 그리드를 추가한다는겁니다.
      이 후 설명은 모두 그리드에 대한 설명이니깐. GridSmplTabItem.java안의 코드라고 할 수 있습니다.

      2011.02.25 13:37 신고 [ ADDR : EDIT/ DEL ]
  2. 솔베이지군

    안녕하세요.
    현재 SDK2.4.0에서 실습해보고 있습니다.
    17번 이후에 remote service 생성시에 xxxAsync객체는 생성이 되지 않는데 해결방안 부탁드립니다..
    그냥 일단 따라해보는 중인데 복잡하네요;

    2011.11.17 17:03 [ ADDR : EDIT/ DEL : REPLY ]
    • 안나오면 그냥 만드셔두 되요 뭐 이클립스가 왜 안만드는지는 저두 해봐야겠지만 기본적으로 네이밍만 맞춰서 그냥 만들어버리세요 그걸루 공부하시는데 너무 오래 시간을 투자하진 말았으면 합니다.

      2012.02.19 22:01 신고 [ ADDR : EDIT/ DEL ]
  3. 봄날의곰

    안녕하세요. 열심히 따라하고있는데 11번에서 딱 막혀서 ㅠㅠㅠ
    private RpcProxy<baselistloadresult<loginuserinfo>> proxy;
    </baselistloadresult<loginuserinfo> 소스 상단에 선언하자, 라고 했는데..
    에러가 쫙쫙 생겨서..
    private RpcProxy(BaseListLoadResult<LoginUserInfo>> proxy;
    </BaseListLoadResult<LoginUserInfo> 로 나름 머리를 굴려보았지만..ㅋㅋ역시 에러..ㅠㅠ;;

    참..근데 이거.. GridSmplTabItem.java에 추가하는것 맞나요 /; LoginUserInfo.java 작성하다가 이어지는부분이라
    어딘지 헷갈리네요 ㅠㅠ

    2012.02.16 14:46 [ ADDR : EDIT/ DEL : REPLY ]
    • 네 GridSmplTabItem에 작성하시는게 맞습니다. 에러내용이 뭔제 좀 알려주시면 해결방법이 있을겁니다.

      2012.02.19 22:09 신고 [ ADDR : EDIT/ DEL ]
  4. 깜재

    죄송하지만 전체 패키지 구성이랑 전체 완성 소스 보여주실 수 있으세요?

    2014.02.12 09:49 [ ADDR : EDIT/ DEL : REPLY ]