Eclipse RCP 배포후 java소스내 한글이 깨지는 경우

 

이클립스 RCP 배포 시 소스코드를 재 빌드하는데 프로젝트 설정을 이용하여 빌드 하지 않고 자체적으로
시스템 디폴트 인코딩으로 소스파일을 컴파일 한다.

따라서 보통 윈도우의 경우 MS949로 되어 utf-8로 되어 있는 소스가 아래와 같이 모두 애러가 발생한다.

 

해결방법 : 이클립스 개발툴에 eclipse.ini에 vm 추가 

-vmargs
-Dfile.encoding=UTF-8

 

org.eclipse.equinox.p2.ui

'IT > RCP' 카테고리의 다른 글

[JFace] 뷰어와 뷰어 프레임 워크  (0) 2020.12.26
[RCP] RCP 기본생성 방법  (0) 2020.12.20
[RCP] 개발 환경설정  (0) 2020.12.20
[RCP] 사전 준비 및 주요 용어  (0) 2020.12.20
[SWT] 윈도우 레지스트리  (0) 2020.12.19

 

 

뷰어 프레임워크는 MVC(모델-뷰-컨트롤)로 알려진 디자인 패턴으로 구현된다.

Viewer의 하위 클래스인 ContentVier와 StructuredViewer가 있다.

 

ContentViewer는 다양한 인터페이스를 활용해서 도메인 객체 형태를 유지하면서 데이터를 다룬다. 

StructuredViewer는 ContentViewer에게 제공하는 데이터를 구조화 한다. 구조화는 필터링, 정렬 기능 같은 일반적인 작업을 실행하는 메도드들이 이 계층에서 구현된다.

 

각 위젯인 Tree, List, Table 등은 이에 맞는 Viewer의 하위 클래스로 ListViewer나 tableViewer 등이 있다.

 

ㅁ ContentViewer의 프로 바이더

   프로바이더에는 두 개가 존재한다. ContentProvider, LabelProvider

 

   ▶ LabelProvider,TableLabelProvider 보여줄 텍스트랑 이미지를 설정

   ▶ ContentProvider 레이블 프로바이더로 관여하기도 하지만 컨텐트 프로바이더로도 역할을 한다.

     레이블 프로바이더가 요소를 보이기 위한 텍스트이미지를 제공하는 반면에 컨텐츠 프로바이더는 실제적으로 요소를 보이게끔 해준다.

 

※ 내용정리 참고: https://wedul.site/70

 

JFace TreeViewer설명

Viewer Viewer는 MVC 패턴을 가지고 있다. Viewer의 하위 클래스인 ContentVier와 StructuredViewer가 있다. ContentViewer는 다양한 인터페이스를 활용해서 도메인 객체 형태를 유지하면서 데이터를 다룬다. 이들..

wedul.site

 

ㅁ TableViewer의 예제

   1) 일단 모델부터  

package com.dicws.mydays.model;

import java.util.ArrayList;
import java.util.List;

public class MyDaysModel {
	
	//모델요소
	String part;
	String title;
	String conetents;
	String writer;
	String wDate;

	//table모델시
	public MyDaysModel(String part, String title, String conetents, String writer, String wDate) {
        super();
        this.part = part;
        this.title = title;
        this.conetents = conetents;
        this.writer = writer;
        this.wDate = wDate;
    }

	/*Getter/Setter 정의*/
	public String getPart() {
		return part;
	}

	public void setPart(String part) {
		this.part = part;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getConetents() {
		return conetents;
	}

	public void setConetents(String conetents) {
		this.conetents = conetents;
	}

	public String getWriter() {
		return writer;
	}

	public void setWriter(String writer) {
		this.writer = writer;
	}

	public String getwDate() {
		return wDate;
	}

	public void setwDate(String wDate) {
		this.wDate = wDate;
	}
}

   2) 실행모듈정의 및 설명 

package com.dicws.mydays.test;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

import com.dicws.mydays.model.MyDaysModel;

public class TableSnippet extends ApplicationWindow {

	List<MyDaysModel> input = new ArrayList<MyDaysModel>();
	
	public TableSnippet() {
		super(null);
	}

	public void run() {
		// Don't return from open() until window closes
		setBlockOnOpen(true);
		// Open the main window
		open();
		// Dispose the display
		Display.getCurrent().dispose();
	}

	/**
	 * Configures the shell
	 * 
	 * @param shell
	 *            the shell
	 */
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		shell.setText("Team Tree");
	}

	/**
	 * Creates the main window's contents
	 * 
	 * @param parent
	 *            the main window
	 * @return Control
	 */
	protected Control createContents(Composite parent) {

		//table data 생성
		for (int i = 1; i < 10; i++) {
			input.add(new MyDaysModel("상환전화 i:" + i, "입금상환", "내용", "나야나1", "aa"));
		}

		TableViewer tableViewer = new TableViewer(parent, SWT.BORDER | SWT.FULL_SELECTION);
		Table table = tableViewer.getTable();
		
		/*
		 * Header Column 생성
		 */
		String[] COLUMN_HEADER = new String[]{"타이틀","제목","내용","작성자","작성일"};
		for(String header : COLUMN_HEADER ) {
			new TableColumn(tableViewer.getTable(), SWT.NONE).setText(header);
		}
		
		//table.layout(); // 레이아웃을 수동으로 갱신해야할 경우에 사용
		table.setLinesVisible(true);
		table.setHeaderVisible(true);
		tableViewer.setUseHashlookup(true);    // table 렌더링 속도 향상
		
		
        // Column Properties 지정 : ICellModifier 동작시 필수
        tableViewer.setColumnProperties(COLUMN_HEADER);
        tableViewer.setContentProvider(new IStructuredContentProvider() {
			
			@Override
			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
				// TODO 자동 생성된 메소드 스텁
			}
			
			@Override
			public void dispose() {
				// TODO 자동 생성된 메소드 스텁
			}
			
			@Override
			public Object[] getElements(Object inputElement) {
				return ((ArrayList<MyDaysModel>)input).toArray();
			}
		});
        
		tableViewer.setLabelProvider(new ITableLabelProvider() {
			
			@Override
			public void removeListener(ILabelProviderListener listener) {
				// TODO 자동 생성된 메소드 스텁
			}
			
			@Override
			public boolean isLabelProperty(Object element, String property) {
				// TODO 자동 생성된 메소드 스텁
				return false;
			}
			
			@Override
			public void dispose() {
				// TODO 자동 생성된 메소드 스텁
			}
			
			@Override
			public void addListener(ILabelProviderListener listener) {
				// TODO 자동 생성된 메소드 스텁
				
			}
			
			@Override
			public String getColumnText(Object element, int columnIndex) {
				MyDaysModel myDays = (MyDaysModel)element;
		        switch (columnIndex) {
		        case 0:
		            return myDays.getPart();
		        case 1:
		            return myDays.getTitle();
		        case 2:
		            return myDays.getConetents();
		        case 3:
		            return myDays.getWriter();
		        case 4:
		            return myDays.getwDate();
		        }
		        return "";
		    }
			
			@Override
			public Image getColumnImage(Object element, int columnIndex) {
				// TODO 자동 생성된 메소드 스텁
				return null;
			}
		});
		
		tableViewer.setInput(input);
		tableViewer.refresh();
		
		for (int i = 0, n = table.getColumnCount(); i < n; i++) {
		  table.getColumn(i).pack();
		}
		table.pack();
	
        /*
         * Cell Modify 기능추가
         */
//        // Column Properties 지정 : ICellModifier 동작시 필수
//        tableViewer.setColumnProperties(COLUMN_HEADER);
//        
//        // CellEditor 생성 
//        CellEditor[] CELL_EDITORS = new CellEditor[COLUMN_HEADER.length];
//        for(int i=0; i < CELL_EDITORS.length ; i++) {
//            CELL_EDITORS[i] = new TextCellEditor(tableViewer.getTable());
//            // or CheckboxCellEditor, ComboBoxCellEditor 등 사용
//        }        
//        tableViewer.setCellEditors(CELL_EDITORS);
        
		return table;
	}
	
	  /**
	   * The application entry point
	   * 
	   * @param args
	   *            the command line arguments
	   */
	  public static void main(String[] args) {
	    new TableSnippet().run();
	  }	

}

 

ㅁ TreeViewer의 예제

   1) 일단 모델부터  

package com.dicws.mydays.model;

import java.util.ArrayList;
import java.util.List;

public class MyDaysModel {
	
	
	String part;
	String title;
	String conetents;
	String writer;
	String wDate;
	
	//tree모델시
	public MyDaysModel parent; // 부모노드
	public List<MyDaysModel> child = new ArrayList(); // 자식노드
	public int counter;
	
	//tree모델시
	public MyDaysModel(int counter, MyDaysModel parent) {
        this.parent = parent;
        this.counter = counter;
    }
	
	//tree모델시 : 데이터만 set
	public void setTreeData(String part, String title, String conetents, String writer, String wDate) {
        
        this.part = part;
        this.title = title;
        this.conetents = conetents;
        this.writer = writer;
        this.wDate = wDate;
    }

    public String getPart() {
		return part;
	}

	public void setPart(String part) {
		this.part = part;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getConetents() {
		return conetents;
	}

	public void setConetents(String conetents) {
		this.conetents = conetents;
	}

	public String getWriter() {
		return writer;
	}

	public void setWriter(String writer) {
		this.writer = writer;
	}

	public String getwDate() {
		return wDate;
	}

	public void setwDate(String wDate) {
		this.wDate = wDate;
	}


}


   2) 실행모듈정의 및 설명 

package com.dicws.mydays.test;

import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;

import com.dicws.mydays.model.MyDaysModel;
import com.dicws.mydays.provider.MyDaysTreeContentProvider;
import com.dicws.mydays.provider.MyDaysTreeLblProvider;

public class TreeSnippet1 extends ApplicationWindow {

	MyDaysModel input;
	
	public TreeSnippet1() {
		super(null);
	}

	public void run() {
		// Don't return from open() until window closes
		setBlockOnOpen(true);
		// Open the main window
		open();
		// Dispose the display
		Display.getCurrent().dispose();
	}

	/**
	 * Configures the shell
	 * 
	 * @param shell
	 *            the shell
	 */
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		shell.setText("Team Tree");
	}

	/**
	 * Creates the main window's contents
	 * 
	 * @param parent
	 *            the main window
	 * @return Control
	 */
	protected Control createContents(Composite parent) {

		TreeViewer treeViewer = new TreeViewer(parent, SWT.BORDER);
		Tree tree = treeViewer.getTree();
		tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 6, 1));
		// tree.setLayout(new TreeColumnLayout());
		tree.setHeaderVisible(true);
		tree.setLinesVisible(true);

		treeViewer.setContentProvider(new ITreeContentProvider() {
			
			@Override
			public void inputChanged(Viewer viewer, Object obj, Object obj1) {
				// TODO 자동 생성된 메소드 스텁
				
			}
			
			@Override
			public void dispose() {
				// TODO 자동 생성된 메소드 스텁
				
			}
			
			@Override
			public boolean hasChildren(Object obj) {
				// TODO 자동 생성된 메소드 스텁
				return false;
			}
			
			@Override
			public Object getParent(Object obj) {
				// TODO 자동 생성된 메소드 스텁
				return null;
			}
			
			@Override
			public Object[] getElements(Object inputElement) {
				return ((MyDaysModel)inputElement).child.toArray();
			}
			
			@Override
			public Object[] getChildren(Object parentElement) {
				return getElements(parentElement);
			}
		});
		
		treeViewer.setLabelProvider(new ILabelProvider() {
			
			@Override
			public void removeListener(ILabelProviderListener ilabelproviderlistener) {
				// TODO 자동 생성된 메소드 스텁
				
			}
			
			@Override
			public boolean isLabelProperty(Object obj, String s) {
				// TODO 자동 생성된 메소드 스텁
				return false;
			}
			
			@Override
			public void dispose() {
				// TODO 자동 생성된 메소드 스텁
				
			}
			
			@Override
			public void addListener(ILabelProviderListener ilabelproviderlistener) {
				// TODO 자동 생성된 메소드 스텁
				
			}
			
			@Override
			public String getText(Object element) {
				return ((MyDaysModel)element).getPart();
			}
			
			@Override
			public Image getImage(Object obj) {
				// TODO 자동 생성된 메소드 스텁
				return null;
			}
		});

		TreeColumn column1 = new TreeColumn(tree, SWT.LEFT);
		column1.setText("Column 1");
		TreeColumn column2 = new TreeColumn(tree, SWT.LEFT);
		column2.setText("Column 1");

		setTree();
		treeViewer.setInput(input);
		treeViewer.refresh();
		
		
		for (int i = 0, n = tree.getColumnCount(); i < n; i++) {
			tree.getColumn(i).pack();
		}
		tree.pack();
		return treeViewer.getTree();
	}
	
	private void setTree() {

		// new LabelView();
		MyDaysModel root = new MyDaysModel(0, null);
		MyDaysModel tmp;
		for (int i = 1; i < 10; i++) {
			tmp = new MyDaysModel(i, root);
			tmp.setTreeData("상환전화 i:" + i, "입금상환", "내용", "나야나1", "aa");
			root.child.add(tmp);

			for (int j = 1; j < i; j++) {
				MyDaysModel tmp1 = new MyDaysModel(j, tmp);
				tmp1.setTreeData("상환전화 j:" + j, "입금상환", "내용", "나야나1", "aa");
				tmp.child.add(tmp1);
			}
		}

		input = root;

	}	

	/**
	 * The application entry point
	 * 
	 * @param args
	 *            the command line arguments
	 */
	public static void main(String[] args) {
		new TreeSnippet1().run();
	}

}

 

 

 

 

참고 사이트 : wiki.eclipse.org/JFaceSnippets#Snippet002_-_Tree_Viewer

 

JFaceSnippets - Eclipsepedia

JFace-Snippets are small and easy understandable programming examples of how to use the JFace API. To browse the examples, navigate to the examples GIT repository. Copy Paste The header section of each snippet is a link to the plain source. You can copy th

wiki.eclipse.org

참고 사이트 : www.java2s.com/Code/Java/SWT-JFace-Eclipse/CatalogSWT-JFace-Eclipse.htm

 

SWT JFace Eclipse « Java

java2s.com  | © Demo Source and Support. All rights reserved.

www.java2s.com

 

 

'IT > RCP' 카테고리의 다른 글

RCP 배포관련 문제  (0) 2022.12.26
[RCP] RCP 기본생성 방법  (0) 2020.12.20
[RCP] 개발 환경설정  (0) 2020.12.20
[RCP] 사전 준비 및 주요 용어  (0) 2020.12.20
[SWT] 윈도우 레지스트리  (0) 2020.12.19

프로젝트 새로 만들기

플러그인 프로젝트 선택
프로젝트 이름 및 플러그인실행대상 선택
기본 자바 실행버전(좀 낮게), UI 제공, RCP응용프로그램 작성여부 Yes
RCP 기본 템플릿 선택(3.x로 시작)
패키지 기본설정
RCP 기본템플릿 실행(plugin.xml선택, 개요탭에 Eclipse응용프로그램 실행)

ㅁ 기본구조 확인

기본적으로 RCP프로젝트를 생성하면 아래와 같은 기본 클래스들이 생긴다. 이 클래스들은 RCP프로그램에서 각자의 역할이 있으며, 구성하고있는 역할을 알고 있어면 훗날 개발을 진행할 때 진행이 수월하다.

  • Application

    RCP프로그램의 main routine으로 동작 및 프로그램의 컨트롤러 역할을 한다. 또한 Workbench와 다른 Workbench Advisor라고 불리는 다른 클래스들을 연결시키는 역할한다. 이때 Workbench는 프로그램 하나를 말한다. Workbench는 Worbench Window을 포괄하는 개념이며, 예를 들어 새로운 이클립스창이 띄워졌을때 New window를 하면 하나의 창이 더 띄워진다. 이때 각각의 창은 Workbench Window이고, 2개가 존재한다. 하지만 Workbench는 창이 늘어나도 하나로 존재하게된다.

  • WorkbenchAdvisor

    Workbench의 lifecycle에 대해 명시하고 있다. default perspective와 같은 중요한 파라미터들을 Workbench에 제공한다. 가장 중요한 점은 WorkbenchAdvisor의 메소드들은 오버라이드가 될 수 없다.

  • WorbenchWindowAdvisor

    상태 line, 툴바. 제목. 윈도우 사이즈 등 커스터마이즈 하길 원하는 것들이 들어간다.

  • Perspective

    view, editor, menu들의 위치와 사이즈를 갖고있음 적어도 하나의 perspective는 가지고 있어야 한다.

  • View

    화면을 담당하는 부분이다. 곧, 뷰어들을 생성하고 초기화를 진행한다. 화면을 Viewer의 컨트롤에 요청하는 setFocus()와 모든 구성 요소들을 활성화하는 CreatePartControl(Composite) 함수가 반드시 필요하다. 이 두 함수는 처음 실행될때 호출된다. setFocus() createPartControl(Composite)는 시키기 위해 선언하는 곳이다

 

10가지의 플러그인 중 큰 몇가지만 설명하고자 한다.

  • UI Workbench: UI Workbench는 editor, view, perspective 등을 포함하고 있다.
  • SWT: 운영체제의 네이티브 윈도우 환경과 긴밀하게 통합된 다양한 컴포넌트와 플랫폼 독립적인 API를 제공한다. 즉, 윈도우에서 정의한 위젯에 대한 접근을 제공한다.
  • JFACE: 범용 UI 개념을 위한 구조와 편의기능을 제공한다. SWT를 이용하여 사용자 인터페이스를 개발할 때 해야하는 많은 공통 작업들을 간단하게 해 주는 컴포넌트와 헬퍼 유틸리티 세트를 제공 데이터 뷰, 위저드, 다이얼로그 컴포넌트 등을 제공하기 위해 SWT를 확장하는 많은 유틸리티 클래스들을 포함하고 있다.
  • RUNTIME: 플러그인과 페이지 로딩 및 초기화 간에 확장 포인트 모델 기반의 느슨한 결합을 정의하고 있다.
  • OSGi: 이클립스에서 플러그인의 발견 및 애플리케이션의 재시작 없이 플러그인을 로딩 및 언로딩하는 것을 포함하여 플러그인의 라이프사이클 관리등을 위한 프레임워크이다.

※ (참고)워크벤치 어드바이저 생명주기



ㅁ RCP관련 참고 사이트 들

    www.eclipse.org/articles/

 

Eclipse Corner - Eclipsepedia

These following articles have been written by members of the various project development teams and other members of the Eclipse community. Eclipse setup instructions on a new Linux (or other OS) computer Getting started with Eclipse as a beginner is diffic

wiki.eclipse.org

    o7planning.org/en/10953/eclipse-rcp

 

Eclipse RCP

The small examples The small examples No examples

o7planning.org

    www.vogella.com/tutorials/eclipse.html

 

Eclipse, RCP, Plugin and OSGi Development

 

www.vogella.com

 

'IT > RCP' 카테고리의 다른 글

RCP 배포관련 문제  (0) 2022.12.26
[JFace] 뷰어와 뷰어 프레임 워크  (0) 2020.12.26
[RCP] 개발 환경설정  (0) 2020.12.20
[RCP] 사전 준비 및 주요 용어  (0) 2020.12.20
[SWT] 윈도우 레지스트리  (0) 2020.12.19

개발을 하기위해서는 SWT -> JFace -> RCP 순으로 되어 있는데,  환경설정구성에서는 RCP가 JFace, SWT를 포함하고 있기 때문에 RCP환경만 설정하면 모두 사용이 가능하다.(RCP환경설정으로 모두 사용가능)

 

RCP환경설정에 앞서 이클립스는 2000년도부터 무수히 많은 버전을 만들어왔는데 문제는 버전별로 처리 가능한지 하기 위해 이중구성(IDE 환경과 RCP환경) 

 

흔하게 Java를 개발하기 위해서 보통 IDE통합환경을 보통 다운을 받아 설치한다.

ㅁ Target 설정

    1) Java Project 추가 : 이름은 (임의)RCP_Indigo_Target

 

구버전 Indigo RCP환경

※ 현재 어느 플랫폼으로 선택되어 있는지 확인이 가능 

 

필요에 따라 환경을 변경하면 됨

IDE 통합툴이지만 RCP플랫폼의 요소들을 가져와 설정되었기 때문에 SWT, Jface, RCP환경이 이거 하나로 됨

 

ㅁ 참고로 이클립스 명칭별 버전 확인

배포판

배포일

플랫폼 버전

프로젝트명

참여 프로젝트

의미

Photon

2018 6 27

4.8

광양자

Oxygen

2017 6 28

4.7

Oxygen projects

산소(O2)

Neon

2016 6 22

4.6

Neon projects

네온(Ne), 그리스어로 새롭다를 뜻하는 'neos'를 어원

Mars

2015 6 24

4.5

Mars projects

79

화성(라틴어)

Luna

2014 6 25

4.4

Luna projects

76

(라틴어)

Kepler

2013 6 26

4.3

Kepler projects

미정

케플러(천문학자)

Juno

2012 6 27

4.2

Juno projects

미정

주노(로마신화에서 피터의 누이이자 아내)

Indigo

2011 6 22

3.7

Indigo projects

62

남색(H의 다음문자)

Helios

2010 6 23

3.6

Helios projects

39

태양신

Galileo

2009 6 24

3.5

Galileo projects

33

목성 4대 위성의 발견자명

Ganymede

2008 6 25

3.4

Ganymede projects

23

목성의 4대 위성 중 하나로 태양계 최대의 위성

Europa

2007 6 29

3.3

Europa projects

20

목성의 4대 위성 중 하나

Callisto

2006 6 30

3.2

Callisto projects

10

목성의 4대 위성 중 하나

Eclipse 3.1

2005 6 28

3.1

Eclipse 3.0

2004 6 21

3.0



※ 참고 : ko.wikipedia.org/wiki/%EC%9D%B4%ED%81%B4%EB%A6%BD%EC%8A%A4_(%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4)

 

ㅁ 구방식 SWT하나만 추가 방법

    참고 : dicws.tistory.com/118

 

[SWT] SWT만 설치사용(구방식)

ㅁ SWT 다운로드 과거에는 바로 swt.jar만 가져올 수 있게 했는데, 여러단계를 거쳐야 들어갈 수 있게 되어 있다 먼저 SWT사이트를 접속해보자: http://www.eclipse.org/swt/ 클릭하면 맨위에 이클립스는 swt

dicws.tistory.com

 

'IT > RCP' 카테고리의 다른 글

[JFace] 뷰어와 뷰어 프레임 워크  (0) 2020.12.26
[RCP] RCP 기본생성 방법  (0) 2020.12.20
[RCP] 사전 준비 및 주요 용어  (0) 2020.12.20
[SWT] 윈도우 레지스트리  (0) 2020.12.19
[SWT] Win32 OLE  (0) 2020.12.19

클립스는 개발툴로 매우 좋은 도구라 생각되어진다. 대규모 프로젝트시 현존하는 개발툴은

거의 이클립스 기반으로 이루어져 있다해도 과언이 아니라 생각되어진다.

이에 이클립스를 잘사용하는 방법말고 추가 나만의 도구를 개발하여 더욱더 좋은 빠른 개발을 하고자 정리하게 되었고 이에 정리과정을 한번 다시 적어볼까 합니다.

총 3개의 단개로 진행됩니다.

       SWT(Standard Widget Toolkit)->JFace(모델기반)->RCP(Platform)

궁극적 목적은 RCP(Rich Client Platform)으로 이클립스에 추가 도구를 만들기 위함으로 진행해보고자 합니다.

 SWT는 각 컴포넌트를 기본적으로 사용할줄 아는게 목적이고,  이를 JFace를 통하여 모델화시키고 RCP 플렛폼을 만들어 이클립스의 도구 또는 Stand-Alone 프로그램을 구현하고자 합니다.

 

ㅁ RCP 화면구성 

퍼스펙티브 : 일종에 작업책상으로 보면 된다. 여러 작업공간분리 하려고 한다.

                   예를 들면 C프로그램작성, 데이터베이스용, Java, PHP 등등 작업공간

-  : 특정 목적으로 처리할수 있는 공구라 생각하면 된다.

       예를 들면 파일목록을 보는 파일관리자, 프로젝트를 관리하는 프로젝트 관리자 기타 특성, 콘솔 등등이 다 사용할 수 있는 공구라 생각하면 된다.

 - 에디터 : 실제 뭔가를 작업하고 처리하는 부분이라 생각하면 된다. 주로 메인작업을 하는 공간

'IT > RCP' 카테고리의 다른 글

[RCP] RCP 기본생성 방법  (0) 2020.12.20
[RCP] 개발 환경설정  (0) 2020.12.20
[SWT] 윈도우 레지스트리  (0) 2020.12.19
[SWT] Win32 OLE  (0) 2020.12.19
[SWT] 클립보드  (0) 2020.12.19

레지스트 간단예제

package swt.registry;

import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

public class RegistryUserTest {
	// 주어진 노드에 키를 포함하고 있는지 체크한다.
	public static boolean contains(Preferences node, String key) {
		return node.get(key, null) != null;
	}

	public static void main(String args[]) throws BackingStoreException {
		
		Preferences userRootPrefs = Preferences.userRoot();
		//레지스트리에 시스템 Root못건드림 Preferences systemRootPrefs = Preferences.systemRoot();
		
		String key = "xname";
		if (contains(userRootPrefs, key)) {
			String value = userRootPrefs.get(key, "");	//있으면 있는거 출력
			System.out.println("xname : " + value);
		} else {
			String value = "upark";
			userRootPrefs.put(key, value);	//없으면 만들어 set
			System.out.println("create uname : " + value);
		}
	}
}

HKEY_CLASSES_ROOT레지스트리에 http\\shell\\open\\command  에 보면 default 브라우저 설정

package swt.registry;

import java.util.Enumeration;

import com.ice.jni.registry.NoSuchValueException;
import com.ice.jni.registry.RegStringValue;
import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryException;
import com.ice.jni.registry.RegistryKey;

public class JNIRegistryTest {
	private static final String REG_SWT_PARAMS = "Software\\RnDClub\\Client\\Params";

	public static final String REG_AMS_KEY_CLASSNAME = "AMS";

	public static final String REG_AMS_KEY_ID = "id";

	public static final String REG_AMS_KEY_DIR_HOME = "home";

	public static final String REG_AMS_KEY_DB_DRIVER = "dbDriver";

	public static final String REG_AMS_KEY_DB_URL = "dbUrl";

	public static final String REG_AMS_KEY_DB_USER = "dbUser";

	public static final String REG_AMS_KEY_DB_PASS = "dbPass";

	private static RegistryKey amsClientParamsRkey = null;

	public static String getDefaultBrowserCommand() {
		String value = null;
		String name = "http\\shell\\open\\command";
		try {
			RegistryKey rkey = Registry.HKEY_CLASSES_ROOT.createSubKey(name,
					"", RegistryKey.ACCESS_ALL);
			// System.out.println("rkey : " + rkey);
			value = rkey.getStringValue("");
		} catch (RegistryException e) {
			e.printStackTrace();
		}
		return (value);
	}

	public static RegistryKey getCurrentUserRegistryKey(String name) {
		RegistryKey rkey = null;
		try {
			rkey = Registry.HKEY_CURRENT_USER.createSubKey(name,
					"", RegistryKey.ACCESS_ALL);
			if (rkey.wasCreated() == true) {
				System.out.println("'" + name + "' rkey was created...");
			}
		} catch (RegistryException e) {
			e.printStackTrace();
		}
		return (rkey);
	}

	public static String getAmsClientParameter(String name) {
		String value = null;
		try {
			if (amsClientParamsRkey == null) {
				amsClientParamsRkey = getCurrentUserRegistryKey(REG_SWT_PARAMS);
			}
			value = amsClientParamsRkey.getStringValue(name);
		} catch (RegistryException e) {
			e.printStackTrace();
		}
		return (value);
	}

	public static void putAmsClientParameter(String name, String str) {
		try {
			if (amsClientParamsRkey == null) {
				amsClientParamsRkey = getCurrentUserRegistryKey(REG_SWT_PARAMS);
			}
			RegStringValue value = new RegStringValue(amsClientParamsRkey,
					name, str);
			amsClientParamsRkey.setValue(name, value);
		} catch (NoSuchValueException e) {
			e.printStackTrace();
		} catch (RegistryException e) {
			e.printStackTrace();
		}
	}

	public static void test() {
		try {
			if (amsClientParamsRkey == null) {
				amsClientParamsRkey = getCurrentUserRegistryKey(REG_SWT_PARAMS);
			}
			System.out.println("getFullName : "
					+ amsClientParamsRkey.getFullName());
			System.out.println("getMaxSubkeyLength : "
					+ amsClientParamsRkey.getMaxSubkeyLength());
			System.out.println("getMaxValueDataLength : "
					+ amsClientParamsRkey.getMaxValueDataLength());
			System.out.println("getMaxValueNameLength : "
					+ amsClientParamsRkey.getMaxValueNameLength());
			System.out.println("getName : " + amsClientParamsRkey.getName());
			System.out.println("getNumberSubkeys : "
					+ amsClientParamsRkey.getNumberSubkeys());
			System.out.println("getNumberValues : "
					+ amsClientParamsRkey.getNumberValues());

			Enumeration e = amsClientParamsRkey.valueElements();
			while (e.hasMoreElements()) {
				String key = (String) e.nextElement();
				String val = amsClientParamsRkey.getStringValue(key);
				System.out.println("key : " + key + ", val : " + val);
			}
			/*
			 * System.out.println(); for (int i = 0; i <
			 * amsClientParamsRkey.getNumberValues(); i++) { String key =
			 * amsClientParamsRkey.regEnumValue(i); String val =
			 * amsClientParamsRkey.getStringValue(key); System.out.println("[" +
			 * i + "] key : " + key + ", val : " + val); }
			 */
		} catch (RegistryException e) {
			e.printStackTrace();
		}
	}

	public static void main(String args[]) {
		test();

		putAmsClientParameter("server", "127.0.0.1");
		String value = getAmsClientParameter("server");
		System.out.println("server : " + value);

		putAmsClientParameter("dbUrl",
				"jdbc:oracle:thin:@127.0.0.1:1521:opendb");
		value = getAmsClientParameter("dbUrl");
		System.out.println("dbUrl : " + value);

		putAmsClientParameter("workspace", "D:\\workspace");
		value = getAmsClientParameter("workspace");
		System.out.println("workspace : " + value);

		putAmsClientParameter("home", "D:\\Temp\\ams_client");
		value = getAmsClientParameter("home");
		System.out.println("home : " + value);

		putAmsClientParameter("id", "ywoopark");
		value = getAmsClientParameter("id");
		System.out.println("id : " + value);

		value = getDefaultBrowserCommand();
		System.out.println("ie : " + value);
	}
}

위 경우는 현재 32bit만 가능하며 32bit인경우 registry.jar,ICE_JNIRegistry.dll 가 필요하며

registry.jar에 Native에 ICE_JNIRegistry.dll를 추가 설정해주어야 가능하다.

'IT > RCP' 카테고리의 다른 글

[RCP] 개발 환경설정  (0) 2020.12.20
[RCP] 사전 준비 및 주요 용어  (0) 2020.12.20
[SWT] Win32 OLE  (0) 2020.12.19
[SWT] 클립보드  (0) 2020.12.19
[SWT] Drag & Drop  (0) 2020.12.19

이클립스에서 OLEFrame으로 OLE객체를 내장할 수 있다.

여기서 OLE란 Object Link Editer로 MS의 OCX, ActiveX 컨트롤를 말한다.

먼저 주요클래스를 확인하여 보자

 

[Win32 주요 클래스]

객체를 생성하는 방법, 그리고 객체를 사용하는 방법을 알아보자

먼저 간단하게 MS워드, 익스플로러, 엑셀, 미디어플레이어 을 띄우는 방법을 알아보자

참고로 oleviewer라고 Visual Studio에서 나온것이 있는데, OLE를 사용하기 위한 API문서처럼 메소드들을 제공한다.

oleview_setup&amp;dll.zip
0.66MB

OLE를 사용하기에 위해 주요클래스 중 몇가지를 살펴보자

OleClientSite : OLE 도큐먼트를 관리하기위함.
  -편집기 생성, 토큐먼트 활성/비활성, 변경내용저장
 OleControlSite : OleClientSite의 상속받아 액티브X컨트롤를 관리
  -컨트롤 이벤트 제공, 변경되었음을 제공, 폰트 배경색 등 변경가능
 OleAutomation : IDispatch 인터페이스 지원,메소드 사용(매개변수는 Variant형태 전달)
   setProperty
   invoke 
   invokeNoReply  

OLE를 사용하여 객체 생성예제

package swt.ole;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.ole.win32.OLE;
import org.eclipse.swt.ole.win32.OleClientSite;
import org.eclipse.swt.ole.win32.OleFrame;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class OLE_Test {

	public static void main(String[] args) {
		
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setLayout(new FillLayout());
		shell.setText("SWT Ole Test");
		OleClientSite clientSite;
		//OleControlSite oleControlSite;
		OleFrame frame = new OleFrame(shell, SWT.NONE);
		clientSite = new OleClientSite(frame, SWT.NONE,"Word.Document");
		clientSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
		//각 OLE객체를 생성하는 방법1~4
		/*
		//1.1 MS Word 띄우기:OLE객체 -ProgramID
		clientSite = new OleClientSite(frame, SWT.NONE,"Word.Document");
		*/
		/*
		//1.2 MS Word 띄우기-MS워드파일로 띄우기 
		clientSite = new OleClientSite(frame, SWT.NONE,new File("d:\\test.doc"));
		*/
		/*
		//2.MS Excel 띄우기-ProgramID
		clientSite = new OleClientSite(frame, SWT.NONE,"Excel.Sheet");
		*/
		/*
		//3.익스플로러 띄우기-ProgramID
		clientSite = new OleClientSite(frame, SWT.NONE,"Shell.Explorer");
		*/
		//4.미디어 플레이어 띄우기
		//clientSite = new OleClientSite(frame, SWT.NONE,"WMPlayer.OCX");
		
		System.out.println("clientSite : " + clientSite.getProgramID());
		
		shell.setSize(640, 480);
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		
		//oleAuto.dispose();
		display.dispose();
	}
}

여기서 주석으로 각각 막아 놓은것은 주요 OLE객체에 임. 1.2에서 파일을 통하여 OLE객체를 생성할 수도 있다.

파일을 통해 OLE객체를 생성한경우 객체에 ProgID를 추가적으로 알수 있다.

clientSite.getProgramID()

 

그럼 OLE객체의 메소드, Property등을 oleview.exe외 자바에서 추출하는 예제를 확인해보자

OleControlSite를 통하여 메소드들을 알수 있다.(너무 많아 자세히 보기 어렵긴하네요)

package swt.ole;

import java.io.File;

import org.eclipse.swt.SWT;
import org.eclipse.swt.internal.ole.win32.TYPEATTR;
import org.eclipse.swt.ole.win32.OLE;
import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.OleClientSite;
import org.eclipse.swt.ole.win32.OleControlSite;
import org.eclipse.swt.ole.win32.OleFrame;
import org.eclipse.swt.ole.win32.OleFunctionDescription;
import org.eclipse.swt.ole.win32.OlePropertyDescription;
import org.eclipse.swt.widgets.Shell;

public class getOLEMethod {

	public static void main(String[] args) {
		/*
		 * if (args.length == 0) { System.out.println("Usage: java Main "); return; }
		 */
		Shell shell = new Shell();

		OleFrame frame = new OleFrame(shell, SWT.NONE);
		OleClientSite oleControlSite = new OleClientSite(frame, SWT.NONE, new File("d:\\test.doc"));
		String progID = oleControlSite.getProgramID();

		// 컨트롤은 프로그램 id를 통하여만 가져올수 있다.
		OleControlSite site = new OleControlSite(frame, SWT.NONE, progID);
		OleAutomation auto = new OleAutomation(site); // 각 메소드의 사용

		TYPEATTR typeattr = auto.getTypeInfoAttributes();

		if (typeattr != null) {

			// function기술시작
			if (typeattr.cFuncs > 0) {
				System.out.println("Functions for " + progID + ":");
			}
			
			for (int i = 0; i < typeattr.cFuncs; i++) {
				
				OleFunctionDescription data = auto.getFunctionDescription(i);
				String argList = "";
				
				int firstOptionalArgIndex = data.args.length - data.optionalArgCount;
				
				for (int j = 0; j < data.args.length; j++) {
					argList += "[";
					//옵션 항목기술
					if (j >= firstOptionalArgIndex) {
						argList += "optional, ";
					}
					//function항목명, type기술
					argList += getDirection(data.args[j].flags) + "] " + getTypeName(data.args[j].type) + " "
							+ data.args[j].name;
					//다음항목 , 표시
					if (j < data.args.length - 1) {
						argList += ", ";
					}
				}
				
				System.out.println(getInvokeKind(data.invokeKind) + " (id = " + data.id + ") : " + "Signature : "
						+ getTypeName(data.returnType) + " " + data.name + "(" + argList + ")" + " Description : "
						+ data.documentation + "Help File : " + data.helpFile + "");
			}

			//속성값 기술 시작
			if (typeattr.cVars > 0) {
				System.out.println(" ");
				System.out.println(" Variables for " + progID + " : ");
			}
			
			//속성값 기술목록출력
			for (int i = 0; i < typeattr.cVars; i++) {
				OlePropertyDescription data = auto.getPropertyDescription(i);
				System.out.println("PROPERTY (id = " + data.id + ") :" + "Name : " + data.name + "Type : "
													 + getTypeName(data.type) + "");
			}
		}

		auto.dispose();
		shell.dispose();
	}

	private static String getTypeName(int type) {
		switch (type) {
		case OLE.VT_BOOL:
			return "boolean";
		case OLE.VT_R4:
			return "float";
		case OLE.VT_R8:
			return "double";
		case OLE.VT_I4:
			return "int";
		case OLE.VT_DISPATCH:
			return "IDispatch";
		case OLE.VT_UNKNOWN:
			return "IUnknown";
		case OLE.VT_I2:
			return "short";
		case OLE.VT_BSTR:
			return "String";
		case OLE.VT_VARIANT:
			return "Variant";
		case OLE.VT_CY:
			return "Currency";
		case OLE.VT_DATE:
			return "Date";
		case OLE.VT_UI1:
			return "unsigned char";
		case OLE.VT_UI4:
			return "unsigned int";
		case OLE.VT_USERDEFINED:
			return "UserDefined";
		case OLE.VT_HRESULT:
			return "int";
		case OLE.VT_VOID:
			return "void";

		case OLE.VT_BYREF | OLE.VT_BOOL:
			return "boolean *";
		case OLE.VT_BYREF | OLE.VT_R4:
			return "float *";
		case OLE.VT_BYREF | OLE.VT_R8:
			return "double *";
		case OLE.VT_BYREF | OLE.VT_I4:
			return "int *";
		case OLE.VT_BYREF | OLE.VT_DISPATCH:
			return "IDispatch *";
		case OLE.VT_BYREF | OLE.VT_UNKNOWN:
			return "IUnknown *";
		case OLE.VT_BYREF | OLE.VT_I2:
			return "short *";
		case OLE.VT_BYREF | OLE.VT_BSTR:
			return "String *";
		case OLE.VT_BYREF | OLE.VT_VARIANT:
			return "Variant *";
		case OLE.VT_BYREF | OLE.VT_CY:
			return "Currency *";
		case OLE.VT_BYREF | OLE.VT_DATE:
			return "Date *";
		case OLE.VT_BYREF | OLE.VT_UI1:
			return "unsigned char *";
		case OLE.VT_BYREF | OLE.VT_UI4:
			return "unsigned int *";
		case OLE.VT_BYREF | OLE.VT_USERDEFINED:
			return "UserDefined *";
		}
		return "unknown " + type;
	}

	private static String getDirection(int direction) {
		String dirString = "";
		boolean comma = false;
		if ((direction & OLE.IDLFLAG_FIN) != 0) {
			dirString += "in";
			comma = true;
		}
		if ((direction & OLE.IDLFLAG_FOUT) != 0) {
			if (comma)
				dirString += ", ";
			dirString += "out";
			comma = true;
		}
		if ((direction & OLE.IDLFLAG_FLCID) != 0) {
			if (comma)
				dirString += ", ";
			dirString += "lcid";
			comma = true;
		}
		if ((direction & OLE.IDLFLAG_FRETVAL) != 0) {
			if (comma)
				dirString += ", ";
			dirString += "retval";
		}

		return dirString;
	}

	private static String getInvokeKind(int invKind) {
		switch (invKind) {
		case OLE.INVOKE_FUNC:
			return "METHOD";
		case OLE.INVOKE_PROPERTYGET:
			return "PROPERTY GET";
		case OLE.INVOKE_PROPERTYPUT:
			return "PROPERTY PUT";
		case OLE.INVOKE_PROPERTYPUTREF:
			return "PROPERTY PUT BY REF";
		}
		return "unknown " + invKind;
	}
}

MS워드의 경우 OLEVIEW를 가지고 한번 메소드를 찾긴 했는데 찾는데 어려운듯

그럼 이걸가지고 특정파일을 열게 실행을 해보겠습니다.

'IT > RCP' 카테고리의 다른 글

[RCP] 사전 준비 및 주요 용어  (0) 2020.12.20
[SWT] 윈도우 레지스트리  (0) 2020.12.19
[SWT] 클립보드  (0) 2020.12.19
[SWT] Drag & Drop  (0) 2020.12.19
[SWT] 다이얼로그  (0) 2020.12.19

윈도우에서 흔히 사용하고 있는 클립보드를 예제를 보자

copy, paste, query(클립보드 내용및 분류)

package swt.clipboard;

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class CopyAndPasteWithClipboard {
	
	Display display = null;
	Shell shell = null;
	Text text = null;
	Button copy = null;
	Button paste = null;
	Button clear = null;
	Button query = null;
	Clipboard cb = null;

	//Main시작
	public static void main(String[] args) {
		CopyAndPasteWithClipboard app = new CopyAndPasteWithClipboard();
		app.run();
	}	

	//run에서 화면 실행
	public void run() {
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}	
	
	public CopyAndPasteWithClipboard() {
		createUI();		//ui선언
		doLayout();		//layout
		addListener();	//이벤트 처리
	}

	public void createUI() {
		display = new Display();
		cb = new Clipboard(display);
		shell = new Shell(display);
		shell.setText("SWT Clipboard Test");

		text = new Text(shell, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL
				| SWT.H_SCROLL);

		copy = new Button(shell, SWT.PUSH);
		copy.setText("Copy");

		paste = new Button(shell, SWT.PUSH);
		paste.setText("Paste");

		clear = new Button(shell, SWT.PUSH);
		clear.setText("Clear");

		query = new Button(shell, SWT.PUSH);
		query.setText("Query");
	}

	public void doLayout() {
		shell.setLayout(new FormLayout());

		FormData data = new FormData();
		data.right = new FormAttachment(100, -5);
		data.top = new FormAttachment(0, 5);
		copy.setLayoutData(data);

		data = new FormData();
		data.right = new FormAttachment(100, -5);
		data.top = new FormAttachment(copy, 5);
		paste.setLayoutData(data);

		data = new FormData();
		data.right = new FormAttachment(100, -5);
		data.top = new FormAttachment(paste, 5);
		clear.setLayoutData(data);

		data = new FormData();
		data.right = new FormAttachment(100, -5);
		data.top = new FormAttachment(clear, 5);
		query.setLayoutData(data);

		data = new FormData();
		data.left = new FormAttachment(0, 5);
		data.top = new FormAttachment(0, 5);
		data.right = new FormAttachment(copy, -5);
		data.bottom = new FormAttachment(100, -5);
		text.setLayoutData(data);

		shell.setSize(320, 240);
	}

	public void addListener() {
		copy.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				String textData = text.getSelectionText();
				if ((textData != null) && (!"".equals(textData))) {
					TextTransfer textTransfer = TextTransfer.getInstance();
					cb.setContents(new Object[]{textData},
							new Transfer[]{textTransfer});
				}
			}
		});
		paste.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				TextTransfer transfer = TextTransfer.getInstance();
				String data = (String) cb.getContents(transfer);
				if (data != null) {
					text.insert(data);
				}
			}
		});
		clear.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				cb.clearContents();
			}
		});
		query.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				String names[] = cb.getAvailableTypeNames();
				text.insert("\n----------------------\n");
				for (int i = 0; (names != null) && (i < names.length); i++) {
					text.insert("names[" + i + "] : " + names[i] + "\n");
				}
				text.insert("----------------------\n");
			}
		});
	}

	public void dispose() {
		if (cb != null) {
			cb.dispose();
		}
		if (display != null) {
			display.dispose();
		}
	}
	

}

하나 중점으로 하나 볼것은 copy할때 Transfer 객체를 통하여 clipboard를 copy됨을 보면

앞전에 Drag&Drop과 같은 방식임을 알수 있다.

'IT > RCP' 카테고리의 다른 글

[SWT] 윈도우 레지스트리  (0) 2020.12.19
[SWT] Win32 OLE  (0) 2020.12.19
[SWT] Drag & Drop  (0) 2020.12.19
[SWT] 다이얼로그  (0) 2020.12.19
[SWT] Layout  (0) 2020.12.19

    드레그 와 드롭은 일상에서 많이 사용하고 있다. 근데 개발툴에서는 많이 사용하지 않았지만 앞으로 개발툴도 이러한 기능으로 소스코딩양을 줄여주는것이 좋을것 같다.

이기능은 사용하려면 드래그 하는 곳과 드롭하는 곳에 상호작용 및 순서가 필요하다.

    드래그소스->드롭타깃->드롭효과 ->트랜스

먼저 드레그 클래스 계층도를 살펴보자

ㅁ 드레그 소스

     드레그 소스에는 여러가지 형태가 있을수 있다

     가령 text, file, 워드와 같이 특정 문자에 색이나 강조등의 효과를 가지고 있는 RTP 형식 문서등이 있다.

여기서는 해당소스가 명칭을 TextTransfer, FileTransfer,HTML Transfer,RTF Transfer 라 하고 각

instance를 생성 전달하게 된다.

 여기서 간단한 예제로 Label에 소스를 드레그해서 이클립스 java editer에 드롭하면 move되는 소스를 참고 하여보자

package swt.drag_drop;

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class DragSourceTest {
	
	public static void main(String[] args) {
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setLayout(new FillLayout());
		shell.setText("SWT DragSource Test");

		// 레이블 위젯을 드래그 원본(Drag Source)으로 활성화 한다.
		final Label label = new Label(shell, SWT.BORDER);
		label.setText("text to be transferred");


		int operations = DND.DROP_MOVE | DND.DROP_COPY;
		DragSource source = new DragSource(label, operations);

		// 텍스트 포맷 내에 데이터를 제공한다.
		Transfer[] types = new Transfer[]{TextTransfer.getInstance()};
		source.setTransfer(types);

		source.addDragListener(new DragSourceListener() {
			public void dragStart(DragSourceEvent event) {
				// 레이블 내에 실제 텍스트가 있을 경우에만, 드래그를 시작한다.
				if (label.getText().length() == 0) {
					event.doit = false;
				}
			}

			public void dragSetData(DragSourceEvent event) {
				// 요청된 타입의 데이터를 제공한다.
				if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
					event.data = label.getText();
				}
			}

			public void dragFinished(DragSourceEvent event) {
				// 만약, 데이터의 이동(MOVE) 작업이 수행되었다면,
				// 드래그 원본인 레이블 위젯에서 이동한 데이터를 제거한다.
				if (event.detail == DND.DROP_MOVE) {
					 label.setText("");
				}
			}
		});

		shell.setSize(640, 480);
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}
}

구현시 처리되는 동영상을 참고하세요

Drag 처리

 

ㅁ 드롭 타겟

   다음은 드롭소스를 예제로 생성해 보았다 반대로 드레그는 이클립스에 자바소스에서 드롭은 개발된 소스에서 받는걸로 예제를 처리했다.

package swt.drag_drop;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class DropTargetCopyTextFileTest {
	private static void open(Text text, String filename) {
		File file = new File(filename);
		try {
			text.setText("");
			FileReader reader = new FileReader(file);
			BufferedReader in = new BufferedReader(reader);
			String str = null;
			while ((str = in.readLine()) != null) {
				text.append(str + "\n");
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setLayout(new FillLayout());
		shell.setText("SWT DropTarget Test");

		final Text text = new Text(shell, SWT.BORDER | SWT.MULTI);
		int operations = DND.DROP_DEFAULT | DND.DROP_COPY | DND.DROP_MOVE;
		DropTarget target = new DropTarget(text, operations);
		target.setTransfer(new Transfer[]{FileTransfer.getInstance(),
				TextTransfer.getInstance()});

		target.addDropListener(new DropTargetAdapter() {
			
			FileTransfer fileTransfer = FileTransfer.getInstance();
			TextTransfer textTransfer = TextTransfer.getInstance();
			public void dragEnter(DropTargetEvent e) {
				System.out.println("[dragEnter] e : " + e);
				TransferData data[] = e.dataTypes;
				for (int i = 0; i < data.length; i++) {
					System.out.println("[dragEnter] data[" + i + "] : "
							+ data[i]);
				}
				if (e.detail == DND.DROP_DEFAULT) {
					e.detail = DND.DROP_COPY;
				}
			}

			public void dragOperationChanged(DropTargetEvent e) {
				if (e.detail == DND.DROP_DEFAULT) {
					e.detail = DND.DROP_COPY;
				}
			}

			public void drop(DropTargetEvent e) {
				System.out.println("[drop] e : " + e);
				if (fileTransfer.isSupportedType(e.currentDataType)) {
					String[] files = (String[]) e.data;
					if (files != null && files.length > 0) {
						open(text, files[0]); // 파일을 연다
					}
				}
				if (textTransfer.isSupportedType(e.currentDataType)) {
					String str = (String) e.data;
					if (str != null) {
						text.setText(str); // 텍스트를 커서 위치에 삽입
					}
				}
			}
		});

//		shell.setLocation(display.getBounds().width - 320,
//				display.getBounds().height - 240);
		shell.setSize(320, 240);
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}
}

여기도 동영상을 보면 어떻게 구현했는지를 알수 있다.

 

Drop

ㅁ 사용자 포멧 드레그 엔 드롭

  개발하다보면 사용자 포멧에 데이터를 드레그 엔 드롭을 하고 싶을때가 있다

 ▶ MySimpleDragAndDrop에서 화면구성 및 Drag 소스를 MyType으로 Table TableItem 객체로 구성

 ▶ DragSource, DragSource TransferType MyTypeTransfer 인스턴스로 선언

 ▶ addDragListener에서 이벤트가 발생시 event.data MyTyp객체로 넘겨줌

 ▶ DropTarget에서도 TransferType MyTypeTransfer 인스턴스 선언

 ▶ addDropListener에서 이벤트 발생시 evnet.data Mytype변환하여 사용

 ※ MyTypeTransfer는 인스턴스로 ByteArrayTransfer 상속받아 byte로 짤라 전달

 

ㅁ 3가지 소스사용

 MyType.java(사용자Drag&Drop선언), MyTypeTransfer.java(인스턴스), MySimpleDragAndDrop(main)

 MyType.java : 내가 Drag & Drop할 객체

package swt.drag_drop;

public class MyType {
	public String fileName;
	public long fileLength;
	public long lastModified;
}

 MySimpleDragAndDrop.java : 화면구성 및 이벤트 선언 

package swt.drag_drop;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;

public class MySimpleDragAndDrop {

	//시작	
	public static void main(String[] args) {

		//화면구성
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setLayout(new FillLayout());
		
		//왼쪽에 테이블: LIST는 setData가 없어 TableItem의 setData를 사용함
		final Table tblDrgSrc = new Table(shell, SWT.BORDER | SWT.WRAP | SWT.MULTI);
		
		//아이템1 : abc.txt 파일명에  크기  lastModified라는 속성을 하나의 사용자 객체를 만들어 add
		TableItem item1 = new TableItem(tblDrgSrc,SWT.NONE);
		MyType myType1 = new MyType();
		myType1.fileName = "C:\\abc.txt";
		myType1.fileLength = 1000;
		myType1.lastModified = 12312313;
		item1.setText(myType1.fileName);
		item1.setData(myType1);
		
		//아이템2 : abc.txt 파일명에  크기  lastModified라는 속성을 하나의 사용자 객체를 만들어 add
		TableItem item2 = new TableItem(tblDrgSrc,SWT.NONE);
		MyType myType2 = new MyType();
		myType2.fileName = "C:\\xyz.txt";
		myType2.fileLength = 500;
		myType2.lastModified = 12312323;
		item2.setText(myType2.fileName);
		item2.setData(myType2);
		
		//두번째는 Drop할 객체로 Lable 선언
		final Label label2 = new Label(shell, SWT.BORDER | SWT.WRAP);
		label2.setText("Drop Target for MyData[]");

		//Drag Transfer 선언 : MyTransfer 인스턴스를 넘김선언
		DragSource source = new DragSource(tblDrgSrc, DND.DROP_COPY);
		source.setTransfer(new Transfer[] { MyTypeTransfer.getInstance() });
		
		//Drag 이벤트를 선언 Transfer로는 내가만든 MyTransfer라는 객체로 넘어감
		source.addDragListener(new DragSourceAdapter() {
			public void dragSetData(DragSourceEvent event) {
				
				int arr = tblDrgSrc.getSelectionCount();
				int cnt = 0; 
				MyType[] myType = new MyType[arr];
				//Drag시 내가 만든 객체 myType이란속성에 Object를 event.data로 넘김
				for(TableItem SelItem :tblDrgSrc.getSelection()) {
					myType[cnt] = (MyType)SelItem.getData(); 
					cnt++;
				}
				event.data = myType;
				System.out.println("drageSetData");
			}
		});
		
		//Drop Target 선언 : MyTransfer 인스턴스를 받으려 선언
		DropTarget target = new DropTarget(label2, DND.DROP_COPY | DND.DROP_DEFAULT);
		target.setTransfer(new Transfer[] { MyTypeTransfer.getInstance() });
		
		//Drop 이벤트로 받은경우 Data Object를 받아 MyType으로 변환하여 그중에 이름을 가져옴
		target.addDropListener(new DropTargetAdapter() {
			
			public void dragEnter(DropTargetEvent event) {
				if (event.detail == DND.DROP_DEFAULT) {
					event.detail = DND.DROP_COPY;
				}
			}

			public void dragOperationChanged(DropTargetEvent event) {
				
				if (event.detail == DND.DROP_DEFAULT) {
					event.detail = DND.DROP_COPY;
				}
			}

			public void drop(DropTargetEvent event) {

				if (event.data != null) {
					
					MyType[] myTypes = (MyType[]) event.data;
					if (myTypes != null) {
						String string = "";
						for (int i = 0; i < myTypes.length; i++) {
							string += myTypes[i].fileName + " ";
						}
						label2.setText(string);
					}
				}

			}

		});
		shell.setSize(200, 200);
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}

		
	static class MyTransfer extends ByteArrayTransfer {

		//인스턴스 객체를 생성하기 위해 Name과 ID가 필요함
		private static final String MYTYPENAME 	= "name_for_my_type";
		private static final int MYTYPEID 		= registerType(MYTYPENAME);
		private static MyTransfer _instance = new MyTransfer();

		public static MyTransfer getInstance() {
			return _instance;
		}

		//Drag소스를 Buffer전환하여 원 소스에 넘김
		public void javaToNative(Object object, TransferData transferData) {
			
			if (!checkMyType(object) || !isSupportedType(transferData)) {
				DND.error(DND.ERROR_INVALID_DATA);
			}
			MyType[] myTypes = (MyType[]) object;
			try {
				// write data to a byte array and then ask super to convert to
				// pMedium
				ByteArrayOutputStream out = new ByteArrayOutputStream();
				DataOutputStream writeOut = new DataOutputStream(out);

				for (int i = 0, length = myTypes.length; i < length; i++) {
					byte[] buffer = myTypes[i].fileName.getBytes();
					writeOut.writeInt(buffer.length);
					writeOut.write(buffer);
					writeOut.writeLong(myTypes[i].fileLength);
					writeOut.writeLong(myTypes[i].lastModified);
				}

				byte[] buffer = out.toByteArray();
				writeOut.close();
				super.javaToNative(buffer, transferData);
			} catch (IOException e) {
			}
		}

		//Drop시 받은것을소스를 Buffer전환하여 원 소스에 넘김
		public Object nativeToJava(TransferData transferData) {
			if (isSupportedType(transferData)) {
				byte[] buffer = (byte[]) super.nativeToJava(transferData);
				if (buffer == null)
					return null;

				MyType[] myData = new MyType[0];
				try {
					ByteArrayInputStream in = new ByteArrayInputStream(buffer);
					DataInputStream readIn 	= new DataInputStream(in);
					
					while (readIn.available() > 20) {
						MyType datum = new MyType();
						int size = readIn.readInt();
						byte[] name = new byte[size];
						readIn.read(name);
						
						datum.fileName = new String(name);
						
						datum.fileLength = readIn.readLong();
						datum.lastModified = readIn.readLong();
						
						MyType[] newMyData = new MyType[myData.length + 1];
						
						System.arraycopy(myData, 0, newMyData, 0, myData.length);
						
						newMyData[myData.length] = datum;
						myData = newMyData;
					}
					readIn.close();
				} catch (IOException ex) {
					return null;
				}
				return myData;
			}

			return null;
		}
		
		
		//기본생성자
		protected String[] getTypeNames() {
			return new String[] { MYTYPENAME };
		}

		//기본생성자
		protected int[] getTypeIds() {
			return new int[] { MYTYPEID };
		}

		boolean checkMyType(Object object) {
			if (object == null || !(object instanceof MyType[]) || ((MyType[]) object).length == 0) {
				return false;
			}
			MyType[] myTypes = (MyType[]) object;
			for (int i = 0; i < myTypes.length; i++) {
				if (myTypes[i] == null || myTypes[i].fileName == null || myTypes[i].fileName.length() == 0) {
					return false;
				}
			}
			return true;
		}

		protected boolean validate(Object object) {
			return checkMyType(object);
		}
	}

}

 MyTypeTransfer.java : 인스턴스 구성

package swt.drag_drop;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.TransferData;

public class MyTypeTransfer extends ByteArrayTransfer {
	
	//인스턴스 객체를 생성하기 위해 Name과 ID가 필요함
	private static final String MYTYPE_NAME = "my_type_name";
	private static final int MYTYPE_ID 		= registerType(MYTYPE_NAME);
	private static MyTypeTransfer INSTANCE 	= new MyTypeTransfer();

	
	public static MyTypeTransfer getInstance() {
		return INSTANCE;
	}

	//Drag소스를 Buffer전환하여 원 소스에 넘김
	public void javaToNative(Object object, TransferData transferData) {
		
		if (!checkMyType(object) || !isSupportedType(transferData)) {
			DND.error(DND.ERROR_INVALID_DATA);
		}
		
		System.out.println("test1 javaToNative:"+transferData);

		//if (isSupportedType(transferData)) {
			MyType[] myTypes = (MyType[]) object;
			try {
				// write data to a byte array and then ask super to convert to
				// pMedium
				ByteArrayOutputStream bout = new ByteArrayOutputStream();
				DataOutputStream out = new DataOutputStream(bout);
				for (int i = 0, length = myTypes.length; i < length; i++) {
					byte[] buffer = myTypes[i].fileName.getBytes();
					out.writeInt(buffer.length);
					out.write(buffer);
					out.writeLong(myTypes[i].fileLength);
					out.writeLong(myTypes[i].lastModified);
				}
				byte[] buffer = bout.toByteArray();
				out.close();

				super.javaToNative(buffer, transferData);
			} catch (IOException e) {
				e.printStackTrace();
			}
		//}
	}

	//Drop시 받은것을소스를 Buffer전환하여 원 소스에 넘김	
	public Object nativeToJava(TransferData transferData) {
		//System.out.println("test2"+transferData);
		System.out.println("test2 nativeToJava:"+transferData);
		
		if (isSupportedType(transferData)) {

			byte[] buffer = (byte[]) super.nativeToJava(transferData);
			if (buffer == null) {
				return null;
			}

			MyType[] myData = new MyType[0];
			try {
				ByteArrayInputStream bin = new ByteArrayInputStream(buffer);
				DataInputStream in = new DataInputStream(bin);
				while (in.available() > 20) {
					MyType datum = new MyType();

					int size = in.readInt();
					byte[] name = new byte[size];
					in.read(name);
					datum.fileName = new String(name);
					datum.fileLength = in.readLong();
					datum.lastModified = in.readLong();

					MyType[] newMyData = new MyType[myData.length + 1];
					System.arraycopy(myData, 0, newMyData, 0, myData.length);
					newMyData[myData.length] = datum;
					myData = newMyData;
				}
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
				return null;
			}
			return myData;
		}

		return null;
	}

	protected String[] getTypeNames() {
		return new String[]{MYTYPE_NAME};
	}

	protected int[] getTypeIds() {
		return new int[]{MYTYPE_ID};
	}
	
	boolean checkMyType(Object object) {
		if (object == null || !(object instanceof MyType[]) || ((MyType[]) object).length == 0) {
			return false;
		}
		MyType[] myTypes = (MyType[]) object;
		for (int i = 0; i < myTypes.length; i++) {
			if (myTypes[i] == null || myTypes[i].fileName == null || myTypes[i].fileName.length() == 0) {
				return false;
			}
		}
		return true;
	}

	protected boolean validate(Object object) {
		return checkMyType(object);
	}	
}

'IT > RCP' 카테고리의 다른 글

[SWT] Win32 OLE  (0) 2020.12.19
[SWT] 클립보드  (0) 2020.12.19
[SWT] 다이얼로그  (0) 2020.12.19
[SWT] Layout  (0) 2020.12.19
[SWT] 이벤트  (0) 2020.12.19

  대화창은  흔히 쓰는 디렉토리 선택, 파일불러오기,파일저장하기, 색선택등등의 대화창을 말한다.

먼저 계층도를 살펴보자

Dialog의 세부 하위 구성

ㅁ ColorDialog

ColorDialog dialog = new ColorDialog(shell);
RGB color = dialog.open();
if (color != null){
	System.out.println("RGB color"+color.toString());			
}else {
	System.out.println("RGB color null");
}

DirectoryDialog

DirectoryDialog dialog = new DirectoryDialog(shell);
dialog.setMessage("Choose a save directory");
String savetarget= dialog.open();
if (savetarget != null){
	System.out.println("savetarget:"+savetarget);			
}else {
	System.out.println("savetarget null");
}	

File Open

FileDialog dialog = new FileDialog(shell,SWT.OPEN | SWT.MULTI);		//SWT.SAVE, SWT.OPEN,SWT.MULTI 등등 있다
dialog.setFilterExtensions(new String[] {"*.txt;*.doc"});
dialog.open();
String [] savetarget= dialog.getFileNames();
if (savetarget != null){
	System.out.println("OPEN FIle List:"+Arrays.toString(savetarget));			
}else {
	System.out.println("OPEN FIle List null");
}

ㅁ File SAVE

FileDialog dialog = new FileDialog(shell,SWT.SAVE | SWT.MULTI);
//SWT.SAVE, SWT.OPEN,SWT.MULTI 등등 있다
dialog.setFilterExtensions(new String[] {"*.txt;*.doc"});
//dialog.setFilterPath(string);
//dialog.setFileName(string);
dialog.open();
//dialog.getFileName();
String savetarget= dialog.getFileName();;
if (!savetarget.equals("")){
	System.out.println("SAVE FIle    :"+savetarget);			
	System.out.println("getFilterPath:"+dialog.getFilterPath());
	System.out.println("getOverwrite :"+dialog.getOverwrite());
}else {
	System.out.println("SAVE FIle null");
}

FontDialog

FontDialog dialog = new FontDialog(shell);		//SWT.SAVE, SWT.OPEN,SWT.MULTI 등등 있다
dialog.open();

if (dialog != null){
	System.out.println("getEffectsVisible:"+dialog.getEffectsVisible());
	System.out.println("getText :"+dialog.getText());			
	System.out.println("getStyle :"+dialog.getStyle());
	System.out.println("getFontData :"+dialog.getFontData());							
	System.out.println("getFontList :"+Arrays.toString(dialog.getFontList()));
}else {
	System.out.println("FontDialog null");
}

MessageBox

/* 버튼 타입
SWT.OK
SWT.OK | SWT.CANCEL
SWT.YES | SWT.NO
SWT.YES | SWT.NO | SWT.CANCEL
SWT.RETRY | SWT.CANCEL
SWT.ABORT | SWT.RETRY | SWT.IGNORE*/

/*아이콘타입
 SWT.ERROR_ICON
 SWT.ICON_INFOMATION
 SWT.ICON_QUESTION
 SWT.ICON_WARNING
 SWT.ICON_WORKING
 */

MessageBox dialog = new MessageBox(shell,SWT.YES | SWT.NO);
dialog.setMessage("내용부분");
dialog.setText("타이틀");
int returnVal = dialog.open();

System.out.println("returnVal :"+returnVal);	//각상수로 비교하여 사용한다
if (returnVal==SWT.YES) {
	//..
}

참고로 Jface에서는 Message Dialog많이 환경설정과 관련된 Dialog들이 추가로 제공해주고 있다

'IT > RCP' 카테고리의 다른 글

[SWT] 클립보드  (0) 2020.12.19
[SWT] Drag & Drop  (0) 2020.12.19
[SWT] Layout  (0) 2020.12.19
[SWT] 이벤트  (0) 2020.12.19
[SWT] 기본정보(구성,환경,위젯정보)  (0) 2020.12.19

레이아웃에 대해서는 잘되어 있는 사이트 먼저 공유하고자 합니다.

(참고 : https://www.eclipse.org/articles/Article-Understanding-Layouts/Understanding-Layouts.htm) 구글에 SWT layout하면 가장 많이 검색되는 화면입니다

 

 

ㅁ MarginLeft, MarginTop, MarginRight, MarginButton Vertical/Horizontal Spacing

 

그리고 layout은 SWT, JFACE 모두 동일하게 사용되어 집니다. 위젯들을 어떻게 배치하고 화면이 늘려짐에 따라 어떤것들이 늘어나고 고정되는지에 대한 얘기 입니다.

 

1. FillLayout

    FillLayout fillLayout = new FillLayout()

    fillLayout.type        = SWT.VERTICAL

    shell.setLayout(fillLayout)    적용하려는 Composite, Shell 등등에 적용

 

 

2. RowLayout

    RowLayout rowLayout = new RowLayout();

    rowLayout.wrap = false;

    rowLayout.pack = false;

    rowLayout.justify = true;

    rowLayout.marginLeft = 5;

    rowLayout.marginTop = 5;

    rowLayout.marginRight = 5;

    rowLayout.marginBottom = 5;

    rowLayout.spacing = 0;

    shell.setLayout(rowLayout);

    wrap(기본 true) : false한행 유지, 부모가 가시적으로 줄어들 때 안보이는게 발생

    pack(기본 true) : false인경우 본래 size사용

    justify(기본 false) : true인경우 균등하게 배치

 

3. GridLayout

   가장많이 사용되어집니다.

4. GridData

  setLayoutData메소드 사용

  Button button1 = new Button(shell, SWT.PUSH);

  button1.setText("B1");

  button1.setLayoutData(new GridData());

 

 

 

'IT > RCP' 카테고리의 다른 글

[SWT] 클립보드  (0) 2020.12.19
[SWT] Drag & Drop  (0) 2020.12.19
[SWT] 다이얼로그  (0) 2020.12.19
[SWT] 이벤트  (0) 2020.12.19
[SWT] 기본정보(구성,환경,위젯정보)  (0) 2020.12.19

   이벤트라 함은 버튼클릭, 텍스트 내용이 변경된경우 등등의 해당되며, 이와 SWT에서 이벤트

를 알아보고자 합니다.

먼저 이벤트 종류에 대해 알아봅시다.

 

1) 유형이벤트 : key클릭, 마우스 up 등등 특정이벤트
2) 무형이벤트 : 특정을 지칭하지 않은 이벤트들
3) 어뎁터 : 이벤트를 전부 구현하지 않고 필요한것만 구현토록 구조화
4) 이벤트를 받아 리스너에서 보통은 처리하는 메서드 구현 즉 연결관계에 있다 

참고로 자바 이벤트와 비슷하다.

1.1 이벤트 유형 리스너와 리스너 메소드

 

1.2 이벤트의 구현

이벤트 리스너의 구현방식 두가지 : 익명구현, 외부클래스

1) 익명구현방식 : 장)소스가 즉흥적 가능, 단)재활용이 안됨

helloBtn.addMouseListener(new MouseListener() {  //==>익명구현   
   @Override
   public void mouseUp(org.eclipse.swt.events.MouseEvent arg0) {
    // TODO Auto-generated method stub
    System.out.println("마우스 업");
    
   }
   
   @Override
   public void mouseDown(org.eclipse.swt.events.MouseEvent arg0) {
    // TODO Auto-generated method stub
    System.out.println("마우스 다운");
   }
   
   @Override
   public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent arg0) {
    // TODO Auto-generated method stub
    System.out.println("마우스 더블클릭");
   }
  });

2) 외부클래스 구현방식 : 장)재활용가능

   
   MouseListener ExMouseListener = new MouseListener() {  //==>외부클래스구현
   @Override
   public void mouseDoubleClick(MouseEvent arg0) {
    // TODO Auto-generated method stub
    System.out.println("마우스 더블클릭");
   }
   @Override
   public void mouseDown(MouseEvent arg0) {
    // TODO Auto-generated method stub
    System.out.println("마우스 다운");
   }
   @Override
   public void mouseUp(MouseEvent arg0) {
    // TODO Auto-generated method stub
    System.out.println("마우스 업");
   }
   
  };

helloBtn.addMouseListener(ExMouseListener); //외부클래스 사용

1.3 어뎁터

 앞 이벤트에서는 특이한 것은 내부 메소드가 모두 @Override된 것을 알수 있다. 구현하지 않아도 선언되지 않으면 안되는 반면 어뎁터는 구현하고 싶은 것들만 구현하도록 되어 있다

즉 익명의 인터페이스를 사용하지 않고 또한 모든메소드를 구현하지 않기 위해 어댑터라 부르는 특별한 클래스로 사용하여 구현 :: 내부 메소드를 필요한것만 사용가능

1) 익명구현

helloBtn.addMouseListener(new MouseAdapter() {  //==>익명구현
  
   public void mouseDown(org.eclipse.swt.events.MouseEvent arg0) {
    // TODO Auto-generated method stub
    System.out.println("마우스 다운");
   }
 });

2) 외부클래스 구현

MouseListener ExMouseListener = new MouseAdapter() {  //==>외부클래스구현
   
   public void mouseDown(MouseEvent arg0) {
    // TODO Auto-generated method stub
    System.out.println("마우스 다운");
   }
   public void mouseUp(MouseEvent arg0) {
    // TODO Auto-generated method stub
    System.out.println("마우스 업");
   }   
  };

helloBtn.addMouseListener(ExMouseListener) ; //외부클래스 사용

1.4 어뎁터  종류

 

※ 참고 사항 Event에서 keyCode(KeyListne/KeyAdapter에서 사용)

 

1.5 무형이벤트

   특정이벤트가 아니라 모든 이벤트처리 대표로처리할수 있는 Listener 클래스이다

    ▶ JFaceTestMain.java작성

import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
 
public class JFaceTestMain extends ApplicationWindow {
  
 public JFaceTestMain() {
  super(null);
  // TODO Auto-generated constructor stub
 }
 protected Control createContents(Composite parent) {
  System.out.println("test main createContents");
  new IntangibleEventTest(parent);
  parent.pack();
  return parent;
 }
 
 public static void main(String[] args) {
  JFaceTestMain obj = new JFaceTestMain();
  obj.setBlockOnOpen(true);
  obj.open();
   
  Display.getCurrent().dispose();
 }
}

 IntangibleEventTest.java작성

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
 
public class IntangibleEventTest extends Composite{
 
 Label output;
  
 public IntangibleEventTest(Composite parent) {
   
  super(parent, SWT.NULL);
  System.out.println("test IntangibleEventTest");
  Button typed = new Button(this,SWT.PUSH);
  typed.setText("Typed");
  typed.setLocation(2,10);
  typed.pack();
   
  typed.addKeyListener(new KeyAdapter() {
   public void keyPressed(KeyEvent e) {
    keyHandler();
   }
 
 
  });
   
  Button untyped = new Button(this,SWT.PUSH);
  untyped.setText("UnTyped");
  untyped.setLocation(80,10);
  untyped.pack();
  untyped.addListener(SWT.MouseEnter, UntypedListener);
  untyped.addListener(SWT.MouseExit, UntypedListener);
   
  output = new Label(this,SWT.SHADOW_OUT);
  output.setBounds(40,70,90,40);
  output.setText("No Event");
   
  pack();
   
 }
  
 Listener UntypedListener = new Listener(){
 
  @Override
  public void handleEvent(Event event) {
   System.out.println("handleEvent:"+event.widget.getClass().getSimpleName() );
   switch(event.type) {
    
   case SWT.MouseEnter:
    output.setText("Mouse Enter");
    break;
   case SWT.MouseExit:
    output.setText("Mouse Exit");
    break;
   }
    
  }
   
 };
 
 void keyHandler() {
  // TODO Auto-generated method stub
  output.setText("Key Event");
 }
}

'IT > RCP' 카테고리의 다른 글

[SWT] 클립보드  (0) 2020.12.19
[SWT] Drag & Drop  (0) 2020.12.19
[SWT] 다이얼로그  (0) 2020.12.19
[SWT] Layout  (0) 2020.12.19
[SWT] 기본정보(구성,환경,위젯정보)  (0) 2020.12.19

위젯 툴킷(Standard Widget Toolkit)으로 이클립스에서 사용하고 있는 자바기반의 위젯 툴킷(Widget Toolkit)

우리가 사용하는 이클립스에 ViewPart,EditorPart등 도구를 만들기 위한 기초입니다.

 

ㅁ 구성

    

   Display객체, Shell객체 그리고 그 하위에 위젯에 개념이 들어간다

   OS swt.jar에 따라 여러가지 운영체계 프로그램을 만들 수 있다

   위젯은 기본이다

 

ㅁ 환경설정

    Java 프로젝트 생성 

   

해당 프로젝트에 swt.jar만 있으면 된다.

ㅁ 참고사이트

    http://www.eclipse.org/swt/

    각종 위젯등에 대한 예시 가 소스하고 함께 잘되어 있음

 

ㅁ Widget의 구성요소

ㅁ 각 위젯에 요소

    위젯은 좀 프로그램을 해본 경험이 있는사람의 경우 쉽게 알수 있기 때문에 많은 설명을 하지않고 단지 기능 요약을 해보겠습니다.

 1) Control 메소드

Control메소드

기능

getSize()

위젯크기를 표시하는 Point 객체반환

setSize(int,int)

너비와 길이 값 설정

setSize(Point)

Point 객체에 따라 위젯크기 설정

computeSize()

위젯 내용을 모두 보여줄수 있는 면적을 반환

computeSize(int,int,boolean)

위젯내용을 모두 보여줄수 있는 면적을 반환하고, 위젯 특성이 바뀌었는지 알려줌

pack()

위젯을 선호하는 크기로 재조정한다

pack(boolean)

위젯을 선호하는 크기로 재조정하고, 특성이 바뀌었는지 알려줌

getLocation()

위젯의 부모에 대한 상대위치

setLocation(int,int)

위젯의 부모에 대한 상대위치 설정

getBounds()

위젯의 크기와 부모에 대한 상대 위치를 반환한다

setBounds(int,int,int,int)

위젯의 크기와 부모에 대한 상대위치 설정

toControl(int,int)

화면 기준 좌표를 컨트롤 기준 Point 값으로 바꾼다

toControl(Point)

화면 기준 Point값을 컨트롤을 기준 Point 값으로 바꾼다

toDisplay(int,int)

컨트롤 기준좌표를 컨트롤 기준 Point 값으로 바꾼다

toDisplay(Point)

컨트롤 기준 Point 값을 Point 값으로 바꾼다

※ setSize() 보다 pack() 컨테이너 크기를 알아서 조절

 

2) Label 메소드

     위치        : SWT.LEFT, SWT.RIGHT, SWT.CENTER,

     구분선     : SWT.SPARATOR

     수직/수평 : SWT.VERTICAL, SWT.HORIZONTAL

     그림자     : SWT.SHADOW_IN, SWT.SHADOW_OUT, SWT.SHADOW_NONE

     ==>SWT에는 열거형 정수형으로 많은 타입을 가지고 있다

Label메소드

기능

getText()

 Label 텍스트 읽기

setText(String)

 Label텍스트 쓰기

getAlignment()

 정렬가져오기

setAlignment(int)

 정렬 setting

getImage()

 이미지 set

setImage(Image)

이미지 get

 

3) Button

     SWT.PUSH,

     SWT.ARROW | SWT.RIGHT

     SWT.TOGGLE

     SWT.CHECK, SWT.RADIO

 

4) Composite

     각Control을 집합으로 구성가능하다

4.1) Composite 기본

Composite 메소드

기능

getChiendren()

Control 객체의 배열을 반환한다

getLayout()

Composite에 연결한 레이아웃을 반환한다

setLayout(Layout)

Composite에 연결한 레이아웃을 설정한다

getTabList()

탭 순서에 따른 Control 객체의 배열을 반환한다

setTabList(Control[])

Composite의 위젯의 탭 순서를 설정한다

 

4.2) Composite의 하위클래스로 Scrollable 속성을 추가 사용         

Scrollable 메소드

기능

getClientArea()

Scrollable 객체에 가능한 화면 표시 면적을 반환한다.

computeTrim(int,int,int,int)

기대하는 클라이언트 영역을 위한 Composite의 필요 면적을 반환한다

getHorizontalBar()

수평 ScrollBar 객체를 반환한다

getVerticalBar()

수직 ScrollBar 객체를 반환한다

 

5)  Group

  그림자 속성과 함께 추가적으로 식각(etching)을 표시한다.

  SWT.SHADOW_ETCHEND_IN SHADOW_ETCHEND_OUT

6) SashForm

7) TabFolder

    getItemCount : TabFolder  TabItem 수반환

    getItems() : TabItem 객체의 배열을 반환

    getSelection() : 사용자가 어떤 TabItem을 선택했는지

    setSelection(): 선택될 탭을 설정

 7) LIst

 8) Combo

   style : SWT.SIMPLE, SWT.DROP_DOWN, SWT.READ_ONLY

 9) Tree

    ▶ 트리에서 사용하는 메소드 : Scrollable의 확장기능임.

메소드

기능

addSelectionListener()

선택 이벤트의 통지

addTreeListener()

TreeListener 인터페이스는 +확장  축소 할 때

select()/deselect()

현재 선택/ 제외

getSelection()

현재 선택항목

 show()

 주어진 항목을 보일때까지 스크롤

  Style로는 SWT.SINGLE, SWT.MULT

 TreeItem 메소드

메소드

기능

getItem()

 Tree 하위를 각각 TreeItem이라하면 불러오기

getChecked()

체크

setExpanded(boolean)

 확장

 

예제) Widdget Window에서 Tab을 만들고 그안에 두개 Composite가 구성된 Composite를 추가

Composite에는 Group Composite, SashForm Composite구성해보았다

 

 

'IT > RCP' 카테고리의 다른 글

[SWT] 클립보드  (0) 2020.12.19
[SWT] Drag & Drop  (0) 2020.12.19
[SWT] 다이얼로그  (0) 2020.12.19
[SWT] Layout  (0) 2020.12.19
[SWT] 이벤트  (0) 2020.12.19

+ Recent posts