2014년 1월 24일 금요일

2014 Std.IO - Hello World!



2014 Std.IO - Hello World!


개발자를 시작하려고 준비하는 학생을 대상으로 하는 세미나가 내일 열리네요... 저도 많이 공감 되는 주제를 다루고 있어서 관심있는 세미나여서 공유합니다.




Hello, World! 란?


 여러분은 이제 막 시작한 개발자입니다. 아직 많은 것들을 알지 못하고 많은 것들을 궁금해하죠. 앞으로 자신이 무엇을 그리고 어떻게 해야 하는지 조차도 잘 알지 못합니다. 학교도, 뛰어나다는 선배들의 조언도 별로 여러분들에게 도움이 되지 못합니다. 여러분들의 궁금증을 풀 수 있을까 참가했던 수많은 개발자 행사들은 최신 기술들과 개발자들을 위한 팁들만을 이야기할 뿐입니다. 정작 여러분이 궁금해하는 그 기술들이 언제 어디에서 쓰이는지, 어떻게 쓰이는지 그리고 정말 나에게 필요한지 알려주지는 않죠.

아직도 개발을 시작했지만, 아직 어떻게 해야 하는지 갈팡질팡하고 계신가요? 아니면 학교에서 배우는 내용보다 더 많은 것들을 알고 싶나요?

여기 여러분들을 위한 행사를 저희가 준비했습니다. IT 업계에서 많은 경력을 가진 분들이 직접 지금까지 겪은 일들과 본인이 경험한 삶 그리고 바로 여러분들이 앞으로 어떻게 나아가야 하는지 이야기해주실 겁니다. 또 학교에서 배울 수 없는 여러 기술에 첫발을 내디딜 수 있도록 도와드릴 겁니다. 이번 행사를 통해 평소 여러분들이 궁금했던 것들을 해소하고 그 어디에서도 들을 수 없는 이야기를 들어보세요.

2014년 1월 25일 토요일 단 하루, 진심으로 여러분들을 위한 개발자 행사를 만나보세요.

본 행사는 학생 개발자를 주요 대상으로 하지만 학생이 아닌 현업 개발자께서도 참석이 가능합니다. 


행사 일정표





행사 안내 


  • 일시 : 2014년 1월 25일 토요일 오전 10시
  • 장소 : 건국대학교 새천년관 지하 2층 국제회의장    


찾아오시는 길

지하철 : 2호선 건대 입구역 4번 출구 상허문 ( 남측 정문 ) , 7호선 어린이대공원역 3번 출구 건국문  ( 북측 정문 ) 으로 들어오면 건국대학교 내 위치.      




안내사항


  • 행사는 무료로 진행됩니다.
  • 다양한 Event를 통해 푸짐한 경품이 준비되어 있습니다 . (Google 티셔츠 , 텀블러 , 목걸이 형 카드 지갑 등...)
  • 스피커 분들과 자유롭게 이야기하실 수 있습니다.
  • 점심 식사는 별도로 제공되지 않습니다.
  • 주차는 제공되지 않으니 대중교통을 이용해 주시기 바랍니다.
  • Wi-Fi는 제공되지 않습니다. 


홈페이지


STD.IO - HELLO, WORLD!




2014년 1월 22일 수요일

SWT - JFaceColors 클래스




JFaceColors 클래스


JFaceColors 클래스는 SWT와 JFace 양쪽에서 호출할 수 있는 유용한 메서드인 setColors()를 제공합니다. setColors() 메서드는 한 번에 위젯의 전경색과 배경색을 설정할 수 있습니다. 

JFaceColors.setColors(Control control, Color foreground, background);



예제코드



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.Ch7;
 
import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
 
/**
 * JFaceColors 테스트
 *
 * @since 2013. 6. 15.
 * @author Cremazer
 *
 */
public class JFaceColorsTest {
 public static void main(String[] args) {
  Display display = new Display();
  Shell shell = new Shell(display);
  shell.setText("My First SWT GUI");
  shell.setSize(200,100);
  
  Button button = new Button(shell, SWT.NONE);
  //전경색 설정
  Color red = display.getSystemColor(SWT.COLOR_RED); 
  //배경색 설정
  Color green = display.getSystemColor(SWT.COLOR_GREEN); 
  JFaceColors.setColors(button, red, green);
  button.setText("Hello SWT!");
  button.setBounds(47,20,100,20);
  
     
  shell.open();
  while (!shell.isDisposed()) {
    if (!display.readAndDispatch()) 
   display.sleep();
  }
  display.dispose();
 }
}


테스트





※ 전경색과 배경색


포토샵에서 전경색 배경색은 색칠할때 사용하는 것이 아니라 두가지의 색을 사용할 때 필요합니다. 예를 들어 그라디언트효과에서 전경색에서 배경색으로 라는 효과는 두가지 색을 설정해야 가능하죠. 또한 필터 사용시 전경색과 배경색에 따라서 효과가 달라집니다.


위 사진은 전경색을 빨강 배경색을 녹색으로 설정하고 필터의 사진복사효과를 낸 것입니다. 전경색 배경색은 어떤 색을 칠할 때 배경색까지 칠하는 의미가 아니라 색칠할 때는 전경색만 칠해집니다. 하지만 어떤 효과가 필요한 경우는 배경색까지 포함해서 작용하는 경우가 많습니다.



참고서적 : SWT/JFace in Action



SWT - Color 사용하기




Color 사용하기


SWT는 시스템 색상이라 불리는 16개의 기본 색상 셋을 제공하기 위해 디스플레이의 getSystemColor() 메서드를 사용합니다. 이 메서드는 SWT의 색상 상수를 나타내는 정수를 취하고, Color 객체를 반환합니다.


SWT 색상 상수색상 16진 값
SWT.COLOR_BLACK0x000000
SWT.COLOR_DARK_GRAY0x808080
SWT.COLOR_GRAY0xC0C0C0
SWT.COLOR_WHITE0xFFFFFF
SWT.COLOR_RED0xFF0000
SWT.COLOR_DARK_RED0x800000
SWT.COLOR_MAGENTA0xFF00FF
SWT.COLOR_DARK_MAGENTA0x800080
SWT.COLOR_YELLOW0xFFFF00
SWT.COLOR_DARK_YELLOW0x808000
SWT.COLOR_GREEN0x00FF00
SWT.COLOR_DARK_GREEN0x008000
SWT.COLOR_CYAN0x00FFFF
SWT.COLOR_DARK_CYAN0x008080
SWT.COLOR_BLUE0x0000FF
SWT.COLOR_DARK_BLUE0x000080
    SWT에 의해 제공되는 기본 시스템 색상

만약 이 기본 색상들 외의 색상을 사용하려면, 원하는 RGB 값에 대응하는 Color 객체를 할당해야 합니다.


아래의 코드는 두 도형을 색칠하는 Canvas를 생성하는 예제입니다.


예제코드



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
package com.swtjface.Ch7;
 
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
 
public class Ch7_Colors extends Canvas {
 
  public Ch7_Colors(Composite parent) {
    super(parent, SWT.NONE);
  
    //Canvas 배경을 위해 시스템 색상을 사용
    setBackground(this.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
    addPaintListener(drawListener);
  
  }
 
  PaintListener drawListener = new PaintListener() {
    public void paintControl(PaintEvent pe) {
      Display disp = pe.display;
   
      //RGB 값에 기반한 Color 객체 생성
      Color light_gray = new Color(disp, 0xE0, 0xE0, 0xE0);
   
      GC gc = pe.gc;
      gc.setBackground(light_gray);
      gc.fillPolygon(new int[] { 20, 20, 60, 50, 100, 20 });
      gc.fillOval(120, 30, 50, 50);
   
      //Color 객체 할당 해제
      light_gray.dispose(); 
    }
  };
}



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
package com.swtjface.Ch7;
 
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 ColorTest extends ApplicationWindow {
 public ColorTest() {
  super(null);
 }
 
 protected Control createContents(Composite parent) {
  Ch7_Colors composite = new Ch7_Colors(parent);
  
  getShell().setText("Widget Window");
  parent.setSize(200, 150);
  return parent;
 }
 
 public static void main(String[] args) {
  ColorTest tc = new ColorTest();
  tc.setBlockOnOpen(true);
  tc.open();
  Display.getCurrent().dispose();
 }
 
}


테스트




색상을 만들어내기 위해 Display 객체가 필요한데, 이는 Canvas와 결합한 getDisplay() 메서드를 사용합니다. 그러나 PaintListener 인터페이스는 생성자 멤버에게 접근할 수 없기 때문에, 생성자에서 PaintListener 를 추가하여 PaintListener 에 속해있는 PaintEvent 의 display 필드를 사용할 수 있습니다.



타임라인(Timeline) 시각화에 대하여...




타임라인(Timeline) 시각화에 대하여...







구글의 연구팀(http://research.google.com/bigpicture/ )이 제공하는 Music Timeline과 함께 음악의 역사를 탐험해 보세요~  다양한 장르의 음악과 아티스트들의 흥망성쇠를 한눈에 살펴볼 수 있도록 시각화했습니다: )  http://research.google.com/bigpicture/music/ 





차트를 활용하여 시간대별 순으로 각 음악에 대한 장르를 한눈에 볼 수 있는 시각화 화면입니다. 이 내용을 보면서 잠깐 생각한 것은, Music Timeline을 벤치마킹해서 대한민국 국사&역사 에 대한 내용을 한 눈에 볼 수 있는 사이트를 만들면 '국사 공부에 도움이 되겠구나' 하는 생각이 듭니다.


언젠가 직접 차트를 활용해서 Music Timeline 같은 이런 화면을 만들날이 오겠죠...

2014년 1월 16일 목요일

SWT - Canvas에 도형그리기




Canvas에 도형그리기


SWT에서 그래픽을 사용하려면, 그래픽 컨텍스트(GC, Graphic Context)를 사용해야 합니다. GC는 Control 위에서 그림판과 같은 기능을 합니다.

그래픽 애플리케이션을 구축하려면 GC를 생성하고, 이를 컴포넌트에 연결해야 합니다.


아래의 예제는 Shell에 Canvas 객체를 생성한 후에 shell.open() 메서드를 호출하고, 그 후에 GC객체를 생성하여 사용하는 예제입니다. shell.open() 메서드는 Canvas 화면을 지워줍니다. 그리고 GC를 모두 사용한 후에는 gc.dispose() 메서드를 호출하여 GC의 할당을 해제하여 줍니다.



▶ 예제코드



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
package com.swtjface.Ch7;
 
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
 
public class DrawExample {
 
  public static void main(String[] args) {
  Display display = new Display();
  Shell shell = new Shell(display);
  shell.setText("Drawing Example");
 
   //shell에 Canvas 객체를 생성
  Canvas canvas = new Canvas(shell, SWT.NONE);
  canvas.setSize(150, 150);
  canvas.setLocation(20, 20);
  shell.open();
  shell.setSize(200, 220);
 
   
  
  //Canvas에 그래픽 컨텍스트를 생성
  GC gc = new GC(canvas);
  //사각형
  gc.drawRectangle(10, 10, 40, 45);
  //원
  gc.drawOval(65, 10, 30, 35); 
  //선
  gc.drawLine(130, 10, 90, 80); 
  //다각형
  gc.drawPolygon(new int[] { 20, 70, 45, 90, 70, 70 }); 
  //꺾은선
  gc.drawPolyline(new int[] { 10, 120, 70, 100, 100, 130, 130, 75 }); 
  gc.dispose(); //할당 해제
 
   while (!shell.isDisposed()) {
   if (!display.readAndDispatch())
    display.sleep();
  }
  display.dispose();
 }
}



▶ 실행결과






SWT - RadialLayout




맞춤 레이아웃(RadialLayout)


맞춤 레이아웃은 표준 레이아웃에 비해 자주 사용하지 않습니다. 그러나 레이아웃을 좀 더 개성적으로 다뤄볼 수 있어서 정말 필요한 경우에는 사용할 수 있습니다.



▶ 예제코드



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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package com.swtjface.Ch6;
 
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;
 
public class RadialLayout extends Layout {
 public RadialLayout() {
  super();
 }
 
  /**
  * 레이아웃이 필요로 하는 공간을 계산한다.
  * @param composite 컨트롤을 넣을 객체
  * @param wHint 너비
  * @param hHint 높이
  * @param flushCache 캐시된 값을 안전하게 사용할지 여부
  * @return 
  */
 protected Point computeSize(Composite composite, int wHint, int hHint
                             , boolean flushCache) {
  Point maxDimensions = calculateMaxDimensions(composite.getChildren());
  int stepsPerHemisphere = stepsPerHemisphere(composite.getChildren().length);
 
   int maxWidth = maxDimensions.x;
  int maxHeight = maxDimensions.y;
 
   int dimensionMultiplier = (stepsPerHemisphere + 1);
  int controlWidth = maxWidth * dimensionMultiplier;
  int controlHeight = maxHeight * dimensionMultiplier;
  int diameter = Math.max(controlWidth, controlHeight);
  Point preferredSize = new Point(diameter, diameter);
 
   //레이아웃 크기 계산
  if (wHint != SWT.DEFAULT) {
   if (preferredSize.x > wHint) {
    preferredSize.x = wHint;
   }
  }
 
   if (hHint != SWT.DEFAULT) {
   if (preferredSize.y > hHint) {
    preferredSize.y = hHint;
   }
  }
 
   return preferredSize;
 }
 
  /**
  * 배치
  */
 protected void layout(Composite composite, boolean flushCache) {
  Point[] positions = calculateControlPositions(composite);
  Control[] controls = composite.getChildren();
  for (int i = 0; i < controls.length; i++) {
   Point preferredSize = controls[i].computeSize(SWT.DEFAULT, SWT.DEFAULT);
   controls[i].setBounds(positions[i].x, positions[i].y, 
                   preferredSize.x, preferredSize.y);
  }
 }
 
  /**
  * 위젯 위치 설정
  * @param composite
  * @return
  */
 private Point[] calculateControlPositions(Composite composite) {
  //컨트롤 개수 설정
  int controlCount = composite.getChildren().length;
  //위젯 순서 설정
  int stepsPerHemisphere = stepsPerHemisphere(controlCount);
  Point[] positions = new Point[controlCount];
 
   //최대 폭 설정
  Point maxControlDimensions = calculateMaxDimensions(composite.getChildren());
  int maxControlWidth = maxControlDimensions.x;
 
   //위젯 배치 모양 설정 - 원
  Rectangle clientArea = composite.getClientArea();
  int smallestDimension = Math.min(clientArea.width, clientArea.height);
  int radius = (smallestDimension / 2) - maxControlWidth;
  Point center = new Point(clientArea.width / 2, clientArea.height / 2);
  long radiusSquared = radius * radius;
 
   int stepXDistance = calculateStepDistance(radius * 2, stepsPerHemisphere);
  
  //부호변환 변수 (1:양수, -1:음수)
  int signMultiplier = 1;
  int x = -radius;
  int y;
  Control[] controls = composite.getChildren();
  for (int i = 0; i < controlCount; i++) {
   Point currSize = controls[i].getSize();
   long xSquared = x * x;
 
    int sqrRoot = (int) Math.sqrt(radiusSquared - xSquared);
   y = signMultiplier * sqrRoot;
   
   //원점이 아닌 원을 중심으로 좌표값을 반환한다.
   int translatedX = x + center.x;
   int translatedY = y + center.y;
   positions[i] = new Point(translatedX - (currSize.x / 2), 
                      translatedY - (currSize.y / 2));
 
    x = x + (signMultiplier * stepXDistance);
   //위쪽 반원은 완료됨. 아래쪽 반윈에 대해 수행.
   // we've finished the upper hemisphere, now do the lower
   if (x >= radius) {
    x = radius - (x - radius);
    signMultiplier = -1;
   }
  }
 
   return positions;
 }
 
  /**
  * 선호하는 가장 큰 값 구하기
  * @param controls
  * @return
  */
 private Point calculateMaxDimensions(Control[] controls) {
  Point maxes = new Point(0, 0);
 
   for (int i = 0; i < controls.length; i++) {
   Point controlSize = controls[i].computeSize(SWT.DEFAULT,
     SWT.DEFAULT);
   maxes.x = Math.max(maxes.x, controlSize.x);
   maxes.y = Math.max(maxes.y, controlSize.y);
  }
 
   return maxes;
 }
 
  private int stepsPerHemisphere(int totalObjects) {
  return (totalObjects / 2) - 1;
 }
 
  /**
  * 위젯의 가로길이 구하기
  * @param clientAreaDimensionSize
  * @param stepCount
  * @return
  */
 private int calculateStepDistance(int clientAreaDimensionSize, int stepCount) {
  return clientAreaDimensionSize / (stepCount + 1);
 }
 
}




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.swtjface.Ch6;
 
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
 
public class Ch6RadialLayoutComposite extends Composite {
 
  public Ch6RadialLayoutComposite(Composite parent) {
  super(parent, SWT.NONE);
  setLayout(new RadialLayout());
 
   for (int i = 0; i < 8; i++) {
   Button b = new Button(this, SWT.NONE);
   b.setText("Cell " + (i + 1));
  }
 
  }
}



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
package com.swtjface.Ch6;
 
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 RadialLayoutTest extends ApplicationWindow {
 public RadialLayoutTest() {
  super(null);
 }
 
  protected Control createContents(Composite parent) {
  Ch6RadialLayoutComposite ca = new Ch6RadialLayoutComposite(parent);
 
   getShell().setText("Widget Window");
  return parent;
 }
 
  public static void main(String[] args) {
  RadialLayoutTest tc = new RadialLayoutTest();
  tc.setBlockOnOpen(true);
  tc.open();
  Display.getCurrent().dispose();
 }
 
}





▶ 실행결과