이번엔 DataGrid를 이용해봅시다!-_-;

예약 리스트를 받아와야하기 때문에 더 쉽습니다-_-; 이 DataGrid라는 놈이 너무 강력해서-_-; 자바Bean이랑 매우 잘 맞아요!

자바측에서 List형태로 리턴하게 되면 DataGrid의 dataProvider가 알아서 다 해줍니다.
우선 자바측의 예약 취소하기 메소드를 보도록 합시다.





[code]
public int BookCancel(int[] seatnum) {
  Connection con = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;

  try {
   String jdbcDriver = "jdbc:apache:commons:dbcp:/pool";
         con = DriverManager.getConnection(jdbcDriver);
   // 현재 요청된 변호레코드의 ID와 좌석번호, ID와 맞는 비번을 추출
   for (int i=0; i<seatnum.length; i++) {
    pstmt = con.prepareStatement("DELETE FROM bs_Book WHERE seatnum = ?");
    pstmt.setInt(1, seatnum[i]);
    pstmt.executeUpdate();
   
    pstmt = con.prepareStatement(
                "UPDATE bs_Seat SET isbooked='X' WHERE seatnum = ?");
    pstmt.setInt(1, seatnum[i]);
    pstmt.executeUpdate();
   }
   return 1;
  } catch (SQLException e) {
   e.printStackTrace();
   return 0;
  } finally {
   if (rs != null) try { rs.close(); } catch(SQLException ex) {}
   if (pstmt != null) try { pstmt.close(); } catch(SQLException ex) {}
   if (con != null) try { con.close(); } catch(SQLException ex) {}
  }
 }
[/code]
아 이거 배열로 처리하려고 했는데 DataGrid에서 다중선택을 할 줄 모르겠어요-_- 아는 사람 좀 가르쳐주세요!

어쨌든-_-; 한개만 넘겼다고 치고 해봅시다. 해당 좌석번호를 찾아서 bs_Book테이블에서 삭제를 하고 bs_Seat테이블에는 예약여부(isbooked)에 X로 바꿔주면 끝납니다.

이제 플렉스로 가봅시다.

[code]
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
  width="100%" height="100%" title="예약취소하기">
 <mx:Script>
  <![CDATA[
   import mx.rpc.events.ResultEvent;
   import mx.rpc.events.FaultEvent;
   import mx.rpc.remoting.RemoteObject;
   import mx.controls.Alert;
   
   private function bookCancel():void {
    var cancellist:Array = new Array();
    var srv:RemoteObject = new RemoteObject();
    var i:int;
    srv.destination = "booksystem";
   
    if (dg.selectedItem == null){
     Alert.show("좌석을 선택하세요!");
     return;
    }
    cancellist.push(int(dg.selectedItem.seatnum));
   
    srv.BookCancel(cancellist);
   
    srv.addEventListener("result", resultHandler);
    srv.addEventListener("fault", faultHandler);
   }
   
   // Result Handler
   private function resultHandler(event:ResultEvent):void {
    var result:int = int(event.result);
   
    switch (result) {
     case 0 :
      Alert.show("DB오류입니다.");
      break;
     case 1 :
      Alert.show("예약취소가 완료되었습니다.");
      parentApplication.viewstack.selectedChild = parentApplication.ViewHome;
      break;
    }
   }
   private function faultHandler(event:FaultEvent):void {
    mx.controls.Alert.show("실패 메세지: " + event.fault.message);
   }
   
   public function UpdateBookcancel():void {
    var srv:RemoteObject = new RemoteObject();
    srv.destination = "booksystem";
    srv.addEventListener("result", bookresultHandler);
    srv.addEventListener("fault", bookfaultHandler);
    srv.getBook(parentApplication.loginid);
   }
   private function bookresultHandler(event:ResultEvent):void {
    dg.dataProvider = event.result;
    parentApplication.viewstack.selectedChild=parentApplication.ViewBookCancel;
   }
   private function bookfaultHandler(event:FaultEvent):void {
    mx.controls.Alert.show("실패 메세지: " + event.fault.message);
   }
  ]]>
 </mx:Script>
 
 <mx:DataGrid id="dg" width="100%" height="100%" />
 <mx:ControlBar horizontalAlign="center">
  <mx:Button label="예약취소하기" click="bookCancel()"/>
 </mx:ControlBar>
</mx:Panel>

[/code]
우선 UpdateBookcancel을 실행하게 되면 getBook함수를 호출하는데 이 함수는 예약리스트를 List객체에 받아오는 역할을 합니다.

dg.dataProvider = event.result; (dg는 DataGrid의 id)

이 결과를 그냥 dg.dataProvider에 처 넣으면 됩니다-_-; 그러면 알아서 테이블로 표시가 됩니다.

그리고 해당줄을 선택하고, 예약취소버튼을 누르면 bookCancel함수를 호출하는데 여기서 자바클래스에 있는 BookCancel함수를 호출하게 됩니다.

선택된 좌석은 dg.selectedItem.seatnum 이렇게 하면 알 수 있습니다.

예매시스템 소스파일입니다.
http://mudchobo.tomeii.com/tt/108

 
Posted by 머드초보
,
 

예약하기부분... 머리가 딸려서 좀 고생했습니다-_-;

아....mxml에서는 반복문 못 쓰는 건가요? 버튼을 90개 만들고 싶은데 다 적을 수도 없고 해서-_-;
as에서 구현을 했습니다 ^^

우선 예약하기부분의 자바클래스를 보도록 합시다.
아 우선 DB구조를 보도록 합시다.


사용자 삽입 이미지

bs는 Booksystem의 약자고요-_-;
bs_Book은 예약리스트입니다. 3개의 필드로 되어있는데요. booknum, id, seatnum으로 되어있구요.
bs_Seat은 seatnum, grade, isbooked로 되어있어요.

예약을 하게 되면 bs_Seat에서 isbooked를 O로 바꾸고 bs_Book에 그 해당 번호와 예약한 id를 저장합니다. booknum은 오토인크리스먼트입니다.

간단한건데 왜이렇게 복잡하게 설명해놨지-_-; 뭐 어쨌든--; 간단합니다-_-;

[code]
public int BookSeat(String id, int[] seatnum) {
  Connection con = null;
  PreparedStatement pstmt = null;

  try {
   String jdbcDriver = "jdbc:apache:commons:dbcp:/pool";
         con = DriverManager.getConnection(jdbcDriver);
   // 요청한 좌석이 예약된 좌석인지 확인을 위해 IsBooked를 추출
   
   for (int i=0; i<seatnum.length; i++) {
    pstmt = con.prepareStatement(
       "UPDATE bs_Seat SET isbooked='O' WHERE bs_Seat.seatnum = ?");
    pstmt.setInt(1, seatnum[i]);
    pstmt.executeUpdate();
    pstmt = con.prepareStatement(
       "INSERT INTO bs_Book (id, seatnum) " + "VALUES (?, ?)");
    pstmt.setString(1, id);
    pstmt.setInt(2, seatnum[i]);
    pstmt.executeUpdate();
   }
   return 1;
  } catch (SQLException e) {
   e.printStackTrace();
   return 0;
  } finally {
   if (pstmt != null) try { pstmt.close(); } catch(SQLException ex) {}
   if (con != null) try { con.close(); } catch(SQLException ex) {}
  }
 }
[/code]
int형배열로 받습니다. 다중선택으로 올 수 있기 때문에-_-; 받아서 for문으로 개수만큼 실행합니다. 우선 bs_Seat테이블에서 예약여부필드에서 예약이 됐다는 의미에서 O로 바꾼 뒤에 bs_Book테이블 예약리스트테이블에 해당 id와 좌석번호(seatnum)을 집어 넣습니다. 예약요청하는 수만큼 반복합니다.

플렉스로 가봅시다-_-;

[code]
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
  width="100%" height="100%"
 creationComplete="CreateButton()" title="좌석 예약하기">
 <mx:Script>
  <![CDATA[
   import mx.containers.ControlBar;
   import mx.controls.Button;
   import mx.rpc.events.ResultEvent;
   import mx.rpc.events.FaultEvent;
   import mx.collections.ArrayCollection;
   import mx.controls.Alert;
   import mx.rpc.remoting.RemoteObject;
   
   public var seatlistAC:ArrayCollection;
   public var bookseatAC:ArrayCollection = new ArrayCollection();
   public var count:int = 0;
   
   // 처음 Panel이 생성될 때 실행되는 버튼생성함수
   public function CreateButton():void {
    var i:int;
    var j:int;
    var space:int;
   
    for (i = 0; i < 9; i++) {
     for (j = 0; j < 10; j++) {
      var btn:Button = new Button();
     
      if (i < 3) {
       btn.label = "R" + (i*10+j+1);
       space = 0;
      } else if (i < 6) {
       btn.label = "S" + (i*10+j+1);
       space = 30;
      } else {
       btn.label = "A" + (i*10+j+1);
       space = 60;
      }
      btn.id = String(i*10+j+1);
      btn.name = "btn" + String(i*10+j+1);
      btn.x = j * 50;
      btn.y = i * 30 + space + 10;
      btn.width = 35;
      btn.height = 20;
      btn.setStyle("fillColors", ["#000000","#000000"]);
      btn.addEventListener(MouseEvent.CLICK, btnclickEvent);
      addChild(btn);
     }
    }
   }
   
   // 버튼클릭시 이벤트
   private function btnclickEvent(e:Event):void {
    var btn:Button = Button(e.currentTarget);
    var i:int;
    for (i = 0; i < bookseatAC.length; i++){
     if (bookseatAC.getItemAt(i) == btn.id){
      bookseatAC.removeItemAt(i);
      btn.setStyle("fillColors", ["#000000","#000000"]);
      count--;
      return;
     }
    }
   
    if (count == 4) {
     Alert.show("더이상 선택할 수 없습니다.");
     return;
    }
    count++;
   
    bookseatAC.addItem(btn.id);
    btn.setStyle("fillColors", ["#ff0000","#ff0000"]);
   }
   
   // 예약하기버튼 클릭시 발생하는 이벤트
   private function bookseatEvent():void {
    if (count == 0) {
     Alert.show("좌석을 선택하세요!");
     return;
    }
    var bookseatlist:Array = [];
    var srv:RemoteObject = new RemoteObject();
    var i:int;
    srv.destination = "booksystem";
   
    for (i=0; i<bookseatAC.length; i++) {
     bookseatlist.push(int(bookseatAC.getItemAt(i)));
    }
    srv.BookSeat(parentApplication.loginid, bookseatlist);
   
    srv.addEventListener("result", resultHandler);
    srv.addEventListener("fault", faultHandler);
   }
   
   // 예약하기 버튼 클릭시 실행하는 RemoteObject에 대한 이벤트핸들러
   private function resultHandler(event:ResultEvent):void {
    var result:int = int(event.result);
   
    switch (result) {
     case 0 :
      Alert.show("DB오류입니다.");
      break;
     case 1 :
      Alert.show("예약에 성공했습니다.");
      bookseatAC.removeAll();
      parentApplication.viewstack.selectedChild = parentApplication.ViewHome;
      count = 0;
      break;
    }
   }  
   private function faultHandler(event:FaultEvent):void {
    mx.controls.Alert.show("실패 메세지: " + event.fault.message);
   }
   
   // 예약여부확인 후 버튼업데이트
   public function UpdateBookseat():void {
    var srv:RemoteObject = new RemoteObject();
    srv.destination = "booksystem";
    srv.addEventListener("result", seatresultHandler);
    srv.addEventListener("fault", seatfaultHandler);
    srv.getSeat();
   }
   private function seatresultHandler(event:ResultEvent):void {
    var i:int;
    var btn:Button;
   
    seatlistAC = ArrayCollection(event.result);
       
    for (i = 0; i < seatlistAC.length; i++){
     btn = Button(this.getChildByName("btn" + String(i+1)));
     btn.setStyle("fillColors", ["#000000","#000000"]);
     if (seatlistAC[i].isbooked == "O") {
      btn.enabled = false;
     } else {
      btn.enabled = true;
     }
    }
    parentApplication.viewstack.selectedChild=parentApplication.ViewBookSeat;
   }
   private function seatfaultHandler(event:FaultEvent):void {
    mx.controls.Alert.show("실패 메세지: " + event.fault.message);
   }
  ]]>
 </mx:Script>
 
 <mx:ControlBar id="ctrbar" horizontalAlign="center">
  <mx:Button id="bookbtn" label="예약하기" click="bookseatEvent();"/>
 </mx:ControlBar>
</mx:Panel>
[/code]
아 길군요-_-; 우선 컴포넌트가 생성이 되면 CreateButton함수를 호출하게 되어있습니다. 이것이 패널에다가 90개의 버튼을 만들어주는 함수입니다. 각각 구별할 수 있게 id와 name을 주고 각 버튼마다 이벤트를 등록했습니다. 그리고 addChild라는 함수는 Panel에 자식으로 붙이겠다는 얘깁니다.

버튼이 생성되면 이미 예약되어있는 좌석은 비활성화 해야합니다. getSeat을 호출하면 좌석정보를 List객체에 담아오는데 이것을 ArrayCollection으로 받습니다.

seatlistAC = ArrayCollection(event.result); 이런식으로 받아오면 됩니다.

해당 되는 버튼은 enable = false로 해서 비활성화시킵니다.

버튼을 생성하고 그 해당 버튼을 클릭하게 되면 이벤트로 등록한 함수를 호출하게 되는데 btnclickEvent 이 함수를 호출하게 됩니다. 클릭할 때마다 ArrayCollection에다가 집어넣습니다-_-; 아..쓰면서 느낀건데 ArrayCollection할 필요 없을 꺼 같은데-_-; 그냥 Array로 해도 될 듯싶습니다. 아 삽질했습니다.

어쨌든 집어 넣어서 이미 클릭이 된거면 삭제를 시키고, 클릭이 안된거면 추가를 하게 되어있습니다.

그렇게 해서 예약하기 버튼을 클릭하면 bookseatEvent함수를 호출합니다. 이 함수를 호출하게 되면 자바클래스에 있는 BookSeat함수를 호출하게 됩니다-_-; 간단해요!

예매시스템 소스파일입니다.
http://mudchobo.tomeii.com/tt/108
 
Posted by 머드초보
,
 

회원가입은 아이디, 비밀번호, 이름 등의 정보를 받아서
RemoteObject를 통해 Join메소드를 호출하기만 하면 끝입니다 ^^

그냥 값만 넘겨주면 자바클래스에서 처리를 합니다.













[code]
public int Join(String id, String pwd, String name, int age, String sex, String tel)
{
  Connection con = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;
 
  try {
   String jdbcDriver = "jdbc:apache:commons:dbcp:/pool";
         con = DriverManager.getConnection(jdbcDriver);

   // 입력한 ID와 같은 ID를 추출(이미있는 id인지 확인위함)
   pstmt = con.prepareStatement("SELECT id FROM bs_Member WHERE id = ?");
   pstmt.setString(1, id);
   rs = pstmt.executeQuery();
   if (rs.next()) {
    return 2;
   } else {
    // 신규등록을 위해 INSERT문을 이용해 DB에 삽입
    pstmt = con.prepareStatement(
                "INSERT INTO bs_Member (id, pwd, name, age, sex, tel) " +
                "VALUES (?, ?, ?, ?, ?, ?)");
    pstmt.setString(1, id);
    pstmt.setString(2, pwd);
    pstmt.setString(3, name);
    pstmt.setInt(4, age);
    pstmt.setString(5, sex);
    pstmt.setString(6, tel);
    pstmt.executeUpdate();
    return 1;
   }
  } catch (SQLException e) {
   e.printStackTrace();
   return 0;
  } finally {
   if (rs != null) try { rs.close(); } catch(SQLException ex) {}
   if (pstmt != null) try { pstmt.close(); } catch(SQLException ex) {}
   if (con != null) try { con.close(); } catch(SQLException ex) {}
  }
 }
[/code]
이미 있는 ID인지 확인을 위해 검사해서 ID가 있으면 2를 리턴, 없으면 DB에 삽입 후에 1을 리턴합니다.

FLEX로 가봅시다.

[code]
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%"
height="100%" xmlns:comp="*" backgroundColor="#c0c0c0" backgroundAlpha="0.7"
creationComplete="initWindow()">
 
 <mx:Script>
  <![CDATA[
   import mx.rpc.events.ResultEvent;
   import mx.rpc.events.FaultEvent;
   import mx.rpc.remoting.RemoteObject;
   import mx.controls.Alert;
   
   private function initWindow():void {
    joinwindow.x = this.width / 2 - 150;
    joinwindow.y = this.height / 2 - 200;
   }
   
   private function RequestJoin():void {
    var srv:RemoteObject = new RemoteObject();
    srv.destination = "booksystem";
    /*
     아이디 길이등의ㅣ 검사문-_-; 귀찮아서-_-;
    */
   
    if (sextext.text == "남" || sextext.text == "여"){
     srv.Join(
       idtext.text, pwtext.text,
       nametext.text, agetext.text, sextext.text, teltext.text);
    } else {
     Alert.show("남 또는 여 라고 입력하세요!");
     return;
    }
   
    srv.addEventListener("result", resultHandler);
    srv.addEventListener("fault", faultHandler);
   }
   
   private function resultHandler(event:ResultEvent):void {
    var result:int = int(event.result);
   
    switch (result) {
     case 0 :
      Alert.show("DB오류입니다.");
      break;
     case 1 :
      Alert.show("가입에 성공했습니다.");
      idtext.text = "";
      pwtext.text = "";
      nametext.text = "";
      agetext.text = "";
      sextext.text = "";
      teltext.text = "";
      visible = false;
      break;
     case 2 :
      Alert.show("ID가 이미있습니다.");
      break;
    }
   }
   
   private function faultHandler(event:FaultEvent):void {
    Alert.show("실패 메세지: " + event.fault.message);
   }
  ]]>
 </mx:Script>
 <mx:TitleWindow id="joinwindow" width="300" height="300"
layout="absolute" title="회원가입하기">
  <mx:Label x="72.5" y="35" text="ID "/>
  <mx:Label x="72.5" y="61" text="PW"/>
  <mx:Label x="70.5" y="87" text="이름"/>
  <mx:Label x="70.5" y="113" text="나이"/>
  <mx:Label x="70.5" y="139" text="성별"/>
  <mx:Label x="70.5" y="167" text="전화"/>
  <mx:TextInput id="idtext" x="103.5" y="33" width="112"/>
  <mx:TextInput id="pwtext" x="103.5" y="59" width="112"
displayAsPassword="true"/>
  <mx:TextInput id="nametext" x="103.5" y="85" width="112"/>
  <mx:TextInput id="agetext" x="103.5" y="111" width="112" restrict="0-9"/>
  <mx:TextInput id="sextext" x="103.5" y="137" width="112"/>
  <mx:TextInput id="teltext" x="103.5" y="165" width="112"/>
  <mx:Button x="79.5" y="193" label="가입신청" click="RequestJoin();"/>
  <mx:Button x="157.5" y="193" label="취소" click="visible=false"/>
 </mx:TitleWindow>
</mx:Canvas>

[/code]
가입신청버튼을 클릭하면 RequestJoin()을 호출합니다. 이것은 RemoteObject를 통해 Join메소드를 호출합니다. 그리고 리턴값에 따라 1이면 성공, 2이면 이미 id가 있다고 알려줍니다. 텍스트박스를 다 초기화하고 visible을 false로 바꿔 창을 다시 로그인창으로 바꿉니다.

아 그리고 agetext를 보면 restrict="0-9"라고 써 놓으면 저 필드에는 숫자밖에 입력이 안됩니다. 좋은 정보입니다 핫핫-_-;

예매시스템 소스파일입니다.
http://mudchobo.tomeii.com/tt/108
 
Posted by 머드초보
,
 

아....친구한테 RemoteObject를 했다고하니까 욕먹었습니다-_-; 실무에서 쓰이지 않는다고 하더군요. 이 LCDS라는게 좀 비싸서 ^^

그리고 객체지향적인 AS3.0의 특성을 살리지 않고, 멋대로지향적으로 설계를 했습니다-_-; 다시 객체지향적으로 변경해서 해보도록 하겠습니다-_-;

뭐 그래도 삽질했으니까 올립니다. 보고 플렉스를 공부하시는 분들 도움이 되셨으면 좋겠어요(아마 도움이 안될껍니다-_-;)
이따구로도 플렉스를 할 수 있다는 것을 보여준 참 좋은 예인거 같습니다-_-;

프로그램은 간단합니다.
로그인, 회원가입으로 아이디를 생성하고, 예약하고 싶은 좌석을 선택해서 예약하면 예약되고-_-;
예약한 좌석 리스트를 보고 예약취소하고 싶으면 선택해서 취소해버리면 됩니다-_-;

덤으로 차팅도 두개 넣었구요. 로그인 로그아웃 등의 flexSession을 이용해서 제작했습니다.

웹에다가 올리려고 했는데 서버가 다운됐어요-_-; 친구한테 욕먹게 생겼어요-_-;
친구한테 물어보고 되면 올려볼께요-_-; 뭐 보고싶은 사람도 없겠지만-_-;

아 올렸어요-_-; 예제사이트입니다-_-;
http://mudchobo.tomeii.com/flex/Booksystem/Booksystem.swf

소스는 플렉스꺼랑 자바클래스꺼랑 두개가 있습니다!
이게 플렉스꺼 mxml파일들입니다.




이게 자바클래스입니다 ^^




DB구조입니다.



나중에 삽질한 거 설명하면서 차근차근 올려보도록 하겠습니다-_-;
사용자 삽입 이미지
사용자 삽입 이미지

사용자 삽입 이미지
사용자 삽입 이미지

 
Posted by 머드초보
,