Java 2D 시작하기

Java 2D API는 핵심 Java 1.2 플랫폼 API입니다 (API 및 해당 구현에 대한 다양한 정보는 참고 자료 참조). API 구현은 Windows NT / 95 및 Solaris 용 Sun JDK의 현재 베타 릴리스에서 JFC (Java Foundation Classes)의 일부로 제공됩니다. Java 1.2가 완성되면 Java 2D를 더 많은 플랫폼에서 사용할 수 있습니다.

Java 2D는 JFC의 다른 부분과 다소 독립적으로 개발되었지만 그럼에도 불구하고 1.2 AWT의 핵심 부분입니다. 우리는 구별을하고 논의를 위해 2D 특정 기능을 지적 할 것이지만,이 기능은 이전 1.0 및 1.1 AWT 지원만큼 1.2 그래픽의 중심이라는 점을 기억해야합니다.

Java 2D는 2D 그래픽 그리기, 텍스트 및 글꼴 조작, 이미지로드 및 사용, 색상 및 색상 공간 정의 및 처리를위한 이전 AWT 메커니즘을 확장합니다. 우리는 이번 칼럼과 향후 칼럼에서 이러한 새로운 메커니즘을 탐구 할 것입니다.

명명법 및 규칙에 대한 참고 사항

이 칼럼에서 필자의 기본 개발 플랫폼은 Windows 95 또는 Windows NT를 실행하는 PC입니다. 가능한 경우 다른 플랫폼 별 팁과 요령을 제공하고 싶지만 Windows에서 대부분의 시간을 보낼 것이므로 Windows에 집중할 것입니다.

메소드 이름을 작성할 때 항상 형식이어야합니다 methodname(). 후행 괄호는이를 메서드로 구분하기위한 것입니다. 메소드는 매개 변수를 사용하거나 사용하지 않을 수 있습니다. 실제로 컨텍스트는 항상이를 명확히해야합니다.

소스 코드 목록은 줄 번호가 포함 된 상태로 제공됩니다. 줄 번호를 사용하여 기사 텍스트와 코드 목록을 적절하게 상호 참조 할 계획입니다. 이렇게하면 복사본을 인쇄하도록 선택한 경우 열에 주석을 추가하기가 훨씬 쉬워집니다. 그러나 열에서 링크 된 소스 파일은 일반 * .java 파일 (sans 줄 번호)이므로 다운로드 및 개발할 수 있습니다.

앞으로 몇 달 내에 많은 미디어 및 통신 API에 대해 작성할 예정이므로 모든 샘플 코드가 개별 부분뿐만 아니라 전체적으로 의미가 있는지 확인하고 싶습니다. 나는 일관되게 내 예제의 이름을 지정하고 감각적 인 패키지에 배치하려고 시도 할 것입니다.

내 패키지 계층 구조의 맨 위는 다음과 같습니다.

com.javaworld.media 

내가 작성하는 각 API 또는 주제에는이 최상위 수준 아래에 하나 이상의 하위 패키지가 있습니다. 예를 들어이 Java 2D 기사의 모든 코드는 다음 위치에 있습니다.

com.javaworld.media.j2d 

따라서 Java 2D에서 첫 번째 예제 애플리케이션을 호출하려면 코드를 다운로드하고 클래스 경로에 넣은 다음 다음을 사용합니다.

java com.javaworld.media.j2d.Example01 

(네임 스페이스가 원하는만큼 너무 길거나 다른 이유로 정규화 된 이름을 사용하지 않고 예제 코드를 사용하려는 경우 각 소스 코드 파일의 시작 부분에있는 패키지 줄을 주석 처리하면됩니다.)

각 기사의 예제 코드와 클래스 파일에 대해 Java 아카이브 (jar) 파일을 생성합니다. 이 아카이브를 다운로드하고 아카이브 내에서 예제를 실행하려면 각 열의 리소스에서 사용할 수 있습니다.

또한 현재 및 이전 미디어 프로그래밍 열의 모든 코드와 클래스가 포함 된 최신 jar 파일을 유지합니다 . 이 포괄적 인 jar 파일은 내 개인 웹 사이트에서 사용할 수 있습니다.

예제에 대한 마지막 요점 : 별도로 언급하지 않는 한, 독립 실행 형 응용 프로그램이나 애플릿을 각 예제로 만들기로 선택했습니다. 이로 인해 때때로 코드가 약간 반복되지만 각 개별 예제의 무결성을 가장 잘 보존한다고 생각합니다.

관례에 대해 충분합니다. Java 2D로 프로그래밍을 시작합시다!

Graphics2D : 더 나은 그래픽 클래스

Java 2D API의 중심 클래스는 2D 렌더링 기능을 확장 java.awt.Graphics2D하는 하위 클래스 인 추상 클래스 java.awt.Graphics입니다. Graphics2D다양한 모양의 조작에 대한보다 균일 한 지원을 추가하여 사실상 텍스트, 선 및 기타 모든 종류의 2 차원 모양을 기능과 유용성면에서 비교할 수있게 만듭니다.

Graphics2d참조 를 얻고 사용하는 방법을 보여주는 간단한 예부터 시작하겠습니다 .

001 패키지 com.javaworld.media.j2d; 002003 import java.awt. *; 004 import java.awt.event. *; 005006 public class Example01 extends Frame {007 / ** 008 * Example01 객체를 인스턴스화합니다. 009 ** / 010 public static void main (String args []) {011 new Example01 (); 012} 013 014 / ** 015 * Example01 생성자는 프레임의 크기를 설정하고 016 * 시각적 구성 요소를 추가 한 다음 사용자에게 표시되도록합니다. 017 * 프레임을 닫는 사용자를 처리하기 위해 어댑터 클래스를 사용합니다. 019 ** / 020 public Example01 () {021 // 프레임 제목. 022 super ( "자바 2D 예제 01"); 023024 // 프레임의 크기를 설정합니다. 025 setSize (400,300); 026 027 // Visible 매개 변수를 true로 설정하여 // 프레임 028의 가시성을 켜야합니다. 029 003031 // 자,032 //이 프레임은 창이 닫힐 때 사용됩니다. 이를 위해 033 // 익명 내부 클래스 어댑터를 사용합니다. 034 addWindowListener (new WindowAdapter () 035 {public void windowClosing (WindowEvent e) 036 {dispose (); System.exit (0);} 037} 038); 039} 040 041 / ** 042 * 페인트 방법은 진정한 마법을 제공합니다. 여기서 우리는 Graphics 객체를 Graphics2D로 캐스트하여 044 * 그래픽과 함께 사용하던 045 * Graphics2D와 동일한 이전 그래픽 기능을 사용할 수 있음을 설명합니다. 046 ** / 047 public void paint (Graphics g) {048 // 다음은 너비 049 // 200, 높이 200, x = 50, y = 50에서 시작하는 정사각형을 그리는 방법입니다. 050 g.setColor (Color.red); 051 g.drawRect (50,50,200,200); 052 053 //하자색상을 파란색으로 설정 한 다음 Graphics2D 054 // 객체를 사용하여 정사각형에서 오프셋 된 직사각형을 그립니다. 055 // 지금까지 Graphics2D를 사용하여 수행 한 작업은 없습니다. (우리는 실제로 057 // Graphics에서 상속 된 Graphics2D 메서드를 사용합니다.) 058 Graphics2D g2d = (Graphics2D) g; 059 g2d.setColor (Color.blue); 060 g2d.drawRect (75,75,300,200); 061} 062}

Example01을 실행하면 아래 그림과 같이 빨간색 사각형과 파란색 사각형이 표시됩니다. Windows NT / 95 버전의 JDK 1.2 베타 3 (이 열에서 가장 최근의 1.2 릴리스)에는 알려진 성능 문제가 있습니다. 이 예제가 시스템에서 너무 느리다면 JavaWorld Java Tip 55에 설명 된대로 버그를 해결해야 할 수 있습니다 (이 팁은 아래 리소스 참조).

Graphics개체를 직접 인스턴스화하지 않는 것처럼 개체도 인스턴스화하지 않습니다 Graphics2D. 오히려 자바 런타임은 렌더링 객체를 생성하고이를 paint()(Example01 코드 목록의 047 행)에 전달하며, Java 1.2 플랫폼 이상에서이 객체는 Graphics2D추상 클래스도 구현합니다 .

지금까지 우리는 2D 그래픽 기능에 특별히 특별한 작업을하지 않았습니다. 이전 예제의 paint()메서드 끝에 몇 가지 코드를 추가 하고 Java 2D에 새로운 몇 가지 기능을 가져 오겠습니다 (Example02).

001 / ** 002 * 여기서는 affine 003 * transforms 및 Shape 객체 (이 경우 일반 004 * one, GeneralPath)와 같은 새로운 Java 2D API 기능을 사용합니다. 005 ** / 006 public void paint (Graphics g) {007 g.setColor (Color.red); 008 g.drawRect (50,50,200,200); 009010 Graphics2D g2d = (Graphics2D) g; 011 g2d.setColor (Color.blue); 012 g2d.drawRect (75,75,300,200); 013 014 // 이제 다른 직사각형을 그리겠습니다. 이번에는 015 // GeneralPath를 사용하여 세그먼트별로 세그먼트를 지정해 보겠습니다. 016 // 또한, AffineTransform을 사용하여이 017 // 사각형을 장치 공간 (따라서 처음 두 개의 사변형)을 기준으로 // 변환하고 회전 할 것입니다. 019 // 또한 색상을 변경합니다. 020 GeneralPath 경로 = new GeneralPath (GeneralPath.EVEN_ODD); 021 경로 .moveTo (0.0f, 0.0f); 022 경로 .lineTo (0.0f, 125.0f); 023 화024 경로 .lineTo (225.0f, 0.0f); 025 경로 .closePath (); 026 027 AffineTransform at = new AffineTransform (); 028 at.setToRotation (-Math.PI / 8.0); 029 g2d.transform (at); 030 at.setToTranslation (50.0f, 200.0f); 031 g2d.transform (at); 032 033 g2d.setColor (Color.green); 034 g2d.fill (경로); 035}

이후 있습니다 GeneralPath에 위치한 java.awt.geom패키지, 우리는 반드시 우리가 가져 오기 줄을 추가뿐만 아니라 할 필요가 :

import java.awt.geom. *; 

Example02의 출력은 다음 그림에 나와 있습니다.

Java 2D는 java.awt.Shape인터페이스를 사용하여 임의의 모양을 지정할 수 있습니다. 직사각형, 다각형, 2D 선 등과 같은 다양한 기본 모양이이 인터페이스를 구현합니다. 유연성 측면에서 가장 흥미로운 것 중 하나는 java.awt.geom.GeneralPath.

GeneralPath를 사용하면 임의의 수의 가장자리와 잠재적으로 매우 복잡한 모양이있는 경로를 설명 할 수 있습니다. Example02에서는 직사각형 (020-025 선)을 만들었지 만 다른면을 추가하여 오각형, 칠각형 또는 다른 여러면을 가진 다각형을 만들 수있었습니다. 또한 표준 Graphics코드 와 달리 Java 2D에서는 정수 대신 부동 소수점 숫자를 사용하여 좌표를 지정할 수 있습니다. 세계의 CAD 벤더 여러분, 기뻐하십시오! 사실, 자바 2D 지원 integer, double그리고 floating많은 장소에서 연산.

또한 경로를 만들 때 GeneralPath.EVEN_ODD생성자에 매개 변수를 전달했습니다 (020 행). 이 매개 변수는 경로에 지정된 모양의 내부를 결정하는 방법을 렌더러에게 알려주 는 굴곡 규칙 을 나타냅니다 . Java 2D 와인딩 규칙에 대한 자세한 내용은 참고 자료에서 참조 된 Java 2D javadoc 문서를 참조하십시오.

Example02의 다른 주요 혁신은 java.awt.geom.AffineTransforms (027-031 행)를 사용하는 것입니다. 이러한 변환의 세부 사항은 독자에게 맡기지 만 (자세한 내용은 리소스를 참조하십시오) AffineTransformJava 2D 그래픽에서 작업하여 변환 (이동)하고 회전 할 수 있다고 말하면 충분 합니다. , 크기 조정, 전단 또는 이러한 조작의 조합을 수행합니다.

핵심 AffineTransform장치 공간사용자 공간 의 개념에 있습니다. 장치 공간은 그래픽이 화면에 렌더링되는 영역입니다. 이는 일반 AWT 스타일 Graphics기반 2D 그래픽을 만들 때 사용되는 좌표와 유사 합니다. 그러나 사용자 공간은 하나 이상의에 의해 작동 될 수있는 변환 가능하고 회전 가능한 좌표계 AffineTransform입니다.

처음에는 장치 공간 및 사용자 공간 좌표계가 렌더링 표면의 왼쪽 상단에있는 원점 (여기서는 프레임)과 겹칩니다. 양의 x 축은 원점에서 오른쪽으로 이동하고 양의 y 축은 아래로 이동합니다.

Example02의 첫 번째 변환 (028 및 029 행) 이후 사용자 공간 좌표계는 장치 공간을 기준으로 시계 반대 방향으로 22.5도 회전되었습니다. 둘 다 여전히 같은 기원을 공유합니다. (회전은 -PI / 8 라디안이 -22.5도 또는 22.5도 CCW와 같은 라디안으로 지정됩니다.) 여기서 멈추고 직사각형을 그리면 대부분의 시야를 벗어납니다. 신청 Frame.

다음으로 두 번째 변환 (030 및 031 행)을 적용합니다.이 변환은 회전이 완료된 후 변환입니다. 이렇게하면 장치 공간을 기준으로 사용자 공간 좌표계가 이동하여 200.0 (부동) 단위 아래로 이동하고 오른쪽 50.0 (부동) 단위로 이동합니다.

녹색 사각형을 채우면 장치 공간을 기준으로 변환 및 회전됩니다.

베 지어 및 더 높은 순서의 곡선

Now that we have examined how transforms can be used to manipulate graphical objects, let's reexamine how we build complex and interesting arbitrary shapes.

Curves are used throughout mathematics and computer graphics to approximate complex shapes using a finite, well-defined (and ideally small) number of mathematical points. Whereas the standard AWT did not directly support drawing with arbitrary curves in the past (Java 1.0 or 1.1 platforms), Java 2D adds built-in support for first-, second-, and third-order curves. You can draw curves with two end points and zero, one, or two control points. Java 2D computes first- and second-order curves using linear and quadratic formulas and cubic, or third-order, curves using Bezier curves.

(베 지어 곡선은 닫힌 곡선 및 표면의 계산과 관련하여 매우 바람직한 속성이있는 파라 메트릭 다항식 곡선의 한 유형입니다. 이들은 수많은 그래픽 응용 프로그램에서 사용됩니다. 파라 메트릭 다항식 및 베 지어 곡선 사용에 대한 자세한 내용은 리소스를 참조하십시오. 컴퓨터 그래픽에서.) GeneralPath이러한 각 곡선을 그리는 방법은 다음과 같습니다.

  • lineTo() 직선 세그먼트의 경우 (끝점 만 지정)
  • quadTo() 2 차 곡선의 경우 (하나의 제어점 지정)
  • curveTo() 3 차 곡선의 경우 (입방 형 베 지어 곡선을 사용하여 그린 두 개의 제어점 지정)