[컴][웹] GWT 사용하기 - UiBinder - 1




HTML 을 UiBinder 로 옮기기

html 로 작성한 UI 가 있다고 하자. 이녀석을 UiBinder 로 많은 수정을 가하지 않고 사용할 수 있다.

<ui:uiBinder>


html 을 일단 <ui:uiBinder></ui:uiBinder> 로 에워싸자.
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
              xmlns:g="urn:import:com.google.gwt.user.client.ui">
<!--the rest of the designers code -->
</ui:UiBinder>

참고로,
&lt; 같은 html 의 entity 이용 하려면 아래와 같이 DOCTYPE 을 xml 에 적어줘야 한다.
<!DOCTYPE ui:UiBinder SYSTEM
    "http://dl.google.com/gwt/DTD/xhtml.ent">

위에서 보듯이 보통 xml 의 namespace 는 아래 2가지를 사용한다.
  • xmlns:ui="urn:ui:com.google.gwt.uibinder"
  • xmlns:g="urn:import:com.google.gwt.user.client.ui"

<g:HTMLPanel>

가지고 있는 html 의 contents 들은 <g:HTMLPanel></g:HTMLPanel>로 묶자.

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
   xmlns:g="urn:import:com.google.gwt.user.client.ui">
  <g:HTMLPanel>
    <!--the rest of the designers code -->
  </g:HTMLPanel>
</ui:UiBinder>
HtmlPanel 은 그 child element 로 Widget 도 가능하고 html 도 가능하다.


Widget 으로 대체

기본적으로 가지고 온 html 의 element 들을 그대로 사용하면 된다. 근데 form 같은 경우는 div 로 수정하고, TextBox 나 Button 처럼 Widget 으로 대체할 수 있는 것들은 Widget 으로 대체한다.

html 의 element 를 Widget으로 대체하는 경우에는 class 라는 이름의 attribute 가 존재하지 없다. 대신에 styleName 이라는 attribute 가 존재한다. 이 Widget 등의 attribute 는 JavaBean 의 semantics 를 따른다. 즉 attribute styleName 은 setStyleName() 을 호출하게 되는 것이다.




Vertical Stack FlowPanel 은 차례대로 사용
VerticalSplitPanel 과 HorizontalSplitPanel 은 두개의 element 만가능.
<g:StackPanel>
  <g:HorizontalPanel>
    <g:HTML>One</g:HTML>
    <g:HTML>Two</g:HTML>
    <g:HTML>Three</g:HTML>
  </g:HorizontalPanel>
  <g:VerticalPanel>
    <g:HTML>One</g:HTML>
    <g:HTML>Two</g:HTML>
    <g:HTML>Three</g:HTML>
  </g:VerticalPanel>
</g:StackPanel>

DockLayoutPanel 을 구현한 녀석들은 아래처럼 사용가능하다.

<g:SplitLayoutPanel>
  <g:north size="100">
    <g:HTML>One</g:HTML>
  </g:north>
  <g:center>
    <g:HTML>Two</g:HTML>
  </g:center>
  <g:east size="100">
    <g:HTML>Three</g:HTML>
  </g:east>
</g:SplitLayoutPanel>



xml 를 javacode 에 연결하기

일단 xml template 과 Java class file 은 같은 package 에 놓아야 한다. 그리고 같은 이름을 사용하자.

@UiTemplate

code-generator 는 interface 정의에 적혀있는 두번째 parameter 를 보고 해당하는 .java file 과 Java class 랑 같은 이름의 template file 을 찾아서 widget 을 만든다.

그런데 만약 다른 이름의 xml 을 사용하게 하고 싶으면 @UiTemplate 을 사용하면 된다.

  • @UiTemplate("OtherTemplate.ui.xml")

이렇게 file 이름을 바꿀수는 있지만 directory 는 바꿀 수 없다. java class 와 같은 package 안에 넣어놔야 한다. 아래처럼 child directory 로 접근하는 것은 가능하다고 한다. 하지만 parent 로의 접근과 절대경로로 접근할 수는 없다고 한다.

  • @UiTemplate("folder/OtherTemplate.ui.xml")


Template 을 instanciate 하고 Bind 하기

public class LoginDialogBox extends PopupPanel {
 interface MyBinder extends UiBinder<Widget, LoginDialogBox>{} 
 private static MyBinder uiBinder = GWT.create(MyBinder.class); 

 public LoginDialogBox() {
  setStyleName("");
  add(uiBinder.createAndBindUi(this)); 
 }
}

  1. UiBinder intrface 를 상속받아서 interface 하나만든다. 이 interface는 이 class 안에서만 쓰이므로 inner interface 로 충분하다. 여기 parameter 가 두개 들어가는데
    1. 첫번째에는 xml template 에서 사용한 root의 type 을 사용하고,
    2. 두번째는 그 xml을 사용할 class 를 적는다.
  2. Gwt.create(interface_name.class) 를 하면 compiler 가 xml 을 보고 만들어준다.
  3. createAndBindUi() 로 초기화한다. 이 때 root element/widget 을 얻게 된다.



UiBinder element 를 java variable 에 연결

이제 이 만든 uiBinder 의 element 를 java의 변수(variable) 에 연결시켜보자.
<div>, <span> 등에 ui:field="helloMessage" 을 사용해서
으로 binding 할수 있다.
코드에는 @UiField SpanElement helloMessage

@UiField(provided = true) TextBox txtPassword;
...
txtPassword = new PasswordTextBox()

위와같이 나중에 instantiate 을 할 수도 있다.

<li>
<g:TextBox ui:field="txtEmail"/>
<div ui:field="eEmailError">
  <span>X</span>
  <span ui:field="eEmailErrorText">Email error</span>
</div>
</li>



@UiField Element eEmailError;
@UiField(provided = true) TextBox txtEmail;

public LoginDialogBox() {
 setStyleName("");
 txtEmail = new PasswordTextBox();
 add(binder.createAndBindUi(this));
}

@UiField 는 UiBinder 가 widget 또는 element 를 instantiate 해주고, 그 결과를 variable 에 set 해준다는 의미이다. UiBinder 가 instantiate 하지 않고, 자신이 직접하려고 한다면
  • provided = true
를 사용하면 되는 것이다. 다만 직접 Widget 등을 만들때는 binder.createAndBindUi() 이전에 해줘야 한다.


Widget 의 consturctor

UiBinder 에게 create 를 맡기지 않는 경우에 우리는 3가지 방법으로 그 widget 들을 create 할 수 있다.
  1. @UiConstructor
  2. @UiFactory
  3. @UiField(provided=true).
code를 만들때(GWT.create())  code-generator 는 @UiField, @UiFactory , @UiConstructor 같은 annotation 을 위해서 class 들을 스캔한다. 그래서 createAndBindUi() 에서 알맞은 method 를 사용할 수 있게 된다.


@UiConstructor

아래처럼 @UiContructor 를 이용하는 경우에 자신만의 Widget 을 만들어서 사용할 수 있겠다. 아래처럼 만들어서 사용할 수 있다. 아래예제를 보면 알지만, parameter 는 xml 의 attribute 로 적어주면 된다.

UiConstructor 를 따로 지정해 주지 않는다면, 기본적으로 parameter 가 없는 constructor 를 찾게 되어 있다. 그리고 parameter 가 없는 constructor 가 없으면 error 가 난다.

@UiConstructor
public RadioButton(String name) {
...
}

<g:RadioButton name="bestActor">Bruce Campbell</g:RadioButton>



@UiFactory

UiFactory 를 아래처럼 작성하면, UiBinder 가 xml template 을 instantiate 할 때 모든 Button 은 아래의 함수를 이용하게 된다. return type 을 보고 UiBinder 가 사용하는 것이라고 한다. 이녀석은 모든 Widget 을 같은 모양으로 만드는 등의 작업에 어울린다.

@UiFactory
Button createLoginButton () {
 Button button = new Button();
 button.setTitle("Submit the login form");
 return button;
}



내가 만든 Composite 을 UiBinder 에서 사용하는 방법







Panel

Panel 에서 child element 를 설정하는 방법은 두가지다.
  1. child element 순서대로 표시하는 방법 
  2. child 가 표시되는 side 를 정해주는 방법.

아래 Panel class javadoc 으로 가면 Direct Known Classes 에 또 다른 Panel 을 찾을 수 있다. 여기서 계속 따라가면, panel 들을 대략적으로 모두 살펴 볼 수 있다.

Panel


 ComplexPanel



Reference

  1. GWT in Action 2nd Edition, Chapter 6

댓글 없음:

댓글 쓰기