2013년 12월 25일 수요일

SWT를 이용한 텍스트(TEXT) 편집




SWT를 이용한 텍스트(TEXT) 편집


  SWT는 텍스트 편집에 필요한 두 개의 컨트롤을 제공합니다. Text 객체는 스타일이나 형식이 없는 문자열을 쓸 수 있게 하는 반면, StyledText 객체는 입력하는 문자열과 컨트롤 자체의 색상과 스타일을 바꿀 수 있습니다.



기본 Text 위젯


  Text 컨트롤은 형식이 없는 글을 입력할 수 있도록 합니다. Text 클래스는 인스턴스화 될 수 있으며, 기본적인 자신의 형태로 사용됩니다. 그리고 여러 이벤트를 받아들일 수 있으며, 이러한 이벤트의 발생을 처리하여 위젯의 동작에 영향을 미칠 수 있습니다.



  다음 예제는 사용자가 문자열을 입력하면, 입력된 문자열을 모두 대문자로 만드는 예제입니다.



<예제 코드>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.swtjface.ch5;
 
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
 
/**
 * 2010.06.02
 * 텍스트 편집 예제
 * @author cremazer
 */
public class Ch5_Capitalizer extends Composite {
 
 //생성자
 public Ch5_Capitalizer(Composite parent){
  super(parent, SWT.NONE);
  buildControls();
 }
 
 private void buildControls(){
  this.setLayout(new FillLayout());
  Text text = new Text(this, SWT.MULTI | SWT.V_SCROLL);
  
  text.addVerifyListener(new VerifyListener() {
   
   @Override
   public void verifyText(VerifyEvent e) {
    if(e.text.startsWith("1")){
     e.doit = false//검증
    }else{
     e.text = e.text.toUpperCase(); //문자열 대문자로 수정
    }
   }
  });
 
 }
 
}



<테스트 예제 코드>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.swtjface.ch5;
 
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
 
/**
 * 2010.06.02
 * 기본 텍스트 편집 테스트 
 * @author cremazer
 */
public class WidgetWindow extends ApplicationWindow {
 public WidgetWindow(){
  super(null);
 }
 
 protected Control createContents(Composite parent){
  Ch5_Capitalizer ca = new Ch5_Capitalizer(parent);  
  
  getShell().setText("Widget Window");
  return parent;
 }
 
 public static void main(String[] args) {
  WidgetWindow wwin = new WidgetWindow();
  wwin.setBlockOnOpen(true);
  wwin.open();
  Display.getCurrent().dispose();
 }
}




<결과>



  아래 표는 Text의 인스턴스를 제어하는 중요한 메서드를 요약한 것입니다. 이 메서드는 텍스트를 수정하고 외양을 조정하고 관심이 있는 이벤트의 발생을 받는 리스너를 추가하는 작업을 합니다.


주요 Text 메서드



  주의할 것은 insert()가 위젯의 모든 내용을 대체한다는 것입니다. 이는 존재하는 내용에 텍스트를 추가하는 것을 허용하지 않습니다.





StyledText 위젯


  StyledText는 단순 Text에서 제공하는 모든 메서드를 제공하면서, 폰트, 텍스트 색상, 폰트 스타일 등을 수정하는 기능이 추가되어 있습니다. 또한 StyledText는 편집의 기본 기능인 잘라내기와 붙여넣기 등을 지원합니다. 


  StyledText는 잘라내기, 붙여넣기, 다음찾기, 텍스트 마지막으로 이동하기 등 동작을 표현하기 위해 상수를 사용하며, 다음 두 가지의 경우에 유용합니다. 


  • 상수를 이용하여 코드상에서 이를 구현할 수 있으며 invokeAction()을 사용합니다.
  • 이러한 동작을 키 입력과 연동시킬 수 있으며, setKeyBinding()을 사용합니다. setKeyBinding()은 키(Shift 나 Ctrl 같은 기능키) 하나를 취해서 이 키를 명시한 동작과 연동합니다.


  
  또한 리스너로 수신할 수 있는 많은 이벤트를 발생시킵니다. Text에서 정의한 이벤트 외에도, 선의 배경색이나 선의 스타일을 그리기 위한 이벤트를 포함합니다.



StyleRange를 이용한 텍스트 스타일 


  StyledText는 StyleRange 클래스를 이용하여 서로 다른 스타일을 관리합니다. 

  StyleRange는 텍스트 범위에 대한 스타일 속성 정보를 보유합니다. StyleRange의 모든 필드는 public이므로 자유롭게 수정가능하지만, 수정한 스타일은 StyledText 인스턴스에서 setStyleRange()를 호출해야 적용이 됩니다. 


  아래의 예제코드는 되돌리기/다시실행 기능을 구현한 예제이며, 텍스트 영역을 스크롤바와 함께 보이며, 이 영역에 사용자가 글을 입력할 수 있습니다. F1을 누르면 마지막 편집을 취소하고, F2를 누르면 마지막 취소한 편집을 복구합니다.



<예제 코드>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package com.swtjface.ch5;
 
import java.util.LinkedList;
import java.util.List;
 
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ExtendedModifyEvent;
import org.eclipse.swt.custom.ExtendedModifyListener;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
 
/**
 * 2010.06.05
 * StyledText 예제코드
 * F1 : 되돌리기
 * F2 : 다시실행 
 * @author cremazer
 */
public class Ch5_Undoable extends Composite{
    
  private static final int MAX_STACK_SIZE = 25;
  private List<String> undoStack;
  private List<String> redoStack;
 
  private StyledText styledText;
 
  //생성자
  public Ch5_Undoable(Composite parent)
  {
    super(parent, SWT.NONE);
    undoStack = new LinkedList<String>();
    redoStack = new LinkedList<String>();
    buildControls();
  }
  
  /*
   * styledText 생성 및 설정
   */
  private void buildControls(){
    this.setLayout(new FillLayout());
    styledText = new StyledText(this, SWT.MULTI | SWT.V_SCROLL);
    
    styledText.addExtendedModifyListener(
      new ExtendedModifyListener() {
        public void modifyText(ExtendedModifyEvent event){
          String currText = styledText.getText();
          String newText = currText.substring(event.start, event.start + event.length);
          if( newText != null && newText.length() > 0 ){
            if( undoStack.size() == MAX_STACK_SIZE ){
              undoStack.remove( undoStack.size() - 1 );
            }
            undoStack.add(0, newText);
          }
        }
      }
    );
    
    styledText.addKeyListener(new KeyAdapter() {
      public void keyPressed(KeyEvent e){
        switch(e.keyCode){
          case SWT.F1:
            undo(); break;
          case SWT.F2:
            redo(); break;
          default:
            //ignore everything else
        }
      }
    });
  }
  
  /**
   * F1 눌렀을 때 실행 : 되돌리기
   */
  private void undo(){
    if( undoStack.size() > 0 ){
      String lastEdit = (String)undoStack.remove(0);
      int editLength = lastEdit.length();
      String currText = styledText.getText();
      int startReplaceIndex = currText.length() - editLength;
      styledText.replaceTextRange(startReplaceIndex, editLength, "");
      redoStack.add(0, lastEdit);    
    }
  }
  
  /**
   * F2 눌렀을 때 실행 : 다시실행
   */
  private void redo(){
    if( redoStack.size() > 0 ){
      String text = (String)redoStack.remove(0);
      moveCursorToEnd();
      styledText.append(text);
      moveCursorToEnd();
    }
  }
 
  private void moveCursorToEnd(){
    styledText.setCaretOffset(styledText.getText().length());
  }
}


<테스트 예제 코드>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.swtjface.ch5;
 
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
 
/**
 * 2010.06.05
 * 스타일 텍스트 편집 테스트 
 * @author cremazer
 */
public class WidgetWindow extends ApplicationWindow {
 public WidgetWindow(){
  super(null);
 }
 
 protected Control createContents(Composite parent){
  Ch5_Undoable redoundo = new Ch5_Undoable(parent);  
  
  getShell().setText("Widget Window");
  return parent;
 }
 
 public static void main(String[] args) {
  WidgetWindow wwin = new WidgetWindow();
  wwin.setBlockOnOpen(true);
  wwin.open();
  Display.getCurrent().dispose();
 }
}



<결과>

  
참고서적 : SWT/JFace in Action



댓글 없음:

댓글 쓰기