반응형

요약

이번 튜토리얼에서는 Jigloo를 사용하여 기본적인 GUI를 생성하는 방법을 살펴보았다. 몇 가지 컨테이너와 컨트롤들을 사용해 봤다. 이벤트를 사용하여 각각의 컨트롤을 비즈니스 로직을 구현해 놓은 모델과 엮는 방법도 살펴보았다. 이제부터 할 수 있는 것이 많아졌을 것이다. Jigloo의 좀 더 어려운 기능들도 사용할 준비가 되었다. Jigloo를 사용하여 다음과 같은 일들을 할 수 있다.

  • 폼에서 재사용 가능하고 분리된 컴포넌트들을 추출
  • 이런 컴포넌트들을 다른 애플리케이션에서 사용할 수 있으며 심지어 비주얼 상속을 사용하여 확장(extend)할 수도 있다.
  • 스윙 컴포넌트 추가
  • 전체 애플리케이션을 스윙으로 변환

Jigloo 구조상 좀 더 다양한 특징을 제공하기 때문에 폼을 좀 더 복잡하게 만들 수 있다. 날짜 선택 컨트롤과 이런 데이터 요소를 위한 콤보 컨트롤을 사용할 수 있다.

애플리케이션에서 Jigloo 사용에 대해서는 참고자료에 있는 추가 문서들과 개념을 참조하기 바란다.

기사의 원문보기

<출처 :https://www.ibm.com/developerworks/kr/library/tutorial/os-eclipse-jigloo/section5.html>

다운로드 하십시오

설명 이름 크기 다운로드 방식
Part 4 source code os-eclipse-jigloo.workflow.zip 18KB HTTP
다운로드 방식에 대한 정보

<출처 :https://www.ibm.com/developerworks/kr/library/tutorial/os-eclipse-jigloo/section6.html>

참고자료

교육

제품 및 기술 얻기

토론
  • 이클립스 플랫폼 뉴스그룹에서 이클립스 관련 궁금증을 해결할 수 있을 것이다(링크를 클릭하면 기본 유즈넷 뉴스 리더 애플리케이션을 실행하고 eclipse.platform을 자동으로 열 것이다).

  • The 이클립스 뉴스그룹에는 이클립스를 확장하고 사용하는 것에 관심 있는 사람들을 위한 많은 참고자료가 있다.

  • 이클립스 플랫폼 SWT 메일링 리스트를 구독하여 최신 이클립스 소식을 얻을 수 있다.

  • developerWorks 블로그와 developerWorks 커뮤니티에 참여할 수 있다.

    <출처 :https://www.ibm.com/developerworks/kr/library/tutorial/os-eclipse-jigloo/section7.html>
반응형

애플리케이션에서 사용할 데이터 모델 만들기

모델-뷰-컨트롤(MVC) 아키텍처에 익숙하다면 지금까지 만든 것이 애플리케이션의 뷰에 해당한다는 것을 알아차렸을 것이다. 이 부분이야 말로 Jigloo가 진가를 발휘하는 부분이다. 이제는 모델을 만들어야 한다. 다시 말하면 시스템에서 사용할 데이터를 가져오고 사용할 자바 코드를 만들어야 함을 의미한다. Jigloo는 여기서도 역시 빛을 발한다. Jigloo는 단순한 이클립스 플러그인으로 Jigloo를 사용할 때도 직접 이클립스의 강력한 기능들을 힘들이지 않고 바로 사용할 수 있다. 이클립스는 자바 코드 작성과 데이터를 다루는 데 매우 훌륭한 도구이기 때문에 Jigloo 역시 이런 작업을 하기에 적합하다.

스키마 만들기

언급했다시피, XML 형식으로 데이터를 저장하고 JAXB를 사용하여 XML을 읽고 쓰는 작업을 할 것이다. 따라서 스키마를 작성할 필요가 있다.


Listing 1. 워크플로우 XML 스키마
                    
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
  targetNamespace="org:developerworks:workflow" 
  xmlns:dw="org:developerworks:workflow">

     <element name="workflow" type="dw:workflow"/>
     <complexType name="workflow">
          <sequence>
               <element name="user" type="dw:user" minOccurs="0"
maxOccurs="unbounded"/>
               <element name="po" type="dw:purchaseOrder"
minOccurs="0" maxOccurs="unbounded"/>
          </sequence>
     </complexType>
     
     <complexType name="user">
          <sequence>
               <element name="username" type="string"/>
               <element name="role" type="dw:role"/>
          </sequence>
          <attribute name="id" type="integer" use="required"/>
     </complexType>
     <simpleType name="role">
          <restriction base="string">
               <enumeration value="worker"/>
               <enumeration value="manager"/>
          </restriction>
     </simpleType>
     
     <complexType name="purchaseOrder">
          <sequence>
               <element name="priority" type="dw:priority"/>
               <element name="dateRequested" type="date"/>
               <element name="dateNeeded" type="date" minOccurs="0"/>
               <element name="itemName" type="string"/>
               <element name="itemDescription" type="string" minOccurs="0"/>
               <element name="quantityRequested" type="integer"/>
               <element name="url" type="anyURI" minOccurs="0"/>
               <element name="price" type="decimal"/>
               <element name="status" type="dw:orderStatus"/>
               <element name="submittedBy" type="integer"/>
               <element name="processedBy" type="integer" minOccurs="0"/>
          </sequence>
          <attribute name="id" type="integer" use="required"/>
     </complexType>
     
     <simpleType name="priority">
          <restriction base="string">
               <enumeration value="normal"/>
               <enumeration value="high"/>
          </restriction>
     </simpleType>
     
     <simpleType name="orderStatus">
          <restriction base="string">
               <enumeration value="pending"/>
               <enumeration value="approved"/>
               <enumeration value="rejected"/>
          </restriction>
     </simpleType>
</schema>

스키마에 해당하는 XML 파일에 바인딩할 자바 클래스를 만들기 위해 JAXB를 사용할 수 있다. 자바 6을 사용한다면 JAXB가 내장되어 있다. 자바 5를 사용한다면 썬에서 JAXB를 다운로드해야 한다. 여러분은 명령행 도구인 xjc를 사용하길 원할 수도 있다. 예를 들어 xjc workflow.xsd와 같이 사용할 수 있다. 이 명령어를 사용하여 workflow.xsd를 스키마 컴파일러가 파싱하고 클래스를 만들어낼 것이다. 그런 다음 클래스 파일들을 프로젝트에 복사하여 사용할 수 있다. 프로젝트에 XML 디렉터리를 만들고 그 안에 스키마 파일도 복사한다. 이제 예제로 사용할 XML 파일을 만들자.


Listing 2. 초기 XML 데이터
                    
<?xml version="1.0" encoding="UTF-8"?>
<dw:workflow xmlns:dw="org:developerworks:workflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="org:developerworks:workflow
workflow.xsd ">
  <user id="0">
    <username>homer</username>
    <role>worker</role>
  </user>
  <user id="1">
    <username>bart</username>
    <role>manager</role>
  </user>
  <po id="0">
    <priority>normal</priority>
    <dateRequested>2001-01-01</dateRequested>
    <dateNeeded>2001-01-01</dateNeeded>
    <itemName>stapler</itemName>
    <itemDescription>A great stapler</itemDescription>
    <quantityRequested>2</quantityRequested>
    <url>http://www.thinkgeek.com/homeoffice/gear/61b7/</url>
    <price>21.99</price>
    <status>pending</status>
    <submittedBy>0</submittedBy>
  </po>
</dw:workflow>

모든 요소들을 추가한 뒤 Package Explorer는 그림 26처럼 보일 것이다(필요하다면 JAXB jar 파일들을 자바 빌드 패스에 추가해야 한다).


그림 26. JAXB 클래스와 XML 파일이 추가된 Package explorer
JAXB 클래스와 XML 파일이 추가된 Package explorer




위로


데이터 접근

Package Explorer에 몇 가지 파일들이 추가된 것을 확인할 수 있을 것이다. 바로 WorkflowDao와 XmlWorkflow다. WorkflowDao는 데이터를 사용할 때 필요로 하는 작업들을 정의한 인터페이스다(Listing 3).


Listing 3. WorkflowDao 인터페이스
                    
package org.developerworks.workflow;

import java.util.List;

public interface WorkflowDao {
     public List<User> getUsers();
     public List<PurchaseOrder> getAllOrders();
     public List<PurchaseOrder> getAllPendingOrders();
     public List<PurchaseOrder> getOrdersForUser(int userId);
     public void saveOrder(PurchaseOrder order);
     public void setOrderStatus(int orderId, OrderStatus status);
}

고전적인 데이터 접근 객체(Data Access Object) 패턴을 사용하고 있다. 간단하게 인터페이스를 정의하고 이 인터페이스에 대한 애플리케이션 코드를 작성한다. XML을 사용하여 JAXB 기반 구현을 할 것이다. 하지만 이 디자인을 사용하여 손쉽게 데이터베이스 기반 구현 같은 기타 구현으로 변경할 수 있다. 이 인터페이스의 구현체가 XmlWorkFlow다.


Listing 4. XmlWorkflow 인터페이스 구현
                    
package org.developerworks.workflow;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class XmlWorkflow implements WorkflowDao {
     private static final String DATA_FILE = "data.xml";
     private static XmlWorkflow instance;
     
     private Workflow workflow;
     
     private XmlWorkflow() {
          try {
               JAXBContext ctx = this.getContext();
               Unmarshaller unm = ctx.createUnmarshaller();
               File dataFile = this.getDataFile();
               InputStream inputStream;
               if (dataFile.exists() && dataFile.length() > 0){
                    inputStream = new FileInputStream(dataFile);
               } else {
                    inputStream = 
Thread.currentThread().getContextClassLoader().getResourceAsStream("xml/"+DATA_FILE);
               }
               JAXBElement element = (JAXBElement) unm.unmarshal(inputStream);
               this.workflow = (Workflow) element.getValue();
          } catch (JAXBException e) {
               e.printStackTrace();
               throw new RuntimeException("Failed to read data file",e);
          } catch (FileNotFoundException e) {
               e.printStackTrace();
               throw new RuntimeException("Could not open data file", e);
          }
     }
     
     public static XmlWorkflow getInstance(){
          if (instance == null){
               instance = new XmlWorkflow();
          }
          return instance;
     }

     public List<PurchaseOrder> getAllOrders() {
          return this.workflow.getPo();
     }

     public List<PurchaseOrder> getAllPendingOrders() {
          List<PurchaseOrder> allOrders = this.getAllOrders();
          List<PurchaseOrder> pending = new ArrayList<PurchaseOrder>();
          for (PurchaseOrder order : allOrders){
               if (order.getStatus().equals(OrderStatus.PENDING)){
                    pending.add(order);
               }
          }
          return pending;
     }

     public List<PurchaseOrder> getOrdersForUser(int userId) {
          List<PurchaseOrder> allOrders = this.getAllOrders();
          List<PurchaseOrder> userOrders = new ArrayList<PurchaseOrder>();
          for (PurchaseOrder order : allOrders){
               if (order.getSubmittedBy().intValue() == userId){
                    userOrders.add(order);
               }
          }
          return userOrders;
     }

     public List<User> getUsers() {
          return this.workflow.getUser();
     }

     public void saveOrder(PurchaseOrder order) {
          int index = 0;
          for (PurchaseOrder po : this.workflow.getPo()){
               if (po.getId().intValue() == order.getId().intValue()){
                    this.workflow.getPo().set(index, order);
                    this.saveData();
                    return;
               }
               index++;
          }
          // add new order
          order.setId(new BigInteger(Integer.toString(this.workflow.getPo().size())));
          this.workflow.getPo().add(order);
          this.saveData();
     }
     
     public void setOrderStatus(int orderId, OrderStatus status) {
          for (PurchaseOrder po : this.workflow.getPo()){
               if (po.getId().intValue() == orderId){
                    po.setStatus(status);
                    this.saveData();
                    return;
               }
          }
     }

     private void saveData(){
          File dataFile = this.getDataFile();
          try {
               JAXBContext ctx = this.getContext();
               Marshaller marshaller = ctx.createMarshaller();
               FileOutputStream stream = new FileOutputStream(dataFile);
               marshaller.marshal(this.workflow, stream);
          } catch (JAXBException e) {
               e.printStackTrace();
               throw new RuntimeException("Exception serializing data file",e);
          } catch (FileNotFoundException e) {
               e.printStackTrace();
               throw new RuntimeException("Exception opening data file");
          }
     }
     
     private File getDataFile() {
          String tempDir = System.getProperty("java.io.tmpdir");
          File dataFile = new File(tempDir + File.separatorChar + DATA_FILE);
          return dataFile;
     }

     private JAXBContext getContext() throws JAXBException {
          JAXBContext ctx = JAXBContext.newInstance("org.developerworks.workflow");
          return ctx;
     }
     
     public static void main(String[] args){
          XmlWorkflow dao = XmlWorkflow.getInstance();
          List<User> users = dao.getUsers();
          assert(users.size() == 2);
          for (User user : users){
               System.out.println("User: " + user.getUsername() + " ID:" + user.getId());
          }
          List<PurchaseOrder> orders = dao.getAllOrders();
          assert(orders.size() == 1);
          for (PurchaseOrder order : orders){
               System.out.println("Order:" + order.getItemName() + "
ID:" + order.getId() + " Status:" + order.getStatus());
          }
          PurchaseOrder order = orders.get(0);
          order.setStatus(OrderStatus.APPROVED);
          order.setProcessedBy(new BigInteger("1"));
          dao.saveOrder(order);
     }
}

위에서 만들었던 예제 파일을 초기에 읽어 들이는 것을 확인할 수 있지만 시스템 임시 폴더에 data.xml로 변경사항을 저장한다. 데이터를 저장하기에 가장 안전한 장소는 아니지만 예제 애플리케이션에 사용하기에는 적절하다. 이 클래스 파일 안에 간단한 main 메서드가 있는 것 또한 볼 수 있다. JAXB가 동작하는 것을 간단하게 단위 테스트하기 위한 용도로 만들었다. 만약에 자바 5를 사용한다면 JAXB jar 파일을 프로젝트의 클래스패스에 추가해야 한다. 계속해서 작업하려면 그 파일들을 복사하여 프로젝트에 추가하거나 프로젝트 외부에 그 파일들이 위치한 장소를 참조할 수 있도록 해야 한다.




위로


애플리케이션 초기화하기

애플리케이션과 인터랙트하기 전에 모든 요소를 초기화해야 한다. 먼저 애플리케이션에서 사용할 모델 객체를 몇 개 선언해야 한다. Listing 5에 있는 코드를 추가하여 WorkflowMain 멤버 변수를 추가한다.


Listing 5. 모델 객체 선언
                    
     // Data Model Objects
     private java.util.List<User> users;
     private User user;
     
     // Service Object
     private WorkflowDao dao = XmlWorkflow.getInstance();

코드에 접근하려면 Workflow.java 파일을 마우스 오른쪽 클릭을 하고 Open With > Java Editor를 선택한다.

애플리케이션의 initGUI() 메서드 코드를 수정한다. 사용자 명단을 초기화하기 위해 private 메서드를 만들겠다.


Listing 6. 사용자 메서드 만들기
                    
     private void initUserList(){
          this.users = dao.getUsers();
          for (User u : users){
               this.userListCombo.add(u.getUsername());
          }
     }

userListCombo를 정의한 후 initGUI()에서 이 메서드를 호출한다.


Listing 7. 사용자 메서드 호출
                    
                {
                    userListCombo = new Combo(this, SWT.NONE);
                    userListCombo.setText("Users");
                    userListCombo.setBounds(28, 35, 105, 21);
                    this.initUserList();
               }




위로


이벤트를 사용하여 뷰와 모델을 엮기

뷰와 모델을 만들었다. 이제 그 둘을 엮어 보자. 컨트롤러가 필요하다. SWT(와 스윙)는 모든 UI 프레임워크에서 사용하는 간단한 기술을 사용한다. 바로 이벤트 주도 시스템이라는 것이다. 이벤트를 사용하여 언제 모델에 있는 작업을 호출하고 뷰를 수정할지 알려줄 수 있다.

이제 다시 비주얼 디자이너로 돌아가자. 모델과 엮기를 원하는 첫 번째 UI 이벤트는 사용자 콤보 리스트에서 사용자를 선택했을 때다. 콤보 컨트롤을 선택하고 GUI 속성 뷰에서 Event 탭으로 변경하면 그림 27에 보이는 것과 같은 화면을 확인할 수 있을 것이다.


그림 27. 콤보 컨트롤 이벤트에 접근하기
콤보 컨트롤 이벤트에 접근하기

몇몇 리스너들을 콤보 컨트롤에서 볼 수 있다. SelectionListener를 선택한다. 이 리스너는 콤보 컨트롤에서 무언가를 선택할 때마다 SelectionEvent를 발생시킨다. 이 이벤트를 다룰 것을 익명 메서드로 그것을 인라인에서 다룰 수도 있고이 이벤트를 다룰 메서드를 정의할 수도 있다. 후자를 선택하겠다. 이렇게 하면 userListComboWidgetSelected라는 메서드가 생성된다. 이벤트를 다루기 위한 코드는 Listing 8에 나와있다.


Listing 8. 사용자 콤보 리스트 선택 코드
                    
     private void userListComboWidgetSelected(SelectionEvent evt) {
          int index = this.userListCombo.getSelectionIndex();
          if (index >= 0){
               this.user = this.users.get(index);
               System.out.println("User selected="+this.user.getUsername());
               purchaseOrderTable.removeAll();
               java.util.List<PurchaseOrder> orders;
               boolean isManager = this.user.getRole().equals(Role.MANAGER);
               if (isManager){
                    orders = dao.getAllPendingOrders();
               } else {
                    orders = dao.getOrdersForUser(this.user.getId().intValue());
               }
               this.approveButton.setVisible(isManager);
               this.rejectButton.setVisible(isManager);
               for (PurchaseOrder order : orders){
                    displayPurchaseOrder(order);
               }
          }
     }

여기서 살펴봐야 할 것들이 많다. 먼저 사용자가 관리자인지 확인한다. 관리자가 아니면 사용자의 모든 구매 주문 목록을 보여준다. 관리자가 맞다면 대기중인 주문 목록만을 보여준다. 다음으로 관리자가 아니면 승인/취소 버튼이 보이지 않도록 한다. 마지막으로 purchaseOrderTable에 있는 모든 주문 데이터들을 데이터 접근 객체를 사용해 가져와 보여준다.

이제 Approve 버튼에 이벤트를 추가한다. 비주얼 디자이너에 보이는 Approve 버튼을 선택하고 GUI 속성 창에 있는 이벤트 탭으로 이동한다. 버튼을 선택했을 때 실행되어야 하기 때문에 그림 28에 보이는 것처럼 여기서도 selection event를 사용할 것이다.


그림 28. Approve 버튼 선택 이벤트 설정
Approve 버튼 선택 이벤트 설정

그리고 나서 이 이벤트를 다룰 코드를 추가한다.


Listing 9. Approve 버튼 선택 이벤트 코드
                    
     private void approveButtonWidgetSelected(SelectionEvent evt) {
          TableItem[] selected = this.purchaseOrderTable.getSelection();
          if (selected != null){
               for (TableItem item : selected){
	this.dao.setOrderStatus(Integer.parseInt(item.getText(4)), OrderStatus.APPROVED);
                    item.setText(3, OrderStatus.APPROVED.toString());
               }
          }
     }

reject 버튼도 이와 매우 비슷하게 할 수 있다. 선택 이벤트 리스너를 추가하고 비슷한 코드를 실행한다. 유일한 차이가 있다면 주문 상태를 APPROVED가 아닌 REJECTED로 바꾼다는 것이다.


Listing 10. Reject 버튼 코드
                    
     private void rejectButtonWidgetSelected(SelectionEvent evt) {
          TableItem[] selected = this.purchaseOrderTable.getSelection();
          if (selected != null){
               for (TableItem item : selected){
	this.dao.setOrderStatus(Integer.parseInt(item.getText(4)), OrderStatus.REJECTED);
                    item.setText(3, OrderStatus.REJECTED.toString());
               }
          }
     }

이제 남은 건 Submit 버튼이다. 이 버튼을 사용하여 새로운 구매 주문을 추가할 수 있어야 한다. 이 버튼 역시 다른 버튼들과 유사하다. 선택 이벤트에 대한 이벤트 핸들러를 그림 29처럼 추가한다.


그림 29. PO 버튼 선택 리스너 추가
PO 버튼 선택 리스너 추가

이벤트를 다룰 코드를 추가한다.


Listing 11. PO 버튼 이벤트 핸들러 코드 추가
                    
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.GregorianCalendar;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

...

     private void addButtonWidgetSelected(SelectionEvent evt) {
          try {
               this.addPurchaseOrder();
          } catch (Exception e) {
               throw new RuntimeException("Exception adding purchase order",e);
          }
          this.formItemText.clearSelection();
          this.formPriceText.clearSelection();
          this.formQuantityText.clearSelection();
     }
     
     private void addPurchaseOrder() throws Exception{
          String item = this.formItemText.getText();
          String priceString = this.formPriceText.getText();
          String quantityString = this.formQuantityText.getText();
          BigDecimal price = new BigDecimal(priceString);
          BigInteger quantity = new BigInteger(quantityString);
          PurchaseOrder po = new PurchaseOrder();
          int num = this.dao.getAllOrders().size();
          String numString = Integer.toString(num);
          BigInteger newId = new BigInteger(numString);
          po.setId(newId);
          po.setItemName(item);
          po.setPrice(price);
          po.setQuantityRequested(quantity);
          po.setPriority(Priority.NORMAL);
          po.setStatus(OrderStatus.PENDING);
          po.setSubmittedBy(this.user.getId());
          GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance();
          DatatypeFactory factory = DatatypeFactory.newInstance();
          XMLGregorianCalendar now = factory.newXMLGregorianCalendar(cal);
          po.setDateRequested(now);
          this.dao.saveOrder(po);
          this.displayPurchaseOrder(po);
     }

	private void displayPurchaseOrder(PurchaseOrder order) {
		String[] row = new String[] 
		         {order.getItemName(), order.getPrice().toString(), 
				order.getQuantityRequested().toString(),
order.getStatus().toString(), order.getId().toString()};
		TableItem tableItem = new TableItem(purchaseOrderTable,0);
		  tableItem.setText(row);
		  this.purchaseOrderTable.showItem(tableItem);
	}




위로


GUI 테스트

GUI를 테스트해야 할 시간이다. 그림 30처럼 클래스를 오른쪽 클릭을 한 후 Run As > SWT Application을 선택한다.


그림 30. 애플리케이션 실행
애플리케이션 실행

이렇게 하면 애플리케이션이 실행된다.


그림 31. 워크플로우 애플리케이션
워크플로우 애플리케이션

기본 데이터로 대기중인 구매 주문을 넣어뒀기 때문에 사용자 bart를 선택한 뒤 구매 주문을 승인할 수 있다.


그림 32. 주문 승인
주문 승인

사용자를 homer로 변경한 뒤 구매 주문의 상태를 확인해 보자.


그림 33. 사용자가 자기 PO 보기
사용자가 자기 PO 보기

새로운 주문을 추가할 수도 있다.


그림 34. PO 추가
PO 추가

Add PO를 클릭하여 테이블에 구매 주문을 추가할 수 있다.


그림 35. 새 PO 추가
새 PO 추가

다시 bart로 변경하여 승인 또는 취소할 수 있다.


그림 36. 업데이트된 관리자 화면
업데이트된 관리자 화면 
반응형

GUI 설정하기

시스템에 대한 기본적인 설계를 했기 때문에 이제는 코드를 작성할 차례다. GUI와 Jigloo 사용법에 집중하도록 하겠다.

워크플로우 애플리케이션 GUI 디자인

워크플로우 애플리케이션 GUI 설계를 시작해 보자. 먼저, 워크플로우 애플리케이션에서 사용할 패키지를 만들자. Package Explorer 창에서 프로젝트를 마우스 오른쪽 클릭을 한 후 New > Package를 선택한다. 기본 패키지를 org.developerworks.workflow로 하겠다. Finish를 클릭한다.

이제 이 패키지에 애플리케이션을 작성해보자. 패키지에서 오른쪽 클릭한 후 New > Other를 선택한다. 그럼 “Select a wizard” 화면을 볼 수 있을 것이다. 모든 Jigloo 마법사들이 이 화면에 있는 GUI Form 폴더에 있을 것이다. 그림 3과 같이 그 폴더를 열고 나서 SWT 폴더를 열고 SWT Main Application 옵션을 선택한다.


그림 3. 마법사 선택
마법사 선택

Next를 선택하여 New SWTApp 마법사를 시작한다. 그림 4처럼 main 클래스를 WorkflowMain으로 하겠다.


그림 4. 새 SWTApp 마법사
새 SWTApp 마법사

나머지는 그대로 두고 Finish를 클릭한다.

Jigloo 비주얼 디자이너 뷰

이제 여러분의 이클립스 워크스페이스가 그림 5처럼 보일 것이다.


그림 5. WorkflowMain을 보여주는 이클립스
WorkflowMain을 보여주는 이클립스

여기서 주목해야 할 것들이 여러 가지 있다. 먼저 메인 창은 Jigloo에서 사용하는 커스텀 뷰를 보여준다. 이 뷰는 몇 개의 화면으로 나뉘어 있다. 맨 위에는 Jigloo 비주얼 디자이너가 있다. GUI에서 드래그 앤 드롭을 사용하여 만들 수 있기 때문에 이 화면을 가장 자주 사용하게 될 것이다. 이 뷰에 대해서는 좀 더 자세히 알아보겠다. 나뉘어져 있는 화면 맨 아래에는 나중에 자세히 살펴 볼 애플리케이션의 자바 코드가 있다. Jigloo가 어떻게 코드를 만들어 놨는지 살펴보길 바란다.

메인 창 바로 아래에는 GUI 속성 창이 있다. 이 뷰에서는 비주얼 다자이너 창에서 선택된 비주얼 컴포넌트의 속성들을 자세히 보여준다. 이 뷰 역시 자주 사용할 것이다. 마지막으로 Package Explorer 뷰에 com.cloudscape.resource패키지가 만들어진 것을 볼 수 있다. 이 패키지는 자동으로 만들어진 SWTResourceManager클래스를 포함하고 있다. 클래스의 이름이 암시하듯이 이 클래스는 글꼴, 색, 이미지와 같은 SWT 자원을 관리한다. Jigloo와 같은 비주얼 디자이너 도구를 사용해본 경험이 있다면, 이런 클래스를 본 적이 있을 것이다. 보통 이런 종류의 클래스는 절대로 수정하지 않도록 권하고 있다. 이 클래스를 수정할 경우 에러를 발생할 가능성이 많으며 아마도 수정하면 예외를 던지거나 수정을 가하더라도 아마 재정의될 것이다. 그러나 SWTResourceManager의 경우에는 그렇지 않다. 이 클래스를 수정하여 Jigloo와 애플리케이션에서 사용할 기본 글꼴과 같은 이 클래스가 관리할 자원을 변경할 수 있다. 그리고 Jigloo가 그 변경사항들을 무시한 채 덮어쓰지도 않을 것이며 에러를 발생시키지도 않을 것이다.

비주얼 디자이너를 사용해 보자. 만약 이클립스를 사용하는 데 익숙하다면, 창 제목 막대를 더블 클릭하면 창을 최대화할 수 있음을 알고 있을 것이다. 그림 6처럼 WorkflowMain 창을 최대화하자.


그림 6. WorkflowMain 최대화
WorkflowMain 최대화

이렇게 함으로써 비주얼 디자이너로 작업할 때 좀 더 예측하기가 수월하며 오른쪽 아래에 있는 GUI 속성에 접근하기도 편리해진다. 또한 우상단에서 GUI를 계층적으로 보여준다. 현재는 매우 단순하지만 GUI에 컴포넌트를 추가하면 그것들이 계층(hierarchy)에 추가되는 것을 확인할 수 있다. 그뿐만 아니라 애플리케이션을 미리 보고 테스트할 수 있는 유용한 기능을 제공한다. 이제 비주얼 디자이너에 조금 익숙해졌을 것이다. 이것을 사용하여 애플리케이션을 만들어 보자.




위로


비주얼 디자이너로 개발하기

스윙이나 SWT 애플리케이션을 개발해 본 적이 있다면, 다양한 종류의 레이아웃 관리자에 익숙할 것이다. 레이아웃 관리자는 자바 GUI 애플리케이션의 강력한 기능 중 하나다. GUI의 레이아웃을 구성할 때 다양한 종류의 알고리즘을 적용할 수 있다. 자바의 모토는 항상 “한 번 만들면 거의 어디서든 동작한다”였고 이러한 레이아웃 알고리즘 역시 이 모토와 일맥상통한다. 이것들을 사용하면 GUI 애플리케이션의 레이아웃이 GUI를 보여주는 창이나 화면에 놓이는 도형들의 크기를 고려하지 않아도 된다.

이런 레이아웃 알고리즘의 유일한 단점은 개발자들이 학습을 해야 한다는 것이며 특히 구성요소들을 절대 좌표에 위치시켜야 하는 플랫폼을 사용하던 개발자들에겐 더욱 심하다. 절대 좌표를 사용하면 컴포넌트들을 화면에서 원하는 위치에 놓을 수 있고 그럼 구성요소들은 그 곳에 놓인다. 이런 레이아웃의 문제점은 창의 크기가 자유롭게 변하는 경우 “깨짐” 현상이 나타난다는 것이다.

예제 애플리케이션은 매우 간단한 프로그램이기 때문에 절대 좌표 레이아웃을 사용할 것이다. 설정은 GUI 속성에서 할 수 있다. 그림 7처럼 Layout 탭을 클릭하고 Layout 값을 Absolute로 변경한다.


그림 7. 레이아웃 설정
레이아웃 설정

다음으로 애플리케이션 크기를 좀 더 크게 해보자. 그렇게 하려면 메인 창의 오른쪽 아래 구석을 마우스로 클릭하여 잡은 다음에 원하는 크기만큼 잡아당겨 늘이면 된다.

이제 애플리케이션에 컴포넌트를 추가할 준비가 끝났다. 여러 사용자 계정 중에 로그인할 사용자 계정을 선택할 수 있어야 한다. 또한 로그인 화면을 만들어 사용자 이름과 비밀번호를 입력할 수 있어야 하지만 최대한 단순하게 만들자. drop-down 리스트를 사용하여 로그인할 사용자를 선택하자.

비주얼 디자이너 위에 툴바가 있고 그곳에서 여러 컴포넌트들을 선택하여 애플리케이션에 추가할 수 있다. 이것은 탭으로 되어 있는 툴바다. 컨트롤을 추가해야 되기 때문에 컨트롤 탭을 선택한다. 각각의 컨트롤은 직관적인 아이콘으로 보이고 있지만 각 아이콘 위에 마우스를 가져가면 이름을 확인할 수 있다. combo 컨트롤을 선택하고 메인 창 위에 놓는다. 그렇게 하면 그림 8처럼 속성 편집 창에 새로운 컨트롤에 대한 정보가 표시된다.


그림 8. 콤보 컨트롤용 속성 편집창
콤보 컨트롤용 속성 편집창

컨포넌트의 이름을 좀 더 직관적인 이름인 userListCombo로 수정하고 Users의 기본 텍스트를 준다. OK를 클릭하면 애플리케이션에서 볼 수 있다.

이제 사용자를 선택하고 바꿀 수 있는 방법이 생겼다. 사용자를 선택했을 때 그 사용자들이 진짜로 원하는 것이 무엇일까? 작업자들은 그들이 입력했던 구매 주문 데이터와 주문 상태를 보고 싶을 것이다. 관리자들은 어떤 주문들이 승인 또는 취소를 기다리고 있는지 보고 싶을 것이다. 구매 주문을 보여주기 위한 테이블을 만들어 보자.

테이블을 추가하기 위해 툴바 탭에서 컨테이너 탭으로 바꾼다. 테이블처럼 보이는 아이콘을 찾아 선택한다. 테이블을 처음 선택하면 마우스를 사용하여 원하는 위치에 그것을 놓을 수 있다. 위에서 추가했던 콤보 리스트 바로 아래에 놓는다. 위치를 정하면 테이블 이름을 묻는 대화창이 나타날 것이다. 콤보 리스트의 이름으로 직관적인 purchaseOrderTable을 입력하자. OK를 클릭하면 테이블이 비주얼 디자이너에 보일 것이다.

테이블 크기도 오른쪽 아래 코너를 잡아 좀 더 크게 만들 수 있다. 이 방법으로 좀 더 테이블을 크게 설정하자. 테이블 속성은 이클립스 오른쪽 아래에 있는 GUI 속성 뷰에 보일 것이다. Properties 탭을 클릭하고 속성 목록 중에서 Expert를 펼친다. 그림 9에 보이는 것처럼 체크박스를 클릭하여 lines-visible 속성을 true로 설정하자.


그림 9. 테이블 속성 편집
테이블 속성 편집

테이블에 칼럼 몇 개를 추가해 보자. 툴바에 있는 컨테이너 탭에서 이전에 선택했던 테이블 아이콘 바로 오른쪽에 있는 Add TableColumn to Table 아이콘을 선택한다. 이제 TableColumn을 purchaseOrderTable에 내려놓으면 TableColumn 속성 편집기가 보일 것이다. 주문한 물건의 이름을 보여줄 것이 때문에 poItemNameColumn이라는 적절한 이름으로 설정한다. 이 값은 테이블의 칼럼 이름으로 사용할 것이기 때문에 Item에 입력하고 OK를 클릭한다.

이것을 추가한 뒤에 비주얼 디자이너는 그림 10처럼 보일 것이다.


그림 10. 칼럼 하나를 추가한 후의 비주얼 편집기
칼럼 하나를 추가한 후의 비주얼 편집기

그런데 지금, 테이블에서 칼럼 이름을 볼 수 없을지도 모른다. 그렇다면 이것은 테이블의 Expert 속성을 변경하여 보이게 할 수 있다. 테이블을 클릭하고 GUI 속성 창으로 다시 이동한다. Expert 섹션을 열고 headerVisible 속성을 Figure 11처럼 설정한다.


그림 11. 테이블 속성 편집
테이블 속성 편집

속성 값은 체크 박스를 사용하여 true나 false로 설정할 수 있다. true로 바꾸고 나면 테이블에서 header를 볼 수 있고 첫 번째 칼럼의 item 레이블을 볼 수 있을 것이다.

계속해서 같은 방법으로 네 개의 칼럼(Price, Quantity, Status, ID)를 추가하자. 모두 추가했으면 그림 12와 같이 보일 것이다.


그림 12. 테이블에 칼럼 전부 추가
모든 칼럼을 테이블에 추가

필요한 주문을 전부 보여줄 수 있다. 여기에서 주문을 승인할지 취소할지 선택할 수 있는 방법이 필요하다. 그렇게 할 수 있도록 각각의 기능을 할 수 있는 버튼들을 추가하자. 버튼을 추가하려면 툴바에 있는 컨트롤 탭으로 이동하여 버튼 컨트롤 아이콘을 선택한다. 이 버튼 역시 원하는 위치에 놓을 수 있다. 테이블 바로 아래에 위치시킨다. 버튼을 위치시키면 버튼의 속성 편집창이 나타날 것이다. 첫 번째 버튼은 구매 주문을 승인하기 위한 버튼으로 사용할 것이다. 따라서 이름은 approveButton이고 텍스트 레이블은 Approve로 하자. OK를 클릭하면 비주얼 편집기에 새로 추가한 버튼이 보일 것이다.

간단하게 Reject 버튼을 애플리케이션에 추가할 것이다. 이 모든 과정을 마친 뒤 비주얼 디자이너는 그림 13처럼 보일 것이다.


그림 13. 버튼 둘 다 추가
버튼 둘 다 추가

추가한 두 개의 버튼이 줄이 맞지 않다는 것을 위 그림에서 알아차렸을 것이다. 맨 눈으로 그런 일을 하는 것은 쉽지 않지만 다행히도 Jigloo가 컴포넌트들의 줄을 맞추는 쉬운 방법을 제공한다. 간단하게 두 개의 컴포넌트를 선택하고(이 경우 버튼 두 개) 비주얼 디자이너 왼쪽에 있는 스타일링 툴바를 사용하면 된다. Align tops of selected elements 버튼을 사용하면 그림 14처럼 보일 것이다.


그림 14. 버튼 정렬
버튼 정렬

버튼들의 모양이 보기 좋게 자리를 잡았다. Jigloo를 사용하면 GUI 모양을 매우 전문적으로 보이게 하는 것이 쉽다.

이제 사용자를 선택할 수 있고 구매 주문 내역을 볼 수 있으며 구매 주문을 승인 또는 거절할 수 있다. 이제 남은 건 구매 주문을 추가하는 기능이다. 새로운 구매 주문을 만들기 위한 데이터를 입력할 때 사용할 폼을 만들 것이다. 폼에는 구매 주문 모델을 만드는 데 필요한 다양한 데이터 유형에 해당하는 여러 가지 컴포넌트과 관련되어 있다. 이 컴포넌트들을 그룹화해 만들어 보자. 모든 컴포넌트를 그룹으로 처리하는 것은 매우 유용하다. 예를 들어, 특정 사용자만 새로운 구매 주문을 추가할 수 있도록 할 수 있다. 그런 권한이 있는 사용자에게만 폼이 보이도록 설정할 수 있다. 이 때 모든 컴포넌트가 그룹으로 되어 있을 때 더 쉽게 할 수 있다.

그룹을 만들려면 Composite 컴포넌트를 애플리케이션에 추가한다. 툴바의 컨테이너 탭으로 이동하고 Figure 15처럼 Composite 아이콘을 선택한다.


그림 15. 툴바를 사용해 컴포지트 추가
툴바를 사용해 컴포지트 추가

원하는 위치에 놓는다. 오른쪽 공간이 많이 비어 있으므로 그곳에 놓자. 그림 16처럼 Composite 속성 편집 창이 나오는 것에 익숙해졌을 것이다.


그림 16. 컴포지트 속성 편집창
컴포지트 속성 편집창

여기서 추가한 Composite이 하는 일의 의도에 적당한 이름인 itemForm을 입력한다. 레이아웃으로 절대 좌표를 사용하는 것에 유의하자. Composite도 자신의 레이아웃 관리자를 사용할 수 있기 때문이다. OK를 클릭한 후 그림 17과 같이 비주얼 디자이너에 보일 것이다.


그림 17. 비주얼 디자이너의 컴포지트
비주얼 디자이너의 컴포지트

오른쪽 아래 코너를 잡아 당겨 Composite의 크기를 조정할 수 있다. 폼 요소들이 모두 자리 잡을 수 있을 만큼 넉넉하게 크기를 확장시키자.

이제 폼을 디자인해 보자. 폼은 텍스트 박스와 레이블을 주로 사용한다. 툴바를 사용하여 이런 요소들을 추가한다. Control 탭으로 이동하여 레이블 아이콘을 선택한다. 예상했듯이 원하는 위치에 내려 놓을 수 있다. 폼 컨테이너 왼쪽 위에 놓도록 하자. 이번에는 레이블 컨트롤에 대한 속성 편집창이 그림 18처럼 나타날 것이다.


그림 18. 라벨 컨트롤 속성 편집창
라벨 컨트롤 속성 편집창

이제 비주얼 디자이너에서 레이블을 볼 수 있을 것이다. 다시 오른쪽 아래 코너를 사용하여 원하는 크기로 조정하자.

레이블 바로 오른쪽에 텍스트 박스를 추가해 사용자가 구매 주문할 물건의 이름을 적을 수 있도록 만든다. 툴바에서 Text Control을 선택한다. 이제 원하는 위치에 놓으면 그림 19와 같은 속성 편집창이 나타난다.


그림 19. 텍스트 컨트롤 속성 편집창
텍스트 컨틀롤 속성 편집창

formItemText라는 이름을 주자. Text 값에는 아무것도 입력하지 않는다. 기본 값을 줄 수도 있지만 그럴 필요는 없다. 이제 비주얼 편집기에서 텍스트 박스를 볼 수 있고 크기를 조정할 수 있다.

계속해서 두 개의 필드 Price와 Quantity를 이와 같은 방법으로 추가한다. 각각 레이블과 텍스트 박스를 사용한다. 모두 추가하면 비주얼 디자이너는 그림 20처럼 보일 것이다.


그림 20. 가격 및 수량 필드 추가
가격 및 수량 필드 추가

Quantity의 기본 값을 1로 설정한 것에 주의하기 바란다. 구매 주문을 할 때 필요로 하는 기본적으로 필요로 하는 요소들이다. 이제 폼을 처리하기 위해 보내는 방법이 필요하다. 이런 기능을 할 버튼을 추가하자. 툴바에서 Button 컨트롤을 선택하여 추가하는 작업은 이전에 살펴보았다. 이번에는 다른 방법으로 해보자. Composite 안에서 마우스 오른쪽 버튼을 클릭하고 그림 21처럼 Add SWT Object > Button을 선택한다.


그림 21. 컨텍스트 메뉴를 사용해 버튼 추가
컨텍스트 메뉴를 사용해 버튼 추가

이제 많이 익숙한 속성 편집창이 뜰 것이다. 컴포넌트의 이름을 addButton으로 하고 텍스트는 Add PO로 한다. OK를 클릭하면 비주얼 디자이너에 그림 22처럼 새로운 버튼이 추가된 것을 볼 수 있다.


그림 22. 버튼 추가
버튼 추가

이 방법과 툴바를 사용하는 방법의 가장 큰 차이는 위치를 조정하고 다른 컨트롤들과의 배열을 맞출 필요가 있다는 것이다. 이 방법을 사용하면 다른 배열 컨트롤을 사용할 수 있는 기회가 생긴다. 세 개의 텍스트 박스와 추가 버튼을 선택하고(shift 키를 사용해 마우스를 클릭하면 여러 컨트롤을 선택할 수 있다) 그림 23처럼 Space selected elements evenly vertically"를 클릭한다.


그림 23. 요소 간 위아래 간격을 똑같게 조정하기
요소 간 위아래 간격을 똑같게 조정하기

다른 정렬 컨트롤러들도 자유롭게 사용할 수 있다. 모든 작업을 완료하면 그림 24처럼 보일 것이다.


그림 24. 최종 UI 디자인
최종 UI 디자인




위로


GUI 미리보기

이제 GUI를 보여주는 멋진 그림을 얻었다. 하지만 아직 어떤 데이터도 연결되지 않았기 때문에 기능적으로 동작하지는 않는다. 간단하게 추가할 수 있지만 그전에 Jigloo의 멋진 기능 중 하나인 미리보기를 사용하기에 적절한 시점이다. 창의 오른쪽 위에 있는 Preview를 클릭한다. 그림 25에서 볼 수 있듯이 GUI의 미리보기가 제공될 것이다.


그림 25. 워크플로우 GUI 미리보기
워크플로우 GUI 미리보기

우리가 마지막으로 만들었던 애플리케이션의 모양과 정확히 일치한다. Windows® 애플리케이션과 모양이 똑같다는 것에 주목하기 바란다. 윈도우에서 SWT를 사용하고 있기 때문이다. 언급했다시피 SWT는 네이티브 위젯을 사용하기 때문이다.
<출처 :https://www.ibm.com/developerworks/kr/library/tutorial/os-eclipse-jigloo/section3.html>

반응형

개요

이번 절에서는 Jigloo 플러그인을 설치하고 설정하기 전에 이것으로 무엇을 할 수 있는지 살펴보겠다.

Jigloo란 무엇인가?

는 비주얼 자바 GUI 빌더다. Jigloo는 CloudGarden에서 만든 이클립스(와 WebSphere® Studio) 플러그인이다. 상업적인 용도가 아니라면 공짜로 쓸 수 있다. CloudGarden에서 라이선스를 받아 상업적인 용도로 사용할 수 있다.

Jigloo로 무엇을 할 수 있나?

Jigloo는 스윙과 SWT GUI를 개발할 수 있는 고전적인 위지위그(WYSIWYG) 편집기다. 만약 자바로 데스크톱 애플리케이션을 개발하고 싶다면 Jigloo가 최고의 대안이 될 것이다. 하지만 그것뿐만이 아니다.

Jigloo는 라운드 트리핑(round-tripping)을 지원한다. 이 말은 코드 수정을 통해서만 GUI에 변화를 줄 수 있는 것이 아니라 GUI에 직접 변화를 주어 코드가 수정되는 것을 확인할 수 있다는 뜻이다. 기존에 만들어진 GUI를 변경하고 싶을 때도 Jigloo는 훌륭한 대안이 될 수 있다. 이미 존재하고 있는 애플리케이션을 분석하고 화면을 통해 수정할 수 있도록 도와준다. 그리고 Jigloo를 NetBeans나 JBuilder와 같은 IDE와도 함께 쓸 수 있다.

Jigloo는 스윙/SWT 호환을 염두에 두고 개발되었다. 각각의 기술이 제공하는 다양한 레이아웃 옵션을 지원한다. 새로운 UI를 만드는 것뿐만 아니라 Jigloo를 사용하여 스윙과 SWT를 서로 변환할 수도 있다. SWT_AWT 브리지(bridge)를 사용하여 스윙 컴포넌트를 SWT 애플리케이션에 포함시킬 수도 있다. 하지만 이번 튜토리얼에서 우리는 SWT GUI를 사용하는 워크플로우 애플리케이션을 개발하겠다.

Jigloo 설치

Jigloo는 이클립스 플러그인이기 때문에 설치가 매우 쉽다. 만약 몇 년 간 이클립스를 사용해오고 있다면 플러그인을 다운로드해 이클립스 설치 디렉터리에 압축을 푸는 방법으로 플러그인을 설치해봤을 것이다. 하지만 최신 버전 이클립스를 사용하면 더 쉽게 설치할 수 있다. 이클립스 업데이트 관리자 기능이 바로 그것이다. 이 기능을 사용하려면 Help > Software Updates > Find and Install을 선택하면 된다. 그러면 Install/Update 대화창이 열린다. 이 때 “Search for new features to install” 옵션을 선택한다. 그리고 나서 Next를 클릭하면 Update Site 대화창으로 이동한다.

만약 다른 이클립스 플러그인들이 이미 설치되어 있다면 “Sites to include in search”에 이미 등록되어 있는 다른 사이트들이 보일 것이다. 이 때 목록에 보이는 모든 사이트들을 선택하지 않는다. 아래 보이는 New Update Site 대화창을 볼 수 있도록 New Remote Site를 클릭한다.


그림 1. 새 업데이트 사이트
새 업데이트 사이트

이 때 중요한 것은 URL 필드에 http://cloudgarden1.com/update-site를 입력하는 것이다. Name 필드에는 어떤 것이든 원하는 값을 입력할 수 있지만 Jigloo Update Site처럼 무슨 사이트인지 설명할 수 있는 내용이 좋을 것이다. OK를 클릭하면 Update Site 대화창으로 다시 이동하지만 이번에는 방금 입력한 업데이트 사이트가 목록에 포함되어 보일 것이다. Finish를 클릭하면 Search Results 대화창으로 이동한다. Search Results 대화창에서 Jigloo를 선택하고 Next를 클릭한다. 그럼 Feature License로 이동할 것이다.

이미 언급했던 것처럼 Jigloo는 무료로 사용할 수 있지만 상업적인 용도가 아닐 경우에만 그렇다. 만약 상용으로 사용할 것이라면 CloudGarden에서 전문가용 라이선스를 받아야 한다. 라이선스를 읽은 후 “I accept the terms in the license agreement”를 선택하여 라이선스에 동의한다. 그리고 나서 간단하게 Next를 클릭하면 Installation details 대화창으로 이동한다. Finish를 클릭하면 Feature Verification 대화창이 나온다. Install이나 Install All을 선택하면 된다. 그럼 이제 설치를 시작하게 된다. 이클립스는 CloudGarden에서 플러그인을 다운로드하고 설치할 것이다. 설치가 끝나면 이클립스를 재시작해야 설치 과정이 끝난다.

축하한다! 이제 Jigloo 설치가 끝났다. 다른 이클립스 플러그인들과 마찬가지로 전혀 어렵지 않았다. 이제 Jigloo를 시작할 준비가 끝났다. 간단한 설정부터 시작하자.




위로


Jigloo 설정하기

이클립스를 사용하여 새 자바 프로젝트를 생성한다. File > New > Project에서 Java Project를 클릭한다. Next를 클릭하여 New Project 창으로 이동한다.

이 튜토리얼에서 프로젝트의 이름은 “workflow”로 하겠다. 물론 여러분이 원하는 이름을 줄 수도 있다. 이름을 준 뒤 Finish를 클릭한다.

이미 언급했다시피, Jigloo를 사용해 스윙 또는 SWT GUI를 만들 수 있다. 이 튜토리얼에서 우리는 SWT GUI를 만들 것이다. 이 경우 약간의 추가 설정이 필요하다. SWT JAR 파일을 프로젝트의 클래스패스에 추가해야 한다. 이 작업을 하기 위해 프로젝트를 클릭하고 메뉴에서 File > Properties를 선택한다. 그럼 Project Properties 화면이 나타나고 여기서 왼쪽 네비게이션의 Java Build Path를 선택하여 Java Build Path 창으로 이동한다.

Libraries 탭을 클릭한 후 Add External JARs 버튼을 클릭한다. 그러면 file explorer 창이 뜬다. 아래 보이는 그림처럼 이클립스를 설치한 디렉터리인 $ECLIPSE_HOME의 하위 디렉터리인 $ECLIPSE_HOME/plug-ins로 이동한다.


그림 2. 이클립스 플러그인 디렉터리
이클립스 플러그인 디렉터리

여기서 org.eclipse.swt.X.X.X.jar를 볼 수 있을 것이다. X.X.X는 사용하는 플랫폼 종류와 설치한 이클립스 버전에 따라 다를 수 있다. Open을 클릭하고 Java Build Path 화면으로 이동하여 OK를 클릭한다.

기본적인 자바 프로젝트를 만들고 SWT 라이브러리를 클래스패스에 추가했다. 이제 Jigloo를 사용하여 워크플로우 애플리케이션 디자인과 개발을 시작할 준비가 끝났다.

워크플로우 애플리케이션

예제는 매우 간단한 워크플로우 애플리케이션이다. 두 종류의 사용자가 있는데 작업자와 관리자다. 작업자는 구매 요청을 입력할 때 이 애플리케이션을 사용한다. 작업자들은 구매 주문에 필요한 정보를 입력할 것이다. 그리고 입력한 모든 주문의 상태를 볼 수도 있어야 한다. 각각의 구매 주문은 세 가지(대기, 승인, 취소) 상태 중 한 상태여야 한다. 관리자에는 이 애플리케이션을 약간 다르게 사용한다. 관리자는 구매 주문을 대기 상태와 함께 볼 수 있어야 한다. 관리자는 구매 주문을 승인 또는 취소할 수 있어야 한다.

간단한 애플리케이션이므로 로그인이나 로그아웃은 신경 쓰지 않겠다. 대신 시스템의 모든 사용자 명단을 보여주고 그 중에 로그인할 사용자를 선택할 수 있도록 하겠다. 진짜 워크플로우 시스템에서는 동시성(concurrency)이 관건이다. 이것도 역시 예제 애플리케이션을 여러 시스템에서 실행하지 않을 것이기 때문에 고려하지 않겠다. 실제 워크플로우 시스템은 워크플로우 데이터를 관계형 데이터베이스 같은 공유 저장소에 영속성을 유지한다. 하지만 여기서는 최대한 단순하게 하기 위해 데이터를 XML 파일을 사용하여 영속성을 유지한다. JAXB를 사용하여 XML 형태로 데이터를 저장하고 읽을 것이다.

자, 이제 GUI를 만들기 위해 실제 코드를 작성해 보자.
<출처 :https://www.ibm.com/developerworks/kr/library/tutorial/os-eclipse-jigloo/section2.html>

반응형

SWT GUI를 사용한 워크플로우 애플리케이션 만들기

Jigloo는 자바(Java™) 플랫폼에서 실행되는 복잡한 그래픽 사용자 인터페이스(GUI)를 빠르게 만들 수 있도록 도와주는 이클립스 플러그인입니다. 이 플러그인을 사용하여 스윙(Swing) 기반 애플리케이션과 SWT(Standard Widget Toolkit) 기반 애플리케이션을 만들 수 있습니다. 사용하기 쉬운 비주얼 편집기이기 때문에 데스크톱용 애플리케이션 UI를 빨리 만들 수 있습니다. 이 튜토리얼에서는 간단한 워크플로우 애플리케이션을 만들고 그 UI를 만들기 위해 Jigloo를 사용합니다. Jigloo 사용이 얼마나 쉬운지 살펴볼 것이며 비주얼 상속과 같은 고급 기능도 살펴볼 것입니다. 마지막으로 애플리케이션을 테스트하고 다른 사람이 사용할 수 있도록 패키징하겠습니다.

시작하기 전에

이 튜토리얼의 목적은 데스크톱 애플리케이션을 만들기 원하는 자바 개발자들이 애플리케이션의 UI를 만들 때 Jigloo라는 이클립스 플러그인을 사용할 수 있도록 도와주는 것이다. 예제 애플리케이션은 XML, XML 스키마, JAXB와 자바 5 기능 중 어노테이션과 제네릭(Generic)를 사용한다.

이 튜토리얼에 대해

자바는 리치 데스크톱 애플리케이션을 만드는 데 뛰어난 플랫폼이다. 자바가 1995년 데뷔했을 때 AWT(Abstract Window Toolkit)이 들어있었다. AWT는 데스크톱 애플리케이션을 빌드하기 위해 자바의 첫 번째 UI 라이브러리였다. 1998년에 나온 JDK 1.2에는 스윙이 들어있었다. 스윙은 훨씬 개선된 툴킷이었다. 그 이후로 스윙에는 많은 개선이 있었다. 스윙은 이제 강력한 UI 라이브러리로 서로 다른 많은 플랫폼에서 잘 동작한다. SWT는 경쟁 UI 툴킷으로 많은 이점을 제공한다. 이제 Jigloo로 스윙이나 SWT를 타깃으로 하는 UI를 빠르게 빌드할 수 있다. 심지어 스윙 구성요소를 포함하는 SWT 애플리케이션을 빌드할 수 있다. 그러나 그 내용은 이 튜토리얼의 범위 밖이다.

이번 튜토리얼에서는 Jigloo를 사용하여 간단한 워크플로우 애플리케이션을 개발하는 방법에 대해 살펴보겠다. 이클립스 플러그인 Jigloo를 사용하여 애플리케이션의 UI를 만들겠다. 그러고 나서 애플리케이션을 빌드 하고 테스트한 뒤 다른 사람들이 사용할 수 있도록 패키징할 것이다.




위로


필요한 사전지식

이벤트 핸들러와 데이터 바인딩과 같은 UI 프로그래밍 개념에 익숙하다면 도움이 되지만 반드시 필요한 것은 아니다. AWT/스윙 또는 SWT를 사용해본 경험이 있으면 좋겠지만 역시 반드시 필요한 것은 아니다.

시스템 요구사항

이클립스 V3.2
Jigloo가 이클립스 플러그인이기 때문에 당연히 이클립스가 필요하다. 애플리케이션이 SWT를 사용할 것이기 때문에 이클립스와 함께 SWT 라이브러리 또한 필요하다.
Jigloo
Jigloo는 이클립스 플러그인이다. 이번 튜토리얼에서는 이클립스의 강력한 업데이트 관리자를 사용하여 이클립스에서 직접 Jigloo를 설치하는 법을 살펴보겠다.
자바 5+
이번 튜토리얼에서 다룰 애플리케이션에서는 어노테이션과 제네릭과 같은 자바 5의 기능들을 사용할 것이다. 자바 5 또는 자바 6을 다운로드해야 한다.
JAXB V2.0
본 튜토리얼에서 데이터를 저장하기 위한 형식으로는 XML을, XML을 파싱하고 직렬화할 때는 JAXB를 사용할 것이다. 자바 6을 사용하고 있다면 JAXB가 내장되어 있기 때문에 별다른 작업이 필요하지 않지만 자바 5를 사용하고 있다면 썬(Sun)의 JAXB 2.0 RI(Reference Implementation)를 참고할 필요가 있다.
<출처 : https://www.ibm.com/developerworks/kr/library/tutorial/os-eclipse-jigloo/section1.html>

+ Recent posts