104
1 บทที1 บทนํJava 2D เปนสวนหนึ่งของ JFC (Java Foundation Class) ของ Java 2 ชวยในการแสดงผลจากการคํานวณ ทางโปรแกรมออกมาเปนภาพกราฟฟก 2 มิติ คือ กวาง และ ยาว มีสวนประกอบหลัก ดังนี1. การแสดงดานเสน รูปราง 2. การแสดงดานตัวอักษร 3. การแสดงดานการระบายสี 4. การแสดงดานภาพ 5. การเคลื่อนยาย ขยาย หมุน และ ตัดภาพ 6. การประมวลผลภาพ 7. การ พิมพภาพ ที่แสดงออกทาง PRINTER Java 2D อยูใน java.awt.Graphics2D ซึ่งเปนรูปแบบใหมที่ขยายมาจาก Graphics ซึ่งในการแสดงภาพออก มานั้น ในโปรแกม java จะผานทาง method : paint ,paintAll ,update ,print, printAll,getGraphics public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; ... } การแสดงตําแหนงภาพจะใชแกน X แกนY รูปที(1-1) แสดงแกน X แกนY

JAVA2D Thai

Embed Size (px)

DESCRIPTION

JAVA2D program command and example.เรียนรู้ จาวา ด้วยตนเอง กับ java2d.ภาษาไทย

Citation preview

Page 1: JAVA2D Thai

1

บทที่1บทนํ า

Java 2D เปนสวนหนึ่งของ JFC (Java Foundation Class) ของ Java 2 ชวยในการแสดงผลจากการคํ านวณทางโปรแกรมออกมาเปนภาพกราฟฟก 2 มิติ คือ กวาง และ ยาว มีสวนประกอบหลัก ดังนี้

1. การแสดงดานเสน รูปราง2. การแสดงดานตัวอักษร3. การแสดงดานการระบายสี4. การแสดงดานภาพ5. การเคลื่อนยาย ขยาย หมุน และ ตัดภาพ6. การประมวลผลภาพ7. การ พมิพภาพ ที่แสดงออกทาง PRINTER

Java 2D อยูใน java.awt.Graphics2D ซ่ึงเปนรูปแบบใหมที่ขยายมาจาก Graphics ซ่ึงในการแสดงภาพออกมานั้น ในโปรแกม java จะผานทาง method : paint ,paintAll ,update ,print, printAll,getGraphics

public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; ...

}

การแสดงตํ าแหนงภาพจะใชแกน X แกนY

รูปท่ี(1-1) แสดงแกน X แกนY

Page 2: JAVA2D Thai

2

การแสดงภาพจะสนับสนุนกับการใช java Swing และ java AWT ซ่ึงใชชุด packet สํ าหรับการแสดงภาพติดตอกับผูใชงาน

Java 2D มี คลาส ตนแบบบรรจุอยูใน Package ดังนี้• java.awt • java.awt.geom• java.awt.font • java.awt.color• java.awt.image • java.awt.image.renderable• java.awt.print

ชุด java.awt จะบรรจุ class และ interface ไวทั้งหมด โดยมี คลาส ดังนี้AlphaComposite BasicStroke ColorComposite CompositeContext FontGradientPaint Graphics2D GraphicsConfigurationGraphicsDevice GraphicsEnvironment PaintPaintContext Rectangle ShapeStroke TexturePaint Transparency

ชุด java.awt.geom บรรจุ class และ interface ทีเ่กี่ยวของกับภาพรูปรางตางๆ ดังนี้AffineTransform Arc2D Arc2D.DoubleArc2D.Float Area CubicCurve2DCubicCurve2D.Double CubicCurve2D.Float Dimension2DEllipse2D Ellipse2D.Double Ellipse2D.FloatFlatteningPathIterator GeneralPath Line2DLine2D.Double Line2D.Float PathIteratorPoint2D Point2D.Double Point2D.FloatQuadCurve2D QuadCurve2D.Double QuadCurve2D.FloatRectangle2D Rectangle2D.Double Rectangle2D.FloatRectangularShape RoundRectangle2D RoundRectangle2D.DoubleRoundRectangle2D.Float

ชุด java.awt.font บรรจุ class และ interface ทีเ่กีย่วของกับการเขียนตัวอักษร มี ดังนี้

Page 3: JAVA2D Thai

3

FontRenderContext GlyphJustificationInfo GlyphMetricsGlyphVector GraphicAttribute ImageGraphicAttributeLineBreakMeasurer LineMetrics MultipleMasterOpenType ShapeGrapicAttribute TextAttributeTextHitInfo TextLayout TransformAttribute

ชุด java.awt.color บรรจุ class และ interface ซ่ึงเปนการใชงานเกี่ยวกับ สี และแฟมสีตางๆที่จะนํ ามาแสดงผลมี ดังนี้ColorSpace ICC_ColorSpace ICC_ProfileICC_ProfileGray ICC_ProfileRGB

ชุด java.awt.image และ java.awt.image.renderable เปนชุด package บรรจุ class และ interface สํ าหรับการประมวลผลภาพเพื่อแสดงผลแบบตางๆ มีดังนี้AffineTransformOp BandCombineOp BandedSampleModelBufferedImage BufferedImageFilter BufferedImageOpByteLookupTable ColorConvertOp ColorModelComponentColorModel ComponentSampleModel ConvolveOpContextualRenderedImageFactory DataBufferDataBufferByte DataBufferInt DataBufferShortDataBufferUShort DirectColorModel IndexColorModelKernel LookupOp LookupTableMultiPixelPackedSampleModel PackedColorModel ParameterBlockPixelInterleavedSampleModel Raster RasterOpRenderableImage RenderableImageOp RenderableImageProducerRenderContext RenderedImageFactory RenderedImageRescaleOp SampleModel ShortLookupTableSinglePixelPackedSampleModel TileObserverWritableRaster WritableRenderedImage

ชุด java.awt.print บรรจุ classe และ interface ที่ทํ าใหการพิมพเกี่ยวกับ ตัวอักษร กราฟฟก และ ภาพใน Java 2Dมีดังนี้Book Pageable PageFormat

Page 4: JAVA2D Thai

4

Paper Printable PrinterGraphicsPrinterJob

คํ าสั่งวาด สํ าหรับ java 2D นั้นจะทํ าทาง fill(), draw(), drawString() และ drawImage() ซ่ึงเปนmethod จากGraphics2D กลาวคือ

- ถาเปน instances ของ class เกีย่วกับรูปราง (shape)ใช การ render ดวย fill() หรือ draw() กไ็ด โดยถาใช fill() การแสดงรูปรางนั้นจะมีพื้นที่ภายในถูกระบายสีปด แตถาใช draw() การแสดงรูปรางภายในจะเปนแบบเปด แสดงเพียงเสนขอบเทานั้น

- ตัวอักษร (text) อาจเปน Strings หรือ array ของ chars การ render ใช drawString()- ถาเปน instances ของ รูปภาพ (image) การ render ใช drawImage()

Page 5: JAVA2D Thai

5

บทที่ 2การแสดงดานเสนและรูปราง

การแสดงดานเสนและจุด ใชในการทํ ากราฟตางๆ จะอยูใน Class java.awt.geom.*; และ java.awt.*; โดยคํ าสั่งที่ นาสนใจ ในการโปรแกรมมีดังนี้

Points2Dใน Java2D มี package java.awt.geom สํ าหรับเก็บคลาสที่ใชแสดงรูปรางหรือวัตถุทางเรขาคณิตเชน คลาส

Point2D สํ าหรับใชแสดงจุดหนึ่งจุดใน user space คือมีคาของ x และ y สังเกตวา point ไมใช pixel เนื่องจาก pointไมมขีนาดแต pixel มีขนาด เราใช Points ในการกํ าหนดรูปรางของวัตถุเรขาคณิต แตเราใช pixel การ rendering

คลาส Points2D เปน abstract class สวนคลาสที่ขยายจาก Points2D ซ่ึงใชงานได คือ คลาส Points2D.Floatกบั Points2D.Double เปน static inner ของคลาส Points2D สังเกตวาคลาสทั้งสองนี้ใหความถูกตอง (precision)มากกวา คลาส Point ที่อยูใน java.awt ซ่ึงเก็บไดแตคา integer โดยทั่วไป หากตองการความเร็วก็เลือกใชPoints2D.Float เพราะการคํ านวณเลข float เร็วกวา Double แตหากตองการความเร็วก็เลือกใช Points2D.Double

รูปแบบโครงสรางคลาสทั้งสองมี constructors ดังนี้public Point2D.Double( ):public Point2D.Double(double x, double y);public Point2D.Float( );public Point2D.Float(float x, float y); สํ าหรับ x และy เปนตํ าแนงในการวาง Points2D

Methodคลาส Point2D มี methods สํ าหรับคํ านวณระยะระหวางจุดที่เปนเจาของ instance นั้นกับจุดที่เปนพารา

มิเตอรpublic static double distance(double X1, double Y1, double X2, double Y2);public double distance(Point2D pt);

Page 6: JAVA2D Thai

6

BasicStrokeอยูใน Class : java.awt.BasicStroke ;

รูปแบบโครงสรางBasicStroke();

โครงสรางสํ าหรับสราง BasicStroke ตวัใหมBasicStroke(float width) ;

โครงสรางสํ าหรับสราง ความกวางของเสน BasicStrokeBasicStroke(float width, int cap, int join) ;

โครงสรางสํ าหรับสราง เสน BasicStroke ที่มีลักษณะเฉพาะตัวBasicStroke(float width, int cap, int join, float miterlimit) ;

โครงสรางสํ าหรับสราง เสน BasicStroke ที่มีลักษณะเฉพาะตัวBasicStroke(float width, int cap, int join, float miterlimit, float[] dash, float dash_phase) ;

โครงสรางสํ าหรับสราง เสน BasicStroke ที่มีลักษณะเฉพาะตัว

สํ าหรับโครงสราง BasicStroke อธิบายไดดังนี้BasicStroke( float width, int cap , int join, float miterlimit, float[] dash, float dash_phase)

คาตัวแปรwidth ความกวางของเสนcap ลักษณะปลายของเสน

รูปท่ี(2-1) แสดงลักษณะปลายของเสน

Page 7: JAVA2D Thai

7

join ลักษณะเสนที่มาบรรจบกัน

miterlimidash

dash_pha

ตวัอยางก…BasicStro g2.setStrog2.drawR…

คํ าอธิบายคํ า

ส่ังวางเสนเร่ิมตนที่ 3

สํ า

รูปท่ี(2-2) แสดงลักษณะเสนที่มาบรรจบกันt คาจ ํากัดของความเรียบรอยของเสนที่มาบรรจบกัน จะมีการลบปลายมุมที่ชนกันเทาไหร

รูปแบบของเสนประ ตัวที่หนึ่งเปนเสนทึบ ตัวเลขตัวที่สองเปนระยะหางสลับกันไปเรื่อยๆคอื new float[]{0,6,0,6}

se การปรับคา offset ของการเริ่มเสนประ

ารโปรแกรม

ke dotted = new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0, new float[]{0,6,0,6}, 0);ke(dotted);ect(3,3,w-6,h-6);

สั่งแรกเปนการสรางเสนประ BasicStroke ใหมโดยมีลักษณะเฉพาะตัว ช่ือ dotted คํ าสั่งชุดที่สองเปนคํ าประ dotted ลงบนพื้นหลังคือ g2 และ คํ าสั่งชุดที่ สามเปนคํ าสั่งวาดรูปสี่เหล่ียมขนาด w-6,h-6 และมี จุด,3หรับคํ าสั่ง g2.drawLine(x1, y1, x2, y2);เปนคํ าสั่งสํ าหรับวาดเสนโดยเริ่มตนที่ x1,y1 ถึงเสน x2,y2

รูปท่ี(2-3) แสดงผลของโปรแกรม

Page 8: JAVA2D Thai

8

Lind2Dอยูใน Class : java.awt.geom.*; ,มี Class ภายในยอยอีก 2 Class คือ Lind2D.Double และ Lind2D.Float

รูปแบบโครงสรางLine2D.Double(double X1, double Y1, double X2, double Y2)

โครงสรางการใช Line2D ดวยตํ าแหนงตัวเลขแบบ double.Line2D.Double (Point2D p1, Point2D p2)

วางต ําแหนงปลายเสนของเสนตรง ดวยตํ าแหนง ของ จุด Point2DLine2D.Float(float X1, float Y1, float X2, float Y2)

โครงสรางการใช Line2D ดวยตํ าแหนงตัวเลขแบบ floatLine2D.Float(Point2D p1, Point2D p2) วางตํ าแหนงปลายเสนของเสนตรง ดวยตํ าแหนง ของ จุด Point2D

Methodpublic void setLine(double X1, double Y1, double X2, double Y2)

เปน Method สํ าหรับวางตํ าแหนงปลายเสนของเสนตรง ดวยตํ าแหนงตัวเลขแบบ double.public void setLine(float X1, float Y1, float X2, float Y2) เปน Method สํ าหรับวางตํ าแหนงปลายเสนของเสนตรง ดวยตํ าแหนงตัวเลขแบบ float

การใชงาน Line2D สามารถอธิบายไดดังนี้

Line2D.Double(double X1, double Y1, double X2, double Y2)คาตัวแปรX1, Y1 เปนตํ าแหนงเริ่มตน ดวยตํ าแหนงตัวเลขแบบ double.X2, Y2 เปนตํ าแหนงปลายทางของเสน ดวยตํ าแหนงตัวเลขแบบ double.

Line2D.Float(float X1, float Y1, float X2, float Y2)คาตัวแปรX1, Y1 เปนตํ าแหนงเริ่มตน ดวยตํ าแหนงตัวเลขแบบ floatX2, Y2 เปนตํ าแหนงปลายทางของเสน ดวยตํ าแหนงตัวเลขแบบ float

Page 9: JAVA2D Thai

9

Line2D.Double (Point2D p1, Point2D p2) และLine2D.Float(Point2D p1, Point2D p2)คาตัวแปรp1, p2 เปนตํ าแหนงจุดเริ่มตนและจุดปลาย

public void setLine(double X1, double Y1, double X2, double Y2) และpublic void setLine(float X1, float Y1, float X2, float Y2)คาตัวแปรเปน Method ทีใ่ชกับตัวแปรแบบ Instance โดยX1, Y1 เปนตํ าแหนงเริ่มตนX2, Y2 เปนตํ าแหนงปลายทางของเสน

ตวัอยางการโปรแกรม….Line2D.Double line = new Line2D.Double(0.0,0.0,5.5,10.0);g2.draw(line);….

คํ าอธิบายค ําสั่งบรรทัดแรกเปนคํ าสั่งการสรางตัวแปรแบบ Instance Class Line2D.Double ช่ือ line โดยมีตํ าแหนง

เร่ิมตนคือ x = 0.0 และ y = 0.0 ต ําแหนงปลายทางของเสน x = 5.5 และ y = 10.0คํ าสั่งบรรทัดสอง เปนคํ าสั่งวาดเสนบน Background คือ g2ตัวเลข double มีคาตั้งแต –17E308 ถึง 1.7E308 เชน 257.34ตัวเลข float มีคาตั้งแต –34E38 ถึง 3.4E38 เชน 1.8f

Page 10: JAVA2D Thai

10

QuadCurve2Dใน package java.awt.geom มีคลาส QuadCurve2D เปน abstract class ที่ทํ าการ implements Shape ใชสราง

คลาสที่กํ าหนดเสน quadCurve2D parametic curve ซ่ึงนํ าไปวาดไดดวย draw( ) ของคลาส Graphics2D ในคลาสนี้มคีลาส quadCurve2D.float และ quadCurve2D.Double เปน static inner classes ซ่ึงทั้งสองเปนคลาสลูกของ QuadCurve2D ที่ใชงานรูปแบบโครงสรางpublic QuadCurve2D.Float();public QuadCurve2D.Float(float x1, float y1, float ctrlx, float ctrly, float x2, float y2);public QuadCurve2D.Double();public QuadCurve2D.Double(double x1, double y1, double ctrlx, double ctrly, double x2, double y2);

ถาใช empty constructors ก็ตองใช setCurve ( ) กํ าหนดจุดทั้งสามใหภายหลัง สวน constructors ที่ไม empty มพีารามิเตอรสองตัวแรกกํ าหนด point 1 ของปลายดานหนึ่ง พารามิเตอรสองตัวตอมากํ าหนดจุด control point และพารามิเตอรสองตัวสุดทายกํ าหนด point 2 ของปลายอีกดานหนึ่ง ดังในรูปนี้

รูปท่ี(2-4) แสดงการใช Quadcurved2D

Page 11: JAVA2D Thai

11

CubicCurve2Dใน package java.awt.geom มีคลาส CubicCurve2D เปน abstract class ที่ทํ าการ implements Shape ใช

สรางคลาสที่กํ าหนดเสน cubic paramentric curve (มีสมการเปน y=ax2+bx2+cx2+cx2+d) ทีถู่กวาดไดดวย draw()ของคลาส Graphics2D

รูปแบบโครงสรางในคลาสนี้มีคลาส CubicCurve2D ทีใ่ชงานไดมี constructors ดังนี้

public CubicCurve2D. Float () ;public CubicCurve 2D. Float (float x1, float y1, float ctrlx1, float ctrly1, float ctrlx2, float ctrly2, float x2, float y2);public CubicCurve 2D. Double () :public CubicCurve2D.Double (double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2, double ctrly2, double x2, double y2);

รูปท่ี(2-5) แสดงการใช CubicCurve2D

Page 12: JAVA2D Thai

12

RectangularShape and Rectangle2Dใน package java.awt.geom มีคลาส RectangularShape เปน abstract class ที่ implements Shape สํ าหรับ

เปนคลาสแมของคลาสที่กํ าหนดรูปสี่เหล่ียมสองมิติ

รูปแบบโครงสรางในคลาส Rectangle2D มีคลาส Rectangle2D.Float และ Rectangle2D.Double เปน static inner classes ซ่ึง

ทั้งสองเปนคลาสลูกของ Rectangle2D ที่ใชงานได มี constructors ดังนี้public Rectangle2D.Float ( ) ;public Rectangle2D.Float (float x, float y, float w, float h) ;public Rectangle2D.Double() ;public Rectangle2D.Double(double x, double y, double w, double h) ;

รูปท่ี(2-6) แสดงการใช Rectangle2D.Double

Page 13: JAVA2D Thai

13

RoundRectangle2Dใน package java.awt.geom มีคลาส RoundRectangle2D เปน abstract class ที่ขยายมาจากคลาส

RectangularSharpe สํ าหรับเปนคลาสแมของคลาสที่กํ าหนดรูปสี่เหล่ียมสองมิติที่มีมุมโคงคลาส RoundRectangle2D มี RoundRectangle2D.Float และ RoundRectangle2D.Double เปนคลาสลูก

และ static inner classes อยูภายในสํ าหรับใชกํ าหนดรูปสี่เหล่ียมสองมิติที่มีมุมโคง โดยสามารถระบุตํ าแหนง และขนาดเปน float หรือ double

รูปแบบโครงสรางpublic RoundRectang2D.Float () ;public RoundRectangle2D.Float (float x, float y, float w, float h, float arcw, float arch) ;public RoundRectang2D.Double() ;public RoundRectang2D.Double(float x, float y, float w, float h, float arcw, float arch);

รูปท่ี(2-7) แสดงการใช RoundRectangle2D.Double

Page 14: JAVA2D Thai

14

Ellipse2Dใน package java.awt.geom มีคลาส Ellipse2D เปน abstract class ทีข่ยายมาจากคลาส RectangularShape

สํ าหรับเปนคลาสแมของคลาสที่กํ าหนดรูปวงรีหรือวงกลมคลาส Ellipse2D มีคลาส Ellipse2D.Float และ Ellipse2D.Double เปนคลาสลูก และ static inner classes อยู

ภายในส ําหรับใชกํ าหนดรูปวงรีหรือวงกลม โดยสามารถระบุตํ าแหนง และขนาดเปน float หรือ double

รูปแบบโครงสรางpublic Ellipse2D.Float() :public Ellipse2D.Float(float x, float y, float w, float h) :public Ellipse2D.Double() :public Ellipse2D.Double(double x, double y, double w, double h) :

ซ่ึงจะวาดรูปวงรีที่มีจุดสมมติมุมซายบนอยูที่ตํ าแหนง x, y มคีวามกวาง และความสูงเปน w และ h ตามลํ าดบั หากความกวางเทากับความสูงจะไดรูปวงกลม หากใช empty constructors จะไดคา x, y, w และ h เปนศูนย

รูปท่ี(2-8) แสดงการใช Ellipse2D.Double

Page 15: JAVA2D Thai

15

Arc2Dใน package java.awt.geom มีคลาส Arc2D เปน abstract class ทีข่ยายมาจากคลาส RectangularShape

สํ าหรับเปนคลาสแมของคลาสที่กํ าหนดรูปเสนโคงหรือวงกลมคลาส Arc2D มีคลาส Arc2D.Float และ Arc2D.Double เปนคลาสลูก และ static inner classes อยูภายใน

สํ าหรับใชกํ าหนดเสนโคงหรือวงกลม โดยสามารถระบุตํ าแหนง และขนาดเปน float หรือ double

รูปแบบโครงสรางpublic Arc2D.Float() ;public Arc2D.Float(int type) ;public Arc2D.Float(float x, float y, float w, float h, floatstart, float extent, int type) ;public Arc2D.Float(Rectangle2D bound, floatstart, float extent, int type) ;public Arc2D.Double() ;public Arc2D.Double(int type) ;public Arc2D.Double(double x, double y, double w, double h, double start, double extent, int type) ;public Arc2D.Double(Rectangle2D bound, double start, double extent, int type) ;

ซ่ึงก ําหนดเสนโคงสวนหนึ่งของวงรีที่มีมุมซายบนอยูตํ าแหนง x, y มคีวามกวางเปน w และความสูงเปน h หรืออาจกํ าหนด x, y, w และ h ดวย Rectangle2D bound กไ็ด เสนโคงจะถูกวาดจากมุม start ไป extent องศา หนวยของมุมเปน degree ก ําหนดใหมุมที่ตํ าแหนง 3:00 นาฬกิา เปนศูนยองศา ถาคา extent เปนบวก เสนโคงจะถูกวาดทวนเข็มนาฬิกา ถาคา extent เปนลบ เสนโคงจะถูกวาดตามเข็มนาฬิกา

การวาดเสนโคงอาจถูกกํ าหนดประเภทไดดวย int type ซ่ึงอาจเปนคาใดคาหนึ่งของคาคงที่ที่กํ าหนดไวในคลาส Arc2Dดังนี้public static final int OPEN ;public static final int CHORD ;public static final int PIE ;

Page 16: JAVA2D Thai

16

Generalค

ได คลาส

รูปแบบโคpublic Gepublic Gepublic Ge

คาตัวแปรrule initialCapเรากํ าหนดถาจํ าเปน ในตอนท

รูปท่ี(2-9) แสดงการใช Arc2D.Float

Pathลาส GeneralPath เปนคลาสที่ implements Shape ใชสํ าหรับสรางคลาสที่เราสามารถกํ าหนดรูปรางใด ๆ GeneralPath อยูใน package java.awt.geom

รงสรางneralPath () ;neralPath (int rule) ;neralPath (int rule, int initialCapacity) ;

ใชสํ าหรับกํ าหนด winding rule คาที่เปนไดคือ WIND_EVEN_ODD และ WINE_NON_ZERO acity ตวัที่สองใชกํ าหนด initial capacity คอืจํ านวนจุด coordinates ของรูปรางนั้น สังเกตวาในขณะที่ รูปรางของ general path จุด coordinates ของ segments เหลานั้นจะถูกไวใน array ทีข่ยายขนาดขึ้นไป

แตจะเสยีเวลา ดังนั้นหากเราทราบจํ านวนจุดที่ถูกตองใชก็กํ าหนดเปน initial capacity เพือ่ความรวดเร็วํ างาน

Page 17: JAVA2D Thai

17

Method เรากํ าหนดรูปรางของ general path ไดโดยใชคํ าสั่ง

public void moveTo(float x,float y);public void lineTo(float x, float y);public void quadTo(float x1, float y1,float x2,float y2);public void curveTo(float x1,float y1,float x2,float y2, float x3, float y3);public void closePath();

ตวัอยางการโปรแกรม…GeneralPath eiffel = new GeneralPath();Eiffel.moveTo(20f,0f);Eiffel.lineTo(30f,0f);Eiffel.quadTo(30f,30f,50f,60f);Eiffel.lineTo(35f,60f);Eiffel.cuveTo(35f,40f,15f,40f,15f,60f);Eiffel.lineTo(0f,60f);Eiffel.quadTo(20f,30f,20f,0f);…

Page 18: JAVA2D Thai

18

รูปท่ี(2-10) แสดงการใช GeneralPath

Page 19: JAVA2D Thai

19

บทที่ 3การแสดงดานตัวอักษร

ภาษา Java เก็บแสดงตัวอักษรดวยรหัส unicode ดังนั้นการ rendering text คือการวาด shape ที่กํ าหนดไวคูกับรหัส unicode ของอักษรตัวนั้น เราเรียก shape ที่กํ าหนดไวสํ าหรับอักษรตัวหนึ่งวา glyph แมวาการ mappingระหวาง glyphs กับตัวอักษรสวนใหญจะเปนแบบหนึ่งตอหนึ่ง แตก็มีบางในบางภาษาที่อักษรมากกวาหนึ่งตัวถูกmapped ไปเปน glyph ตัวเดียว และอักษรบางตัวอาจ mapped ไปเปน glyphs มากกวาหนึ่ง ขึ้นกับตํ าแหนงของตวัอักษรนั้นในคํ าหรือประโยค

ระบบแสดงผลสวนใหญมักมีหลายๆ glyhs สํ าหรับอักษรตัวหนึ่ง เราเรียก set ของ glyphs วา font โดยปกติfont คอื glyphs ชุดหนึ่งที่กํ าหนดขึ้นสํ าหรับอักษรแตละตัวในภาษานั้น ซ่ึงนอกจากมีขอมูลเกี่ยวกับ glyphs แลวยังมีขอมลูเกี่ยวกับการ mapping ระหวางตัวอักษรกับ glyphs ดวย

Fontsภาษา Java มีคลาส font อยูใน java.awt.*; สํ าหรับใชเก็บขอมูลเกี่ยวกับ font ทํ าใหโปรแกรมสามารถเลือก

ใชงาน font ที่ติดตั้งอยูในระบบปฏิบัติการได เรากํ าหนด font ใหแก component หรือ graphics เพื่อใหใช font นั้นในการวาดตัวอักษรโดยใชpublic void setFont ( java.awt.Font ):

หากตองการทราบวา font ที่ถูกกํ าหนดไวปจจุบันเปน font ใดก็เรียกดูไดโดยใชpublic Font getFont ():

Methods ทัง้สองมีอยูทั้งในคลาส component และคลาส Graphics

รูปแบบโครงสรางpublic Font (String name ,int style, int size);

font style ม ีรูปแบบ 4 แบบ กํ าหนดดวยตัวเลข integer เลข 0-3 โดยมีคํ าอธิบายดังนี้0 เปน ตัวอักษรธรรมดา (PLAIN)1 เปน ตัวอักษรตัวหนา (BOLD)2 เปน ตัวอักษรตัวเอียง (ITALIC)3 เปน ตัวอักษรตัวหนา ผสมตัวเอียง (BOLD + ITALIC)วธีิการงายๆในการสรางลักษณะเฉพาะของ font ท ําไดดังตัวอยางตอไปนี้Font boldFont = new Font("Helvetica", Font.BOLD, 12);

Page 20: JAVA2D Thai

20

เราสามารถสราง font จาก font อ่ืนไดจาก font อ่ืน โดยการเปลี่ยน style ,size หรือการใช Affinetransformปรับการเอียง การหมุน การวางตํ าแหนง ดวยการใช methods

public Font deriveFont(int stye);public Font deriveFont(float stye);public Font deriveFont(int stye,float size);public Font deriveFont(AffineTransform f);public Font deriveFont(int stye, AffineTransform f);

ตวัอยางการโปรแกรม…Font boldFont = new Font("Helvetica", Font.BOLD, 12);Font italicDerived = boldFont.deriveFont(Font.ITALIC, 12);Font plainDerived = boldFont.deriveFont(Font.PLAIN, 14);…

LineMetrics & FontMatricsLineMetrics อยูใน java.awt.font.*; เปนชดุกลุมขอมูลเกี่ยวกับขนาดตัวอักษร ใชในการจัดขนาดตัวอักษร

โดยมี method สํ าหรับใหคารายละเอียดสวนตางๆของตัวอักษร ดังนี้public abstract float getAscent();public abstract float getDescent();public abstract float getHeight();public abstract float getLeading();

FontMetrics อยูใน java.awt.font.*; เปนชดุกลุมขอมูลเกี่ยวกับขนาดตัวอักษรเชนเดียวกับ LineMetricsใชในการจัดตัวอักษรโดยมี method สํ าหรับใหคารายละเอียดสวนตางๆของตัวอักษร ดังนี้public int getAscent();public int getDescent();public int getHeight();public int getLeading();

Page 21: JAVA2D Thai

21

F

F

คtxisu

mp

T

ja

รูปท่ี(3-1) แสดงลักษณะรายละเอียดสวนตางๆของตัวอักษร

ontRenderContextใน JAVA2D หากตองการทราบขนาดของตัวอักษรหรือ String เราตองการสราง instance ของClass

ontRenderContext ซ่ึงอยูในชุด packet java.awt.font.*;โดยมีโครงสรางดังนี้public FontRenderContext(AffineTransform tx, boolean isAntiAliased, boolean usesFractionalMetrics)

าตัวแปรเปน AffineTransform

AntiAliased เปน boolean บอกการทํ า antialiasing หรือไมsesFractionalMetrics เปน boole บอกวามีการทํ า fractional metrics หรือไม

ในการใชงานปกติจะไมนิยมการสราง แตจะการดึงขอมูลของ FontRnderContxt ปจจุบันมาใช ผานทางethod นี้

ublic abstract FontRenderContext getFontRenderContext();

extLayoutTextLayout เปนobject ใชแสดงดานกราฟฟกของ ตัวอักษร ผานทาง method ช่ือ draw อยูใน packet ของ

va.awt.font.*;โดยที่นิยมใชคือ

Page 22: JAVA2D Thai

22

public TextLayout(String string, Font font, FontRenderContext frc);

ตวัอยางการโปรแกรม…FontRenderContext frc = g2.getFontRenderContext();Font f = new Font("Helvetica",Font.BOLD, 24);String s = new String("24 Pont Helvetica Bold");TextLayout tl = new TextLayout(s, f, frc);Dimension theSize=getSize();g2.setColor(Color.green);tl.draw(g2, theSize.width/30, theSize.height/2);…

คํ าอธิบายผลของการทํ างานแสดง จะไดตัวอักษร แบบ Helvetica ตัวหนาขนาดตัวอักษร 24 มีสีเขียว มีขอความวา

"24 Pont Helvetica Bold" แสดงไดดังนี้

รูปท่ี(3-2) แสดงผลของการทํ างานโปรแกรมตัวอยาง

LineBreakMeasurerใชแสดง Text แบบทีม่ีจํ านวนบรรทัดการแสดงมากๆ อยูในpacket ของ java.awt.font.*;ไดโดยการใช

LineBreakMeasurer เปน Object ในการวาดเสนของขอความผานทาง TextLayoutโครงสรางของ LineBreakMeasurer สํ าหรับสรางขอความตัวอักษรที่มีลักษณะเฉพาะ มีดังนี้

รูปแบบโครงสรางตวัที่นิยมใชคือ

public LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc);

คาตัวแปรtext เปนขอความที่จะนํ าไปใชในการผลิต TextLayout

Page 23: JAVA2D Thai

23

frc เปนขอมูลในการแสดงดานกราฟฟกของขอความที่ถูกทํ าการวัดขนาดมาเรียบรอยแลว

Methodการใช method ของ LineBreakMeasurer มดีังนี้

public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos)เปลี่ยนแปลง LineBreakMeasurer นีห้ลังจากที่ มีตัวอักษรหนึ่งตัวถูกลบจาก text และวางตํ าแหนงปจจุบัน

ในการเริ่มยอหนา

public int getPosition() Returns คนืคาตํ าแหนงปจจุบันของ LineBreakMeasurer

public void insertChar(AttributedCharacterIterator newParagraph, int insertPos) เปลี่ยนแปลง LineBreakMeasurer นีห้ลังจากที่ มีตัวอักษรหนึ่งตัวถูกเพิ่มเขาไปใน text และวางตํ าแหนงปจจุบันในการเริ่มยอหนา

public TextLayout nextLayout(float wrappingWidth) Returns คนืคาตํ าแหนงสิ้นสุดของ layoutทีอ่ยูถัดไปและแสดงตํ าแหนงปจจุบัน

public TextLayout nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord) Returns คนืคาตํ าแหนงสิ้นสุดของ layoutทีอ่ยูถัดไปและแสดงตํ าแหนงปจจุบัน

public int nextOffset(float wrappingWidth) Returns คนืคาตํ าแหนงสิ้นสุดของ layoutทีอ่ยูถัดไป

public int nextOffset(float wrappingWidth, int offsetLimit, boolean requireNextWord) Returns คนืคาตํ าแหนงสิ้นสุดของ layoutทีอ่ยูถัดไป

public void setPosition(int newPosition) แสดงตํ าแหนงปจจุบันของ LineBreakMeasurer.

Page 24: JAVA2D Thai

24

ตวัอยางการโปรแกรมและคํ าอธิบายimport javax.swing.*;import java.awt.*;import java.awt.font.FontRenderContext;import java.awt.font.LineBreakMeasurer;import java.awt.font.TextLayout;import java.util.Hashtable;import java.text.AttributedCharacterIterator;import java.text.AttributedString;import java.awt.font.TextAttribute;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;

/** * แสดงการ line-break การวาด paragraph * และการ ใช LineBreakMeasurer กับ TextLayout.* ใน class นี้ โครงสราง LineBreakMeasurer จาก AttributedCharacterIterator.* เราใช LineBreakMeasurer สรางและวาด TextLayouts (เสนวางขอความ) * ภายใน ความกวางของComponent */

public class LineBreakSample extends JApplet {

// LineBreakMeasurer ถูกใช สํ าหรับหยุดการวางเสนวางขอความ // line-break ของ paragraph. private LineBreakMeasurer lineMeasurer; // ดัชนี ใน LineBreakMeasurer ของตัวอักขระตัวแรก ใน paragraph. private int paragraphStart; // ดัชนี ใน LineBreakMeasurer ของตัวอักขระตัวแรกหลังจากจบ paragraph.

Page 25: JAVA2D Thai

25

private int paragraphEnd;

private static final Hashtable map = new Hashtable(); static { map.put(TextAttribute.SIZE, new Float(18.0)); }

private static AttributedString vanGogh = new AttributedString( "Many people believe that Vincent van Gogh painted his best works " + "during the two-year period he spent in Provence. Here is where he " + "painted The Starry Night--which some consider to be his greatest " + "work of all. However, as his artistic brilliance reached new heights " + "in Provence, his physical and mental health plummeted. ", map);

public void init() {buildUI(getContentPane());

}

public void buildUI(Container container){ LineBreakPanel lineBreakPanel = new LineBreakPanel();

container.add(lineBreakPanel, BorderLayout.CENTER); }

class LineBreakPanel extends JPanel {

public LineBreakPanel() { AttributedCharacterIterator paragraph = vanGogh.getIterator(); paragraphStart = paragraph.getBeginIndex(); paragraphEnd = paragraph.getEndIndex();

// สราง LineBreakMeasurer ใหม จาก paragraph. lineMeasurer = new LineBreakMeasurer(paragraph,

Page 26: JAVA2D Thai

26

new FontRenderContext(null, false, false)); }

public void paintComponent(Graphics g) {

super.paintComponent(g); setBackground(Color.white);

Graphics2D graphics2D = (Graphics2D) g;

// กํ าหนด รูปแบบความกวางของ Component.Dimension size = getSize();

float formatWidth = (float) size.width; float drawPosY = 0; lineMeasurer.setPosition(paragraphStart); // ให มี เสน lineMeasurer ทั้งหมดตลอดกรอบ // แสดง paragraph while (lineMeasurer.getPosition() < paragraphEnd) { // นํ ามาแสดงอีกใน layout ถัดไป TextLayout layout = lineMeasurer.nextLayout(formatWidth); // เล่ือนตํ าแหนง y โดยการใช ascent ของ layout. drawPosY += layout.getAscent(); // คํ านวณ ตํ าแหนง x ถาให paragraph เปนจาก ขวาไป ซาย // เราตองการวาง TextLayout ถึงขอบขวาของกรอบ float drawPosX; if (layout.isLeftToRight()) { drawPosX = 0; } else { drawPosX = formatWidth - layout.getAdvance(); } // วาด TextLayout ที่ตํ าแหนง (drawPosX, drawPosY).

Page 27: JAVA2D Thai

27

layout.draw(graphics2D, drawPosX, drawPosY); // เล่ือนตํ าแหนง y ไปยัง preparation ของ layout ถัดไป drawPosY += layout.getDescent() + layout.getLeading(); }

} }

public static void main(String[] args) { JFrame f = new JFrame("HitTestSample"); f.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e) { System.exit(0); } });

LineBreakSample controller = new LineBreakSample(); controller.buildUI(f.getContentPane()); f.setSize(new Dimension(400, 250)); f.setVisible(true); }

}

Page 28: JAVA2D Thai

28

AttrybuteString & AttributedCharacterIteratorAttributedCharacterIterator เปน instance ทีอ่ยูใน java.text.*; ใชสํ าหรับสราง class ทีย่อมใหมีการจัดการ

กบัอักษรใน String ทลีะตัวอักษร(iterating) โดยแตละตัวอักษรสามารถที่จะมีขอมูลผูกติดไปดวย เชน สี รูปแบบของตัวอักษร เปนตน

AttrybuteString ใชแนวทางแบบ AttributedCharacterIterator แตมีการจัดการที่งายกวารูปแบบโครงสราง

โครงสรางที่นิยมใชคือ public AttributedString (String text);คาตัวแปรtext ขอความที่จะนํ าไปใชใน AttrybuteString

Methodpublic AttributedCharacterIterator getIterator();

ใชสราง instance ของ AttributedCharacterIterator เพื่อเตรียมนํ าขอมูลที่ผูกติดกับแตละตํ าแหนงของตัวอักขระในขอความ string ของ AttributeString มาแสดงผานทาง drawString()

public void addAttribute(AttributedCharacterIterator.Attribute attribute ,Object value);public void addAttribute(AttributedCharacterIterator.Attribute attribute,Object value,

int beginIndex , int endIndex );ใชก ําหนดคุณสมบัติของแตละตัวอักษรของขอความใน AttrybuteString

คาตัวแปรattribute เปน attribute key ถูกสรางภายใต TextAttribute Class ใน java.awt.font;value เปนคาของตัวแปร attributebeginIndex ตวัอักษรตวัแรกของขอความที่ใหคุณสมบัติเปนไปตามคาของตัวแปร attributeที่กํ าหนดไวendIndex ตวัอักษรตวัสุดทายของขอความที่ใหคุณสมบัติเปนไปตามคาของตัวแปร attributeที่กํ าหนดไว

Page 29: JAVA2D Thai

29

รูปท่ี(3-3) ตาราง แสดงAttribute Key

Attribute Key Possible valueBACKGROUND สีตางๆCHAR_REPLACEMENT ลักษณะทางกราฟฟกFAMILY Font แบบ Family FontFONT ตัวอักขระFOREGROUND สีตางๆINPUT_METHOD_HIGHLIGH ลักษณะ Heighlight ในขณะสรางขอความขึ้นINPUT_METHOD_UNDELINE ตวัเลข แบบ Integer หรือใช

UNDELINE_LOW_ONE_PIXELUNDELINE_LOW_TWO_PIXELUNDELINE_LOW_DOTTEDUNDELINE_LOW_GRAYUNDELINE_LOW_DASHED

POSTURE ตัวเลข แบบ FloatPOSTURE_REGULAR = 0POSTURE_OBLIQUE = 0.2

RUN_DIRECTION คาแบบ BoonleanRUN_DIRECTION_LTR = trueRUN_DIRECTION_RTL = false

SIZE ตัวเลข แบบ FloatSTRIKETROUGH คาแบบ Boonlean

STRIKETHROUGH_ON = TRUESUPERSCRIPT ตวัเลข แบบ Integer

SUPERSCRIPT_NONE = 0SUPERSCRIPT_SUPER = 1SUPERSCRIPT_SUB = -1

SWAP_COLORS คาแบบ BoonleanSWAP_COLORS_ON

TRANSFORM คา TransformAttribute

Page 30: JAVA2D Thai

30

Attribute Key Possible valueUNDERLINE ตวัเลข แบบ Integer

UNDERLINE_ON = 0WEIGHT ตัวเลข แบบ Float

WEIGHT_ULTRA_LIGHT = 0.25,WEIGHT_EXTRA_LIGHT = 0.5,WEIGHT_LIGHT = 0.75,WEIGHT_DEMILIGHT = 0.875,WEIGHT_REGULAR = 1.0,WEIGHT_SEMIBOLD = 1.25,WEIGHT_MEDIUM = 1.5,WEIGHT_DEMIBOLD = 1.75,WEIGHT_BOLD = 2.0,WEIGHT_HEAVY = 2.25,WEIGHT_EXTRABOLD = 2.5,WEIGHT_ULTRABOLD = 2.75

WIDTH ตัวเลข แบบ FloatWIDTH_CONDENSED = 0.75,WIDTH_SEMI_CONDENSED = 0.875,WIDTH_REGULAR = 1.0,WIDTH_SEMI_EXTENDED = 1.25,WIDTH_EXTENDED = 1.5

Page 31: JAVA2D Thai

31

ตวัอยางการโปรแกรม…String text = "Attributed Strings are fun !";AttributedString styledText = new AttributedString(text);styledText.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, 0, 10);styledText.addAttribute(TextAttribute.FOREGROUND, new Color(128, 0, 0), 0, 10);styledText.addAttribute(TextAttribute.FOREGROUND, new Color(70, 107, 132), 11, 18);styledText.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, 23, 28);styledText.addAttribute(TextAttribute.FOREGROUND, new Color(236, 214, 70), 23, 28);styledText.addAttribute(TextAttribute.BACKGROUND, new Color(70, 107, 132), 23, 28);…

คํ าอธิบาย

1 23

รูปท่ี(3-4) แสดงผลของการทํ างานโปรแกรมตัวอยาง Attributed Strings

: styledText.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, 0, 10); styledText.addAttribute(TextAttribute.FOREGROUND, new Color(128, 0, 0), 0, 10);: styledText.addAttribute(TextAttribute.FOREGROUND, new Color(70, 107, 132), 11, 18);: styledText.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, 23, 28); styledText.addAttribute(TextAttribute.FOREGROUND, new Color(236, 214, 70), 23, 28); styledText.addAttribute(TextAttribute.BACKGROUND, new Color(70, 107, 132), 23, 28);

Page 32: JAVA2D Thai

32

บทที่ 4การแสดงดานการระบายสี

การระบายสี เปนกิจกรรมของ Graphics2D ทีท่ ําการระบายภายในรูปรางดวยสีหรือ texture เราตองบอกแก Graphics2D วาจะทํ าการ paint เชนใดโดยใช methods ของคลาส Graohics2D คือPublic abstract void setPaint (Paint) ;

โดย paint เปน interface ทีอ่ยูใน java.awt.*; เมื่อเรียก setPaint() แลว graphics2D นัน้จะเก็บ paint ไว เปน data member หนึง่ จนเมื่อถูกเรียก fill() เพือ่วาด และระบายรูปรางหนึ่ง paint จงึถูกใชวาจะระบายภายในรูปรางนั้นอยางไร ซ่ึงเปนไดสามอยาง คือ

1. Solid Paint2. Gradient Paint3. Texture Paint

Solid Paintคลาส color ทํ าการ implements Paint ไวแลว หากเราเรียก setPaint() ดวยพารามิเตอรที่เปน instance ของ

คลาส Color จะทํ าให Graphics2D ท ําการระบาย (เมื่อถูกเรียก fill() ) ดวย color นั้น

Gradient PaintGradient Paint คอืการระบายดวยสีที่เปลี่ยนแปลง (อยาง linear) จากสหีนึ่งไปเปนอีกสีหนึ่ง เรากํ าหนด

gradient paint โดยจุดสองจุด และสีสองสี เชน ใหจุด p1 มีสี c1 และจุด p2 มีสี c2 จะท ําใหจุดที่อยูบนเสนตอระหวาง p1 กับ p2 มสีีที่เปลี่ยนจากสี c1 ไปเปนสี c2 อยาง linear สวนจุดที่อยูนอกเสนตออยางเชน จุด p’ จะมีสีเหมือนกับจุด p ซ่ึงเปนจุดที่ลากเสนจาก p’ มากตั้งฉากกับเสนตอระหวาง p1 กับ p2 แสดงดังรูปในหนาถัดไปนี้

รูปท่ี(4-1) แสดง gradient paint

Page 33: JAVA2D Thai

33

สวนจุดที่อยูกอนจุด p1 (ซายของเสนตั้งฉากกับเสนตอระหวางจุด p1 กับ p2 ในรปูนี้) และจุดที่อยูหลังจุด p2 (ขวาของเสนตั้งฉากกับเสนตอระหวางจุด p1 กับ p2 ในรปูนี้) จะมีสีใดขึ้นกับคาของ cyclic ซ่ึงเปน boolean ถามีคาเปน false จดุที่อยูกอนจุด p1จะมีสี c1 และจุดที่อยูหลังจุด p2 จะมีสี c2 แตถามีคาเปน true สีของจุดที่อยูกอนจุด p1 และจุดที่อยูหลังจุด p2 จะเปลี่ยนจากสี c1 ไปสี c2 ขึน้กบัระยะทางเหมือนกับการเปลี่ยนแปลงสีระหวางจุด p1 กับ p2

รูปแบบโครงสรางใน java.awt.*; มีคลาส GradientPaint สํ าหรับสราง instance ที่กํ าหนด gradient paint ม ีconstructors ดังนี้

คือpublic GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2);public GradientPaint(Point2D pt1, Color color1, Point2D pt2,Color color2);public GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2, boolean cyclic);public GradientPaint(Point2D pt1, Color color1, Point2D pt2, Color color2, boolean cyclic) ;

คาตัวแปรเราอาจกํ าหนดจุดดวย coordinate x, y ทีเ่ปน float หรือ Point2D กไ็ด โดยคูของจุด และสีแรกเปนของ pt1

และ c1 สวนคูของจุด และสีที่ตามมาเปนของ pt2 และ c2 กรณีที่ไมมีพารามิเตอรสํ าหรับ cyclic ซ่ึงเปน boolean จะไดเปน false

Texture PaintTexture Paint คือการระบายภายในรูปรางดวยรูปภาพ(texture) หากพื้นที่ของรูปรางใหญกวาพื้นที่ของ

texture รูป texture จะถูกวาดซํ้ าจนกวาจะเต็มพื้นที่ โดยปกติเราสรางรูป texture เปน instance ของคลาส Bufferedlmage ซ่ึงอาจไดภาพโดยโหลดจากไฟล image หรือวาดเปน graphics กไ็ดใน package java.awt มีคลาส TexturePaint ที่ทํ าการ implements Paint ไวแลวใชสํ าหรับกํ าหนด texture ทีเ่ปนพารามิเตอรใหแก setPaint() ได

ในการกํ าหนด texture เราตองระบุสองอยาง คือ buffered image ที่เปน texture กับ rectangle2D ซ่ึงเรียกวา tuxture rectangle ซ่ึงรูปภาพ texture จะถูก scale ใหพอดีกับ rectangle2D

รูปแบบโครงสรางPublic TexturePaint (BufferedImage, Rectangle2D) ;

เราจะกลาวถึงรายละเอียดของคลาส Bufferedlmage ภายหลังในที่นี้จะแสดงวิธีสรางรูปภาพขึ้นใน buffered image โดยการวาดเปน graphics เพือ่ใชเปน texture ดังนี้

Page 34: JAVA2D Thai

34

คลาส BufferedImage มี constructors หลายตัว แตตัวที่เราใชในตอนนี้ คือpublic BufferedImage(int width, int height, int imageType)

พารามิเตอร int width, int height เปนตัวก ําหนดขนาดกวาง และสูงของรูป สวนพารามิเตอร int imageTypeก ําหนดประเภทของ image ซ่ึงมไีดหลายแบบ ในที่นี้จะใชเปน TYPE_INT_RGB

คลาส BufferedImage มี mothodsPublic Graphics2D createGraphics() ;

สํ าหรับเรียกขอ Graphics2D เพือ่นํ าไปวาด graphics ใส buffered image นี้

ตวัอยางการโปรแกรมและคํ าอธิบาย…// สราง buffered image สํ าหรับ texture ใชผาน ขนาด 5x5BufferedImage bi = new BufferedImage(5, 5,BufferedImage.TYPE_INT_RGB);Graphics2D big = bi.createGraphics();// ประมวลผลภาพลงใน BufferedImage เพื่อสราง texturebig.setColor(Color.green);big.fillRect(0,0,5,5);big.setColor(Color.lightGray);big.fillOval(0,0,5,5);// ระบาย texture จาก buffered imageRectangle r = new Rectangle(0,0,5,5);TexturePaint tp = newTexturePaint(bi,r,TexturePaint.NEAREST_NEIGHBOR);// รวม texture paint ไปใน graphics context.g2.setPaint(tp);// สรางและประมวลผลสี่เหล่ียมที่มี texture.g2.fillRect(0,0,200,200);}…

Page 35: JAVA2D Thai

35

รูปท่ี(4-2) แสดงผลของโปรแกรม Texture Paint

Page 36: JAVA2D Thai

36

บทที่ 5การแสดงดานภาพ

BufferedImageนับตั้งแต JDK1.2 ใน java.awt.image.*; มี BufferedImage classเพิม่ขึ้นมาโดยเปน class ทีเ่พิ่มขึ้นขยายมา

จาก Image class จงึสงใหแก drawImage(); ไดเหมือน image แตมีขอดีกวาคือไมตองใช image consumer และimage proceder กลาวอีกอยางวา BufferedImage เปน writeable image

รูปแบบโครงสรางpublic BufferedImage(int width, int height, int imageType);พารามิเตอร int width และ int height เปนความกวางและความยาวของ BufferedImage สวน imageType

เปนชนิดของ BufferedImage มรีายละเอียดดังนี้

รูปท่ี(5-1) ตาราง แสดง imageType

ImageType รายละเอียด

TYPE_3BYTE_BGR 8-bit สีแบบ RGB ประกอบดวยนํ้ าเงิน,แดง,เขียว ขนาด 3 BYTETYPE_4BYTE_ABGR 8-bit สีRGBA ประกอบดวยนํ้ าเงิน,แดง,เขียว ขนาด 3 BYTE มี ALPHA 1 BYTETYPE_4BYTE_ABGR_PRE 8-bit สีRGBA ประกอบดวยนํ้ าเงิน,แดง,เขียว ขนาด 3 BYTE มี ALPHA 1 BYTETYPE_BYTE_BINARY ภาพแบบทึบแสงTYPE_BYTE_GRAY ภาพแบบขาวดํ า สีเทาไลสีTYPE_BYTE_INDEXED ภาพแบบ indexed byteTYPE_CUSTOM ภาพแบบตามความตองการที่จะสรางTYPE_INT_ARGB 8-bit สีแบบ RGBA บรรจุใน Pixel แบบ intgerTYPE_INT_ARGB_PRE 8-bit สีแบบ RGBA บรรจุใน Pixel แบบ intgerTYPE_INT_BGR 8-bit สีแบบ BGR ประกอบดวยนํ้ าเงิน,แดง,เขียว บรรจุใน Pixel แบบ intgerTYPE_INT_RGB 8-bit สีแบบ RGB ประกอบดวยนํ้ าเงิน,แดง,เขียว บรรจุใน Pixel แบบ intgerTYPE_USHORT_555_RGB แสดงภาพสแีบบ 5-5-5 RGB (5-bits แดง, 5-bits เขียว, 5-bits นํ้ าเงิน) ไมมี alpha.TYPE_USHORT_565_RGB แสดงภาพสแีบบ 5-5-5 RGB (5-bits แดง, 6-bits เขียว, 5-bits นํ้ าเงิน) ไมมี alpha.TYPE_USHORT_GRAY ภาพแบบขาวดํ า สีเทาไลสี แบบ short grayscale

Page 37: JAVA2D Thai

37

Methodpublic int getWidth();public int getHeight();

ตวัอยางการโปรแกรมและคํ าอธิบายตวัอยางแรกเปนการแสดงภาพวาดแบบ Offscreen Buffer

…public void update(Graphics g){Graphics2D g2 = (Graphics2D)g;if(firstTime){Dimension dim = getSize();int w = dim.width;int h = dim.height;area = new Rectangle(dim);bi = (BufferedImage)createImage(w, h);big = bi.createGraphics();rect.setLocation(w/2-50, h/2-25);big.setStroke(new BasicStroke(8.0f));firstTime = false;}// สรางสี่เหล่ียมอันแรก.big.setColor(Color.white);big.clearRect(0, 0, area.width, area.height);// วาดและใส รายละเอียดใหมเขาไปในรูปสี่เหล่ียม แลวสงให buffer.big.setPaint(strokePolka);big.draw(rect);big.setPaint(fillPolka);big.fill(rect);//วาด buffered image บนจอภาพg2.drawImage(bi, 0, 0, this);}

Page 38: JAVA2D Thai

38

ตวัอยางที่ 2 เปนการแสดงภาพแบบ ดวย BufferedImage…public void init() { img[0] = getToolkit().getImage("1.jpg"); img[1] = getToolkit().getImage("2.gif"); try { MediaTracker tracker = new MediaTracker(this); tracker.addImage(img[0],0); tracker.addImage(img[1],0); tracker.waitForAll(); } catch (Exception e) {} } public void drawimg(int w, int h, Graphics2D g2) { // สราง BufferedImage ช่ือ bi1 BufferedImage bi1 = new BufferedImage(w,h,BufferedImage.TYPE_BYTE_GRAY); Graphics2D big = bi1.createGraphics(); // สราง Background และวาดรูป big.setBackground(getBackground()); big.clearRect(0, 0, w, h); big.setColor(Color.green.darker()); // หาขนาดของรูป int iw = img[1].getWidth(this); int ih = img[1].getHeight(this); // วาดรูปจากภาพ big.drawImage(img[1],0,0, iw, ih, this);}…

Page 39: JAVA2D Thai

39

บทที่ 6การเคลื่อนยาย ขยาย หมุน และ ตัดภาพ

TransformationGraphics2D สามารถเปลี่ยนแปลง (transform) รูปภาพที่จะวาดไดส่ีแบบ คือ

- translation คอืการยายตํ าแหนงของรูปภาพจากจุดหนึ่งไปอีกจุดหนึ่ง- Rotation คอื การหมุนรูปภาพรอบจุดหนึ่ง- Scaling คอื การขยายหรือลดขนาดของรูปภาพ- Shear คอื การบิดรูปภาพไปในแกนใดแกนหนึ่งสังเกตวาในการเปลี่ยนแปลงรูปภาพทั้งสี่แบบนี้ หากรูปเดิมที่เสนใดที่ขนานกัน ผลที่ไดก็จะยังมีเสนเหลานั้น

ขนานกนัเชนเดิม เราเรียกการเปลี่ยนแปลงรูปภาพแบบนี้วา affine transformation ใน package java.awt.geom มีคลาส AffineTransform สํ าหรับใชในการกํ าหนด affine transformation

คลาส Graphics2D มี instance ของ AffineTransform เปน data member โดย default เพื่อใชทํ าtransformation ใหแกรูปภาพที่จะถูก rendered

MethodGraphics2D class มี methods สํ าหรับ set และ get affine transform คือ

Public abstract void setTransform(AffineTransform Tx) ;Public abstract AffineTransform getTransform() ;

โดย setTransform() จะเปลี่ยน affine transform เดมิเปนตัวใหมที่เปนพารามิเตอร ในกรณีที่เราตองการดัดแปลง affine transform เดิมก็ใชPublic abstract void transform(AffineTranform Tx) ;

ซ่ึงจะตอทาย affine transform ตวัเดมิดวยตัวที่เปนพารามิเตอรคลาส AffineTransform ก ําหนดคา transformation โดย 3×3 matrix ซ่ึงจะเปลี่ยนจุด (x, y) ไปเปน (x’, y’)

โดยแทนจุดดวย columm vector และทํ าการ transform โดยคูณดวย matrix ดังนี้

=

=

′′

++

++

1 m12 m11y m10x

02my01mx00m

1yx

*10012m11m10m02m01m00m

1yx

เรากํ าหนดการ transform ตาง ๆ ดวยคา 6 คา คือ m00, m01, m02, m11 และ m12

Page 40: JAVA2D Thai

40

คลาส AffineTransform ม ี constructors หลายตัวใหเราสามารถกํ าหนดคาในการทํ า transform แบบตางๆคา 6 คา ซ่ึงอาจจะเปน float หรือ double กไ็ด ดังนี้public AffineTransform();public AffineTransform(AffineTransform Tx) public AffineTransform(float m00, float m10, float m01, float m11, float m02, float m12);public AffineTransform(float[] flatmatrix);public AffineTransform(double m00, double m10, double m01, double m11, double m02, double m12);public AffineTransform(double[] flatmatrix);

ตวัอยางการโปรแกรม…AffineTransform aT = g2d.getTransform();g2d.transform(...);g2d.draw(...);…

Translationคอืการเลือ่นรูปภาพจากตํ าแหนงหนึ่งไปอีกตํ าแหนงหนึ่ง กํ าหนดเปน double คาสองคาคือ tx และ ty ซ่ึง

จะทํ าใหจุด x, y ใด ๆ ถูกเปลี่ยนเปน x + tx, y + ty

Methodคลาส AffineTransform มี methods หลายตัวในการทํ า translation เชน เราสามารถ get คา tx และ ty ไดโดย

ใชpublic double getTranslateX () ;public double getTranslateY () ;

ดังที่ทราบวา Graphics2D มี default affine transform อยูแลวเราสามารถเพิ่มการ translation ตอทายเขาไปใน affine transform ไดโดยใชpublic void translate (double tx, double ty) ;

Page 41: JAVA2D Thai

41

public void setToTranslation(double tx, double ty) ;ซ่ึงจะกํ าหนดคา tx และ ty เปนคา translation ใหแก affine transform นัน้ โดยคา translation เดมิที่มีจะสูญ

หายไป

public static AffineTransform getTranslateance (double tx, double ty) ;เปน factory method สํ าหรับสราง affine tranform ที่มีคา translation เปน tx และ ty ทีเ่ปนพารามิเตอรหรือ

กลาวอีกอยางหนึ่งวา method นีใ้หผลเหมือนกับการสราง affine transform ขึน้อยางวางเปลากอน แลวใชsetToTransform() ก ําหนดใหมีคา translation เปน tx และ ty แลวสง affine transform นัน้ออกมา เราตองนํ า affinetransform ทีไ่ดนั้นไปติดตั้งใหแก grapgics2D โดยใช transform()

Affine transform ทีไ่ดจาก getTranslateInstance() เปน transformation matrix ดังนี้

100ty10tx01

public void getMatrix(double [ ] ) ;ซ่ึงจะใหคาของ m00, m10, m01, m11, m02 และ m12 ของ transformation matrix ออกมาใน double d[ ]เราสราง AffineTransform a ขึน้จาก getTranslateInstance() จึงมี transform matrix ดังนี้

=

10012m11m10m02m01m00m

10020101001

เมื่อเรียก getMatrix() จะไดคาใน d [] เปน m00, m10, m01, m11, m02 และ m12 ตามลํ าดับ

Page 42: JAVA2D Thai

42

Scalingคอืการเพิ่มหรือลดขนาดของรูปภาพ กํ าหนดเปน double คาสองคาคือ sx และ sy ซ่ึงจะท ําใหขนาดในแกน

x ถูกคูณดวย sx และขนาดในแกน y ถูกคูณดวย sy

Methodในการทํ า scaling เชน เราสามารถ get คา sx และ sy ไดโดยใช

public double getScaleX() ;public double getScaleY() ;

public void scale(double sx, double sy) ;public void setToScale(double sx, double sy) ;public static AffineTransform getScaleInstance(double sx, double sy) ;

การใชงาน methods เหลานี้คลายกับ methods เกีย่วกับการทํ า translation คือเราสามารถเพิ่ม scaling ตอทายเขาไปใน affine transform ทีม่อียูเดิมโดยใช scale() และใช setToScale() ก ําหนดคา scaling ใหใหม ซ่ึงจะทํ าใหคา scaling เดิมสูญหายไป

Affine transform ทีไ่ดจาก getScaleInstance() เปน transformation matrix ดังนี้

1000sy000sx

Rotationคอืการหมุนรูปภาพไปเปนมุม a ( หนวยเปน radians ) รอบจุดสมมติ ( anchor ) ที่ ( x, y )

Methodpublic void rotate (double theta) ;public void rotate (double theta, double x, double y );public void setToRotation(double theta);public void setToRotation(double theta, double x, double y); public static AffinTransform getRotateInstance (double theta);public static AffinTransform getRotateInstance (double theta, double x, double y);

Page 43: JAVA2D Thai

43

การใชงาน methods เหลานี้คลายกับ methods เกี่ยวกับการทํ า translation และ scalingMethods ที่มีเพียง double theta เปนพารามิเตอรจะ rotation เปนมุม theta radians ( ถามีคาบวกจะหมุน

ตามเขม็นาฬิกา ) รอบจุด anchor ( 0,0 ) สวน Methods ที่มี double x และ double y เปนพารามิเตอรจะทํ าการ translate จากจุด origin ไปที่จุด ( x,y ) แลวจึงทํ า rotation เปนมุม a radians จากนั้นทํ าการ transtate กลับไปที่จุด origin

Affine transform ที่ไดจาก getRotaleInstance (double theta) จะเปน transformation martix ดังนี้

1000 ) theta( cos ) theta(sin 0 ) theta(sin - ) theta( cos

สวน getRotatelnstance (double theta, double x, double y ) จะให offine transform เปน transformation matrix ดังนี้

+

+

100cos*xsin*x-y ) theta( cos ) theta(sin sin*xcos*x-x ) theta(sin - ) theta( cos

หรือเปรียบไดกับAffineTransform t = new AffineTransform ( );t. setToTranslation ( x,y );t. rotate (theta) ;t. translate ( -x, -y ) ;

Page 44: JAVA2D Thai

44

Shearingคอืการบิด ( shear ) รูปภาพไปจากเดิมดวยคา double shx และ double shy นั่นคือ จุด ( x,y ) จะถูกเปลี่ยน

ไปเปน ( x + (shx)y, y + (shy) x) การเปลี่ยนแปลงแบบ affine ดังนั้น หากรูปเดิมมีเสนใดขนานกันผลของการบิดรูปจะไดเสนนั้นขนานกันเชนเดิม

Method คลาส Affine Transform มี methods หลายตัวในการทํ า shearing คือ

public void shear ( double shx , double shy );public void shearToShear ( double shx , double shy );public static AffineTransform getShearInstance ( double shx , double shy ):

Affine transform ที่ไดจาก getShearInstance ( ) เปน transformation matrix ดังนี้

10001shy0shx1

Compound TransformationAffine transform ตัวหนึ่งทํ าการ transform มากกวาหนึ่งอยางได โดยเรียก translate ( ), scale ( ), rotate ( )

และ shear ( ) เพิ่ม transform ใหมตอทาย transform เดิม

ตวัอยางการโปรแกรม…Graphics 2D g2 = ( Graphics 2D ) g ;AffneTransform a = new AffineTransform ( ) ;a. setToTranslation ( 30, 10 ) ;a. rotate ( Math. PI/8 ) ;g2. Transform ( a ) ;g2. draw ( new Rectangle 2D. Double ( 0, 0, 60, 40 )) ;…

Page 45: JAVA2D Thai

45

มีคาเหมือนกับ…Graphics 2D g2 = ( Graphics 2D ) g ;AffneTransform a = new AffineTransform ( ) ;a. setToTranslation ( Math. PI/8 ) ;a. translate ( 30, 10 ) ;g2. Transform ( a ) ;g2. draw ( new Rectangle 2D. Double ( 0, 0, 60, 40 )) ;…

รูปท่ี(6-1)แสดงผลของโปรแกรม Compound Transformation

Clippingคอื การกํ าหนดใหบางสวนของรูปภาพถูกวาดออกไป Java 2D ยอมใหเรากํ าหนดขอบเขตของรูปที่ถูกวาด

ออกไปไวกอน แลวหากมีสวนใดของภาพที่ถูกวาดอยูนอกขอบเขตนั้น ก็จะถูกตัดออกไป มีเฉพาะที่อยูในขอบเขตถูกวาดออกไปเทานั้น อยูใน java.awt.*;

Methodpublic abstract void setClip ( int x. int y. int w. int h );public abstract void setClip ( Shape s ) ;

สํ าหรับก ําหนดขอบเขตที่จะวาด โดยอาจกํ าหนดเปนสี่เหล่ียมที่มี bound เปน int ส่ีที่เปนตัวพารามิเตอร หรือจะเปน shape ก็ได

Page 46: JAVA2D Thai

46

public abstract void clip ( Shape s ) :หากเราเรียก method นี้กับ graphics2D ที่มี shape ถูกกํ าหนดสํ าหรับ clipping อยูแลว ก็จะทํ าการ intersect

รูป shape ที่เปนพารามิเตอรกับ shape ที่มีอยูเดิม แลวผลที่ไดจะกลายเปน shape สํ าหรับ clipping ของ graphics2d นั้น

Page 47: JAVA2D Thai

47

บทที่ 7การประมวลผลภาพ

Compositingคอืการน ําภาพมากกวาหนึ่งภาพมารวมกัน ซ่ึงจะเกิดขึ้นเมื่อเราวาดภาพหนึ่งไมวาจะเปน shape, text หรือ

image ทบัลงบนอกีภาพหนึ่งที่วาดอยูกอน เพื่อความสะดวกเราเรียกภาพที่จะถูกวาดวา source และภาพที่ถูกวาดอยู กอนและจะถูกวาดทับวา destination

Graphics2D ทํ า compositing มีขั้นตอนดังนี้- ภาพ source จะถูก rasterizer สรางเซต็ของคา alpha ของรูปภาพนั้นขึ้น ซ่ึงคา alpha หนึ่งแสดงคาความ

โปรงแสง ( transparency ) ที่ pixel หนึ่ง หากคา alpha เปน 0.0 แสดงวา pixel นั้นโปรงแสงนั่นคือ สีที่ อยูหลัง pixel นั้นสามารถผานมาไดหมด แตหากคา alpha เปน 1.0 แสดงวา pixel นั้นทึบแสง นั่นคือ สี ทีอ่ยูหลัง pixel นั้นไมสามารถผานมาไดเลย

- คาส ี ( color ) ที่แตละ pixel ของภาพนั้น ถูกสรางขึ้นโดยดูจาก paint ที่ติดตั้งให Graphics2D หรือสี ของ image

- Pixels ( คา color และคา alpha ) ของภาพ source และ destination จะถูกนํ ามารวมกันโดยมีกฎเกณฑตาม compositing rule ที่กํ าหนดใหแก Graphics2D นั้น

Thomas Porter และ Tom Duff มีบทความ “Compositing Digital Images” ใน SIGGRAPH 1984 Proceeding เสนอ 12 วิธีการนํ าคาสีและคา alpha ของภาพ source และ destination มารวมกันเรียกวา Porter – Duff Compositing Rules Java2D สามารถทํ า 8 ใน 12 วิธีของ Porter – Duff Compositing Rules ดังจะอธิบายตอไปนี้กํ าหนดใหคา alpha ของ source และ destination ถูกเขียนเปน αs และ αd ตามลํ าดับ

คา color ของ source และ destination ถูกเขียนเปน Cs และ Cd ตามลํ าดับคา fraction ของ source และ destination ถูกเขียนเปน fs และ fd ตามลํ าดับ

คา color และคา alpha ที่เปนผลลัพธของการ compositing คือnew Color = αs . fs . cs + αd . fd . cd

new Alpha = fs . cs + fd . cd

Page 48: JAVA2D Thai

48

ช่ือและกฎเกณฑของการทํ า compositing rules ขึ้นกับคา fractions ( fa กับ fd ) ดังแสดงในตารางนี้

รูปท่ี(7-1)ตาราง แสดง compositing rules

Name fs Fd DescriptionSrcOver 1 1- αs วาง source เหนือ destinationDstOver 1- αd 1 วาง destination เหนือ sourceClear 0 0 ลาง destination ภายใต sourceSrc αd 0 วาดทับ destination ดวย sourceDstin 0 αs แสดงสวนของ destination ภายใน sourceSrcOUt 1- αd 0 แสดงสวนของ source ภายนอก destinationDstOut 0 1- αs แสดงสวนของ destination ภายนอก source

Java2D มี Composite เปน interface สํ าหรับกํ าหนด compositing rule และใน Graphics2D มี member หนึ่งเปน instance ของคลาส Alphacomposite ซ่ึงทํ าการ implements Composite ไวแลวสํ าหรับใชกํ าหนด compositing rules ซ่ึงมีอยู 8 แบบตามตารางขางบนนี้ ในคลาสนี้มีคาคงที่สํ าหรับระบุช่ือ composirting rules ทั้ง 8 คือPublic static final AlphaComposite Clear ;Public static final AlphaComposite Src ;Public static final AlphaComposite SrcOver ;Public static final AlphaComposite DstOver ;Public static final AlphaComposite DstIn ;Public static final AlphaComposite SrcOut ;Public static final AlphaComposite DstOut ;

Page 49: JAVA2D Thai

49

Graphics2D มี SrcOver เปน default compositing rule เราสามารถเปลี่ยนเปนแบบอื่นไดโดยPublic abstract void setComposite ( Compositer ) :

สังเกตวา compositing rules ของคลาส AlphaComposite มีการจัดการเกี่ยวกับคา alpha แตหากเราวาดภาพลงบน Graphics2D g2 ที่ cast ไดจาก Graphics g ตามปกติ จะถูกจัดการเฉพาะคา color ไมรวมคา alpha จึงไมไดผลลัพธตามที่ตองการ วิธีทํ าใหคา alpha ถูกจัดการดวยคือ สราง Buffered image ชนิดที่เปนแบบ BufferedImage. TYPE_INT_ARGB แลวใช createGraphics ( ) เรียกขอ Graphics2D g2 ออกมา และวาดใส Graphics2D g2 นี้เมื่อเสรจ็แลวจึงนํ า Buffered image วาดใส Graphic g ที่เปนพื้นที่แสดง graphics

AlphaComposite มี Factory methods สํ าหรับสราง alpha composite ดังนี้

public static final int CLEAR ;public static final int SRC ;public static final int SRC_OVER ;public static final int DST_OVER ;public static final int SRC_IN ;public static final int DST_IN ;public static final int SRC_OUT ;public static final int DST_OUT ;

เมือ่ได alpha composite จาก factory methods เหลานี้ เราก็สามารถนํ าไปติดตั้งใหแก Graphics2D ไดโดยใช setComposite ( ) ดังที่กลาวไปแลว

Page 50: JAVA2D Thai

50

รูปท่ี(7-2)แสดงcompositing rules

Page 51: JAVA2D Thai

51

Rendering Hintsในการ redering ภาพ ไมวาจะเปน shape, text หรือ image หากตองการใหไดคุณภาพก็ตองใชเวลานาน

และถาทํ าอยางเร็วๆ กแ็นนอนวาไมไดคุณภาพ โดยทั่วไปหากภาพที่วาดยังไมใชตัวจริง เราไมจํ าเปนตองวาดอยางมคีณุภาพ ซ่ึงเสียทั้งหมึกและเวลามาก และถาภาพที่วาดเปนตัวจริงที่จะใชงาน เราจึงเนนคุณภาพในการวาดคลาส Graphics2D มีกลไกใหเราเลือกวาตองการคุณภาพ หรือความเร็ว โดยกํ าหนดเปน rendering hints ที่เรียกเชนนีเ้พราะวา rendering hints ไมใชคํ าสั่งที่ Graphics2D จะตองทํ าเสมอ แตจะทํ าเฉพาะถาสามารถทํ าได

เราใชคลาส RenderingHints ที่อยูใน package java.awt ในการกํ าหนด rendering hints ซ่ึงจะตองระบุในรูป<key, value> คือ ใช key ระบุวาจะกํ าหนดอะไร ใหมีคาเปน value เชนใด ในคลาส RenderingHints มี static innerclass ช่ือ key สํ าหรับใชเก็บคาของ key ซ่ึงถูกสรางเปนคาคงที่อยูภายในคลาส RenderingHints รวมทั้งในมีคาคงที่ของ value สํ าหรับแตละ value สํ าหรับแตละ key อยูคลาสนี้ดวย ดังในตารางนี้

รูปท่ี(7-3)ตาราง แสดง RenderingHints keyKey ( java.awt.RenderingHints.Key ) Possible values ( java.lang.Object )KEY_ANTIALLIASING VALUE_ANTIALIAS_ON

VALUE_ANTIALIAS_OFFVALUE_ANTIALIAS_DEFAULT

KEY_TEXT_ANTIALIASING VALUE_TEXT_ANTIALIAS_ONVALUE_TEXT_ANTIALIAS_OFFVALUE_TEXT_ANTIALIAS_DEFAULT

KEY_RENDERING VALUE_RENDER_SPEEDVALUE_RENDER_QUALITYVALUE_RENDER_DEFAULT

KEY_COLOR_RENDERING VALUE_COLOR_RENDER_SPEEDVALUE_COLOR_RENDER_QUALITYVALUE_COLOR_RENDER_DEFAULT

KEY_DITHERING VALUE_DITHER_DISABLEVALUE_DITHER_ENBLEVALUE_DITHER_DEFAULT

KEY_STROKE_CONTROL VALUE_STROKE_DEFAULTVALUE_STROKE_NORMALIZEVALUE_STROKE_PURE

KEY_FRACTIONALMETERICS VALUE_FRACTIONALMETRICS_OFFVALUE_FRACTIONALMETRICS_ONVALUE_FRACTIONALMETRICS_DEFAULT

Page 52: JAVA2D Thai

52

Key ( java.awt.RenderingHints.Key ) Possible values ( java.lang.Object )KEY_INTERPOLATION VALUE_INTERPOLATION_NEAREST_NEIGHBOR

VALUE_INTERPOLATION_NEAREST_BILINEARVALUE_INTERPOLATION_NEAREST_BICUBIC

KEY_ALPHA_INTERPOLATION VALUE_ALPHA_INTERPOLATION_SPEDVALUE_ALPHA_INTERPOLATION_QUALITYVALUE_ALPHA_INTERPOLATION_DEFAULT

ความหมายของ key แตละตัว คือKEY_ANTIALLIASING บอกวาใหทํ า antialiasing หรือไมKEY_TEXT_ANTIALIASING บอกวาใหทํ า antialiasing ในตอนวาด text หรือไม ( โดยปกติการทํ าantialiasing สํ าหรับ text จะใชเวลาคอนขางมาก )KEY_RENDERING บอกวาใหทํ า rendering อยางเร็วที่สุดที่ทํ าไดหรือไมKEY_COLOR_RENDERING บอกวาใหทํ าการปรับเปลี่ยนสี ในการวาดใส display devices โดยใช profileของ display devices นั้นหรือไมKEY_DITHERING บอกวาใหทํ า dithering หรือไม ( dithering คือการคํ านวณเพื่อประมาณคาสี ใชในกรณีที่ display devices ไมสามารถแสดงสีของภาพที่วาดไดทั้งหมด )KEY_STROKE_CONTROL บอกวาใหทํ า normalizatio กับ stroke หรือไมKEY_FRACTIONALMETERICS บอกวาใหคํ านวณขนาดเกี่ยวกับ font โดยใช floating point หรือ integersหากใช integers จะทํ างานเร็ว แตไมไดถูกตองตามที่ตองการKEY_INTERPOLATION บอกวาใช algorithm ใดในการทํ า transform หากใชแบบ nearest neighbor จะท ํางานเร็วแตคุณภาพไมดี แบบ bi – linear จะไดคุณภาพดีกวาแตทํ างานชา สวนแบบ bi – cubic จะไดคุณภาพดียิ่งขึน้อีก แต Java 2d ยังไมสามารถใชงานไดKEY_ALPHA_INTERPOLATION บอกวานํ าคา alpha มาคํ านวณในการทํ า rendering อยางไร เราสามารถติดตัง้ rendering hints ใหแก graphics2D ไดโดยใช

public abstract void setRenderingHint ( RenderingHints. Key Object );

Page 53: JAVA2D Thai

53

รูปแบบโครงสราง

โดยก ําหนด key และ value ใหเปนพารามิเตอรหรืออาจสราง rendering hints ขึ้นกอน โดยใช โครงสรางของคลาส RenderingHints คื อ

public RenderingHint ( RenderingHints. Key Object );

และเพิ่ม rendering hints อ่ืนๆ ลงไปใน rendering hints นั้นไดโดยใช method

public void add ( RenderingHints ):

แลวนํ าไปติดตั้งใหแก graphics2D โดยใชpublic abstract void setRenderingHint (Map init)):

สังเกตวาคลาส RenderingHints ทํ าการ implements Map ไวเพื่อเก็บ rendering hints หลายๆ คู

Aqntialiasingในการท ํา rendering เมื่อเสนหรือขอบของรูป shape หรือ text ถูกคํ านวณขึ้น ก็จะถูกเปลี่ยนไปเปนเซ็ตของ

pixels ที่ถูกทํ าใหมีสี แตเนื่องจากจุด pixels ถูกเรียงไวเปนตาราง ( grid ) หากมีเสนลากผานตารางของ pixels เหลานีเ้ปนมมุเอยีงไมมากพอ ก็ตองทํ าการประมาณวาจะใหจุดใดถูกทํ าใหมีสี และอาจทํ าใหเสนที่ไดเปนหยักเหมือนขั้นบันได

ในการ fill รูปภาพที่อาจเปน shape หรือ text หากเราคํ านวณอยางงายๆ วา ถาจะศูนยกลางของ pixels ใดอยูในขอบเขตของรูปภาพก็จะถูกทํ าใหมีสี แตหาก shape นั้นใหญพอ เราจะเห็นรอยหยักตามสวนโคงของ shape ดังในรปูขางลางดานซายนี้ แตหากเรายอมใชเวลาคํ านวณเพิ่มขึ้น คือใหสีของ pixel มีความสวางขึ้นกับปริมาณพื้นที่ของ pixel นั้นที่อยูในขอบเขตของ shape ที่วาด ก็จะไดผลดังรูปขางลางดานขวานี้เราเรียกการคํ านวณอยางนี้เรียกวาantialiasing

รูปท่ี(7-4)แสดงการใช Antialiasing

Page 54: JAVA2D Thai

54

บทที่ 8การ พิมพภาพ ท่ีแสดงออกทาง PRINTER

การทํ างานเกี่ยวกับการพิมพ เร่ิมตั้งแต JDK1.2 อยูในชุด java.awt.print.*; โดย class ทีเ่กีย่วของกับการพิมพ คือ PrinterJob , PageFormat, Printable

PrinterJobใชควบคุมนํ า printing dialog หรือ page setup ขึน้แสดงและสั่งใหเรมการพิมพ โดยในการพิมพตองสราง

print job ขึน้กอน โดยใช methodpublic static PrinterJob getPrinterJob();

ตอจากนั้นตองกํ าหนดสิ่งที่จะพิมพ คือpublic abstract void setPrintable(Printable painter);public abstract void setPrintable(Printable painter, PageFormat format);

การเริ่มพิมพ ตองเรียกpublic abstract void print() throws PrinterException;

หากตองการยกเลิกกอนพิมพเสร็จเรียกpublic abstract void cancel();

Printableเปน interface สํ าหรับกํ าหนดสิ่งที่จะพิมพ โดยใช

public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException;graphics คือกราฟฟกที่ตองการพิมพออกมา pageFormat เปนรูปแบบที่จะพิมพ pageIndex เปน พิมพหนา

ที่เทาไหรโดยเริ่มจาก 0 เสมอ

PageFormatใชกํ าหนดขนาด และ orientation page ที่จะพิมพ โครงสรางเปนดังนี้

public PageFormat();โดยการกํ าหนดขนาดแบบ default 6.5” x 11” PageFormat แบบ portrait-oriented

Page 55: JAVA2D Thai

55

การกํ าหนดขนาดของหนาใช method ผานทางPaper class ทีร่ะบุขนาดหนาดวย setSize และกรอบของภาพดวย setImageableArea ใน java.awt.print.*; ดังนี้public void setPaper(Paper paper);public Paper();public void setSize(double width, double height);public void setImageableArea (double x, double y, double width, double height) ;

ใชกํ าหนด orientation ของ page มี ดังนี้public static final int LANDSCAPE;public static final int PORTRAIT;public static final int REVERSE_LANDSCAPE;

ตวัอยางการโปรแกรมและคํ าอธิบายimport java.awt.*;import java.awt.print.*;public class SimplePrint2D implements Printable{

private static Font fnt = new Font("Helvetica",Font.PLAIN,24);private Paint pnt = new GradientPaint(100f, 100f, Color.red,136f, 100f, Color.green, true);

public static void main(String[] args){ // ให PrinterJob PrinterJob job = PrinterJob.getPrinterJob(); // ระบุ Printable เปน instance ของ SimplePrint2D job.setPrintable(new SimplePrint2D()); // วาง dialog box if (job.printDialog()) { // พิมพงาน ถาผูใช ไม cancel printing try { job.print(); } catch (Exception e) { /* handle exception */ } }System.exit(0);}

Page 56: JAVA2D Thai

56

public int print(Graphics g, PageFormat pf, int pageIndex)throws PrinterException{ // pageIndex 0 ถึง 4 หนาที่จะตอบสนองคือ 1 ถึง 5. if (pageIndex >= 5)

return Printable.NO_SUCH_PAGE;// กลับเมื่อไมมี Page

Graphics2D g2 = (Graphics2D) g; // กํ าหนด font g2.setFont(fnt); // ลงสีแบบ gradient color g2.setPaint(pnt); g2.drawString("Page " + (pageIndex+1), 100f, 100f); return Printable.PAGE_EXISTS; }}

Page 57: JAVA2D Thai

57

บทที่ 9การนํ า java2D ไปประยุกตใชงาน

ในที่นี้ไดนํ า java2D มาท ําเปนตัวอยางการประยุกตใชงานมี 5 ตัวอยาง คือ1. Page1.class ใชในการนํ าเสนอภาพ เคลื่อนไหว ตอเนื่อง2. Controls2.class ใชในการนํ าเสนอภาพ แผนที่ ขยายและยอ แผนที่ ซ่ึงควบคุมไปยัง Page2.class อีกทีหนึ่ง3. Controls3.class ใชในการนํ าเสนอภาพ แผนที่ โดยใช clip ซ่ึงควบคุมไปยัง Page3.class อีกทีหนึ่ง4. Page4.class ใชในการนํ าเสนอภาพ เคลื่อนไหว ตอเนื่อง การทํ างานเกี่ยวกับ FONT5. Controls5.class ใชในการนํ าเสนอภาพกราฟ โดยใช line2D ซ่ึงควบคุมไปยัง Page5.class อีกทีหนึ่ง

Page 58: JAVA2D Thai

58

Apane.javaimport java.awt.*;import java.awt.image.*;import javax.swing.*;import java.awt.event.*;import java.awt.geom.*;class APane extends JPanel {int W,H;Dimension d ;GradientPaint gPaintTop ,gPaintBut;public void paintComponent(Graphics g) {//----------------------------------------------------------------- super.paintComponent(g); //-----------------------------------------------------------------Graphics2D g2 = (Graphics2D) g;d= getSize();W=d.width;H= d.height;g2.setBackground(getBackground());g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);g2.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);gPaintTop =new GradientPaint(0,0,new Color(255,200,0,100),W/3,H/2,new Color(255,255,255,50));g2.setPaint(gPaintTop );g2.fillRect(0,0,W,H);gPaintBut =new GradientPaint(W/3,H/2,new Color(255,255,255,50) ,W,H,new Color(50,150,50,100));g2.setPaint(gPaintBut );g2.fillRect(0,0,W,H);drawimg(W,H,g2);}

Page 59: JAVA2D Thai

59

public void drawimg(int w, int h, Graphics2D g2) {

}

public void run() {

}

public synchronized void stop() {

}}

Page 60: JAVA2D Thai

60

Page1.javaimport java.awt.*;import java.awt.image.*;import javax.swing.*;import java.awt.event.*;import java.awt.geom.*;class Page1 extends APane implements Runnable {private Image pic[] =new Image[2] ;private BufferedImage bi;private int countframe =1;private int limitframe = 3;private int w,h;private int x,y;private int iw, ih;private int Xtext ,Ytext;private int XImg =0 ;private Timer timer;private Dimension d ;private float alpha=0.5f;private GradientPaint gPaintTop ,gPaintBut;

public Page1 (){addMouseListener(new MouseAdapter() {

public void mouserPressed(MouseEvent e){}// close mouserPressedpublic void mouseClicked(MouseEvent e) {}// close mouseClickedpublic void mouseReleased(MouseEvent e) {

countframe++; if (countframe>limitframe ) { countframe=1; }

Page 61: JAVA2D Thai

61

alpha =0.1f; repaint();}// close mouseReleased

}// close MouseAdapter ); addMouseMotionListener (new MouseMotionAdapter() {

public void mouseMoved(MouseEvent e) { x=e.getX();

y=e.getY() ;if ( (x > Xtext && x < Xtext+90)&& ( y >Ytext-50 && y < Ytext )) {

alpha =1.0f;repaint();

}}// close mouseMovedpublic void mouseDragged(MouseEvent e) {}// close mouseDragged

} );

}//close Page1 ()

public void paintComponent(Graphics g) { //----------------------------------------------------------------- super.paintComponent(g); //----------------------------------------------------------------- Dimension d = getSize(); w=d.width; h=d.height ;}

Page 62: JAVA2D Thai

62

public void drawimg(int w, int h, Graphics2D g2) {super.drawimg(w,h,g2);

switch (countframe){ case 1: iw = pic[0].getWidth(this); ih =pic[0].getHeight(this);

BufferedImage bi1 = new BufferedImage(w,h/2,BufferedImage.TYPE_INT_ARGB); Graphics2D big1 = bi1.createGraphics(); if (XImg<w-w/10)

{ XImg +=50; } big1.drawImage(pic[0],w-XImg,0, iw, ih, this); g2.drawImage(bi1,0,0, this); if (Xtext<(w/2)*1) {Xtext +=50; }

AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,alpha);Font font = new Font ("AngsanaUPC",Font.BOLD,80) ;g2.setFont(font);g2.setColor(Color.red);g2.setComposite(ac); g2.drawString(" จาวา ",Xtext,Ytext);break;

case 2:font = new Font ("AngsanaUPC",Font.BOLD,h/4) ;g2.setFont(font);g2.setColor(Color.black);Xtext=w/5;Ytext=h/3;g2.drawString(" การสราง ",Xtext,Ytext);break;

Page 63: JAVA2D Thai

63

case 3:iw = pic[1].getWidth(this);ih =pic[1].getHeight(this);g2.drawImage(pic[1],w/5,(h/5)*1, this);break;

default: break; }

g2.dispose();}

public void run() {pic[0] = Toolkit.getDefaultToolkit().getImage("1.gif");pic[1] = Toolkit.getDefaultToolkit().getImage("2.png");MediaTracker tracker = new MediaTracker(this);

tracker.addImage(pic[0],0); tracker.addImage(pic[1],1);

try {tracker.waitForAll();} catch (Exception e) {}

Xtext=0;Ytext=H/5*3;repaint();

timer = new Timer(5,new ActionListener(){public void actionPerformed(ActionEvent e){

repaint();}

});timer.start();}

Page 64: JAVA2D Thai

64

public synchronized void stop() { timer.stop();}

public static void main(String[] args) {try{ UIManager.setLookAndFeel("com.sun.java.swing.plaf.metal.MetalLookAndFeel");}

catch(Exception e){}Page1 panel =new Page1 (); JFrame frame= new JFrame("shows PaintPane");frame.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){System.exit(0);}

}); Container container =frame.getContentPane(); frame.setSize(new Dimension(500,500)); container.add(panel,BorderLayout.CENTER); frame.setVisible(true); panel.run();}

}

Page 65: JAVA2D Thai

65

Controls2.javaimport java.awt.*;import java.awt.image.*;import javax.swing.*;import java.awt.event.*;import java.awt.geom.*;

class Controls2 extends JFrame {Page2 p2 = new Page2();JPanel p1 =new JPanel();JPanel p3 =new JPanel();JPanel pane =new JPanel();JPanel BIGp1=new JPanel ();JButton b1 =new JButton("UP");JButton b2 =new JButton("LEFT");JButton b3 =new JButton("RIGHT");JButton b4 =new JButton("DOWN");JButton b5 =new JButton("O");JButton reset =new JButton("RESET");JButton zoombutton =new JButton("+Zoom-");JButton Positonbutton=new JButton("Positon");GradientPaint Paintzoom,PaintPositon;boolean PointZoom =true;

public void Controls () {

GridBagLayout gbl =new GridBagLayout();GridBagConstraints constraints=new GridBagConstraints ();p1.setLayout(gbl);p1.setBackground(Color.black);

Page 66: JAVA2D Thai

66

p1.setSize(new Dimension(50,50));p1.add(b1);constraints.gridx=1;constraints.gridy=0;gbl.setConstraints(b1,constraints);b1.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e){

p2.location = 1;p2.repaint();

}});

//-------------------------------------------------------------------------------------------------p1.add(b2);constraints.gridx=0;constraints.gridy=1;gbl.setConstraints(b2,constraints);b2.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e){

p2.location = 2;p2.repaint();

}});

//----------------------------------------------------------------------------------------------p1.add(b5);constraints.gridx=1;constraints.gridy=1;gbl.setConstraints(b5,constraints);b5.addActionListener(new ActionListener() {

Page 67: JAVA2D Thai

67

public void actionPerformed(ActionEvent e){

p2.location = 5;p2.repaint();

}});

//-----------------------------------------------------------------------------------------------p1.add(b3);constraints.gridx=2;constraints.gridy=1;gbl.setConstraints(b3,constraints);b3.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e){

p2.location = 3;p2.repaint();

}});

//-------------------------------------------------------------------------------------------------p1.add(b4);constraints.gridx=1;constraints.gridy=2;gbl.setConstraints(b4,constraints);b4.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e){

p2.location = 4;p2.repaint();

Page 68: JAVA2D Thai

68

}});

//-------------------------------------------------------------------------------------------------

reset.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e)

{p2.location = 0;p2.FirstPositionZoom = true;p2.repaint();

}});

//--------------------------------------------------------------------------------------------------

Positonbutton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e)

{p2.location = 0;p2.PositionZoom = true;p2.FirstPositionZoom = true;PointZoom = true;paintButton();

}});

zoombutton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e)

{p2.location = 5;

p2.PositionZoom =false;

Page 69: JAVA2D Thai

69

PointZoom=false;paintButton();

}});

paintButton(); p3.setLayout(new GridLayout(2,1,2,2));

p3.add(Positonbutton);p3.add(zoombutton);

//--------------------------------------------------------------------------------------------------

BIGp1.setLayout(new BorderLayout());BIGp1.add(p3,BorderLayout.WEST);BIGp1.add(p1,BorderLayout.CENTER);BIGp1.add(reset,BorderLayout.EAST);//------------------------------------------------pane.setLayout(new BorderLayout());pane.add(BIGp1,BorderLayout.SOUTH);pane.add(p2,BorderLayout.CENTER);p2.run();try{ UIManager.setLookAndFeel("com.sun.java.swing.plaf.metal.MetalLookAndFeel");}

catch(Exception e){} JFrame frame= new JFrame("Control Page2");

frame.setResizable(false); frame.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){

System.exit(0);}

});

Page 70: JAVA2D Thai

70

frame.setContentPane(pane); frame.setSize(new Dimension(500,500));

frame.show(); }

public void paintButton(){

if (PointZoom == true){Positonbutton.setBackground(new Color(145,145,145));zoombutton.setBackground(Color.lightGray);}else{

Positonbutton.setBackground(Color.lightGray);zoombutton.setBackground(new Color(145,145,145));

}

}public static void main(String[] args) { Controls2 frame= new Controls2 (); frame.Controls ();}

} // End Controls class

Page 71: JAVA2D Thai

71

Page2.javaimport java.awt.*;import java.awt.image.*;import javax.swing.*;import javax.swing.event.*;import java.awt.event.*;import java.awt.geom.*;

class Page2 extends APane implements Runnable {int location =0;boolean PositionZoom = true;boolean FirstPositionZoom = true;private Image pic ;private int w,h;private int x,y;private double XMap;private double YMap;private double iw, ih;private double iwpart ;private double ihpart ;private double XImg =0.25;private double YImg;private Dimension d ;private AffineTransform a = new AffineTransform(); ;private Thread thread;

public Page2(){addMouseListener(new MouseAdapter() {public void mouserPressed(MouseEvent e){

}// close mouserPressed

Page 72: JAVA2D Thai

72

public void mouseClicked(MouseEvent e) {}// close mouseClicked

public void mouseReleased(MouseEvent e) {if ((e.getModifiers()& InputEvent.BUTTON1_MASK)!=0)

{if (PositionZoom == true){ if (FirstPositionZoom == true)

{ XImg = 1;ihpart = (e.getY()*ih)/490 ;YMap = (-1)*(ihpart) ;iwpart = (e.getX()*iw)/680;XMap = (-1)*(iwpart);FirstPositionZoom = false;

}}else{XImg +=0.25;}

repaint();}if ((e.getModifiers()& InputEvent.BUTTON3_MASK)!=0){ if (XImg >0.25)

{XImg -=0.25;

}}

repaint();

}// close mouseReleased }// close MouseAdapter );

Page 73: JAVA2D Thai

73

addMouseMotionListener (new MouseMotionAdapter() {public void mouseMoved(MouseEvent e) {

setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));}// close mouseMoved

public void mouseDragged(MouseEvent e) {

}// close mouseDragged

} );}//close PaintPane ()

public void paintComponent(Graphics g) { //----------------------------------------------------------------- super.paintComponent(g); //----------------------------------------------------------------- }

public void drawimg(int w, int h, Graphics2D g2) {super.drawimg(w,h,g2);switch (location){case 0:

XMap = -70;YMap = -60;XImg = 0.25;YImg = 0.25;location= 5;break;

Page 74: JAVA2D Thai

74

case 1:YMap +=12.5;break;

case 2:XMap +=12.5;break;

case 3:XMap -=12.5;break;

case 4:YMap -=12.5;break;

default:break;

}

a.setToTranslation(XMap,YMap);YImg=XImg;g2.scale(XImg,YImg);g2.drawImage(pic,a,null);g2.dispose();}

public void run() {pic = Toolkit.getDefaultToolkit().getImage("MAP.jpg");MediaTracker tracker = new MediaTracker(this);tracker.addImage(pic,0);try {tracker.waitForAll();} catch (Exception e) {}iw=pic.getWidth(this);ih=pic.getHeight(this) ;

Page 75: JAVA2D Thai

75

thread = new Thread(this);thread.setPriority(Thread.MIN_PRIORITY);thread.start();repaint();

Thread me = Thread.currentThread();while (thread == me) {

repaint();try {

thread.sleep(10);} catch (InterruptedException e) { }

}}

public synchronized void stop() { thread = null; }

}//Close Panel

Page 76: JAVA2D Thai

76

Controls3.javaimport java.awt.*;import java.awt.image.*;import javax.swing.*;import java.awt.event.*;import java.awt.geom.*;

class Controls3 extends JFrame {Page3 p2 = new Page3();JPanel p1 =new JPanel();JPanel pane =new JPanel();JPanel clipPanel=new JPanel();JButton b1 =new JButton("อนุสาวรียชัยสมรภูมิ");JButton b2 =new JButton("ขยายอนุสาวรียชัยฯ");JButton b3 =new JButton("สถานีรถไฟหัวลํ าโพง");JButton b4 =new JButton("ขยายสถานีรถไฟฯ");JButton reset =new JButton("Reset");

public void Controls () {

clipPanel.setBackground(Color.black);clipPanel.add(b1);b1.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e){

p2.location = 1;p2.repaint();

}});

Page 77: JAVA2D Thai

77

//-------------------------------------------------------------------------------------------------clipPanel.add(b2);b2.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e){

p2.location = 2;p2.repaint();

}});

//-----------------------------------------------------------------------------------------------clipPanel.add(b3);b3.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e){

p2.location = 3;p2.repaint();

}});

//-------------------------------------------------------------------------------------------------clipPanel.add(b4);b4.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e){

p2.location = 4;p2.repaint();

}});

Page 78: JAVA2D Thai

78

//----------------------------------------------------------------------------------------------------

reset.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e)

{p2.location = 0;p2.repaint();

}});

//------------------------------------------------------------------------------------------------p1.setLayout(new BorderLayout());p1.add(new JPanel(),BorderLayout.NORTH);p1.add(clipPanel,BorderLayout.WEST);p1.add(reset,BorderLayout.EAST);p1.add(new JPanel(),BorderLayout.SOUTH);//-------------------------------------------------pane.setLayout(new BorderLayout());pane.add(p1,BorderLayout.SOUTH);pane.add(p2,BorderLayout.CENTER);p2.run();

try{ UIManager.setLookAndFeel("com.sun.java.swing.plaf.metal.MetalLookAndFeel");}catch(Exception e){}

JFrame frame= new JFrame("Control Page3"); frame.setResizable(false); frame.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){System.exit(0);

}});

Page 79: JAVA2D Thai

79

frame.setContentPane(pane); frame.setSize(new Dimension(505,500)); frame.show(); }

public static void main(String[] args) { Controls3 frame= new Controls3 (); frame.Controls ();}

} // End Controls class

Page 80: JAVA2D Thai

80

Page3.javaimport java.awt.*;import java.awt.image.*;import javax.swing.*;import java.awt.event.*;import java.awt.geom.*;

class Page3 extends APane {private Image pic ;int location =0;private int w,h;private int x,y;double XMap=-120;double YMap=-120;private int iw, ih;private int loop1=0;double XImg =0.50;double YImg;private Dimension d ;AffineTransform a;private Thread thread;private Ellipse2D ellipse ;private BufferedImage offImg;

public void paintComponent(Graphics g) { //-----------------------------------------------------------------

super.paintComponent(g); //-----------------------------------------------------------------

d = getSize(); w=d.width; h=d.height ; }

Page 81: JAVA2D Thai

81

public void drawimg(int w, int h, Graphics2D g2) { super.drawimg(w,h,g2);

a = new AffineTransform();switch (location){case 0:

XMap = -50;YMap = -350;XImg = 0.5;YImg = 0.5;g2.translate(XMap,YMap);YImg=XImg;a.setToScale(XImg,YImg);g2.drawImage(pic,a,null);break;

case 1: ellipse = new Ellipse2D.Double(150.0,75.0,150.0,100.0); g2.setClip(ellipse); g2.translate(XMap,YMap);YImg=XImg;a.setToScale(XImg,YImg);g2.drawImage(pic,a,null);break;

case 2:g2.translate(-900,-1700);YImg=XImg;a.setToScale(2,2);g2.drawImage(pic,a,null);

break;case 3:

ellipse = new Ellipse2D.Double(2.0,320.0,80.0,80.0);

Page 82: JAVA2D Thai

82

g2.setClip(ellipse);g2.translate(XMap,YMap);YImg=XImg;a.setToScale(XImg,YImg);g2.drawImage(pic,a,null);

break; case 4:

g2.translate(-140,-2750);YImg=XImg;a.setToScale(2,2);g2.drawImage(pic,a,null); break;

default:XMap = -50;YMap = -600;XImg = 0.5;YImg = 0.5;g2.translate(XMap,YMap);YImg=XImg;a.setToScale(XImg,YImg);g2.drawImage(pic,a,null);break;

}a.setToScale(XImg,YImg);g2.drawImage(pic,a,null);g2.dispose();

}

Page 83: JAVA2D Thai

83

public void run() {

pic = Toolkit.getDefaultToolkit().getImage("MAP.jpg");MediaTracker tracker = new MediaTracker(this);tracker.addImage(pic,0);

try {tracker.waitForAll();} catch (Exception e) {}

repaint();

}

}//Close Panel

Page 84: JAVA2D Thai

84

Page4.javaimport java.awt.*;import java.awt.image.*;import javax.swing.*;import javax.swing.event.*;import java.awt.event.*;

class Page4 extends APane implements Runnable {

private Image pic ;private int w,h;private int i;private boolean showframe = false;private boolean stopScroll =false;private int iw, ih;private int y=300;private Dimension d ;private Thread thread;

private String[] headlines = {"import java.awt.*; ","import javax.swing.*; ","import java.awt.event.*; ","public class frame extends JFrame { "," public void paint (Graphics g) { "," g.drawString("," New Frame"," ,50,50); "," } ","public static void main(String [ ] args){ ","frame f = new frame(); ",

Page 85: JAVA2D Thai

85

"f.setSize(500,500); ","f.setVisible(true); ","//ตรวจสอบการออกจากโปรแกรม ","f.addWindowListener(new WindowAdapter(){ "," public void windowClosing(WindowEvent e){ "," System.exit(0); "," }"," });"," }","}",};

public Page4(){

addMouseListener(new MouseAdapter() {public void mouserPressed(MouseEvent e){

}// close mouserPressedpublic void mouseClicked(MouseEvent e) {

}// close mouseClickedpublic void mouseReleased(MouseEvent e) {

if ((e.getModifiers()& InputEvent.BUTTON1_MASK)!=0){if ( (e.getX() > 10 && e.getX()< 10+200)&& ( e.getY() > y-30 && e.getY() <y+300 ) )

{ showframe = true; }else{ stopScroll = true; }

}if ((e.getModifiers()& InputEvent.BUTTON3_MASK)!=0)

{if (showframe == true){ showframe = false;

Page 86: JAVA2D Thai

86

y=300;}stopScroll = false;

}

repaint();

}// close mouseReleased }// close MouseAdapter );addMouseMotionListener (new MouseMotionAdapter() {public void mouseMoved(MouseEvent e) {

if (showframe == false) { if ( (e.getX() > 10 && e.getX()< 10+200)&& ( e.getY() > y-30 && e.getY() <y+300 ) )

{setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

}else{setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));

} }else{

setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));

}

}// close mouseMoved

public void mouseDragged(MouseEvent e) {}// close mouseDragged

Page 87: JAVA2D Thai

87

} );}//close PaintPane ()

public void paintComponent(Graphics g) { //----------------------------------------------------------------- super.paintComponent(g); //----------------------------------------------------------------- d = getSize(); w=d.width; h=d.height ; }

public void drawimg(int w, int h, Graphics2D g2) {super.drawimg(w,h,g2);

if (showframe == false){

Font font=new Font("CordiaUPC",Font.PLAIN,18);g2.setFont(font);g2.fillRect(0,0,w,h);g2.setColor(Color.black);for ( i=0;i< headlines.length ;i++ )

{g2.drawString( headlines[i],10,(y+15*i));}

}else{g2.setColor(Color.red);g2.drawString("javac frame.java",80,20);g2.drawString("java frame",80,50);g2.drawImage(pic,80,80,null);

Page 88: JAVA2D Thai

88

g2.drawString("(Click Right)",300,370);}

g2.dispose();}

public void run() { pic = Toolkit.getDefaultToolkit().getImage("frame.jpg"); MediaTracker tracker = new MediaTracker(this); tracker.addImage(pic,0); try {tracker.waitForAll();}

catch (Exception e) {} if (showframe == false) { while (true) {

if (stopScroll == false) {

y--;if (y<-300)

{y=301;}repaint();try { thread.sleep(5);

} catch (InterruptedException e) { }}

} }

repaint();}

public synchronized void stop() { thread = null;

Page 89: JAVA2D Thai

89

}

public static void main(String [] args){try{ UIManager.setLookAndFeel("com.sun.java.swing.plaf.metal.MetalLookAndFeel");}

catch(Exception e){}JFrame frame= new JFrame("Page4");Page4 pane = new Page4();frame.setResizable(false);frame.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){System.exit(0);

}});

frame.setContentPane(pane);frame.setSize(new Dimension(400,400));frame.show();pane.run();}

}//Close Panel

Page 90: JAVA2D Thai

90

Controls5.javaimport java.awt.*;import javax.swing.*;import javax.swing.event.*;import java.awt.event.*;import java.awt.geom.*;

class Controls5 extends JFrame {Page5 p5 = new Page5();JPanel pane =new JPanel();private JSlider limitSlider;int Yalarm ;

public void Controls () {limitSlider=new JSlider ( JSlider.VERTICAL,0,10,9);

// limitSlider.setMinimum(0);// limitSlider.setMaximum(10);// limitSlider.setValue(9);

limitSlider.setPaintTicks(true);limitSlider.setPaintLabels(true);limitSlider.setMajorTickSpacing(1);limitSlider.setMinorTickSpacing(1);limitSlider.setPreferredSize(new Dimension(50,200));p5.alarm=10- limitSlider.getValue();

//------------------------------------------------------------------------------------------------limitSlider.addChangeListener(new ChangeListener() {

public void stateChanged(ChangeEvent e){ p5.alarm=10- limitSlider.getValue();

p5.repaint();

Page 91: JAVA2D Thai

91

}});

//------------------------------------------------------------------------------------------------ JFrame frame= new JFrame("shows Page5 (การเตือนเมื่อมากกวาหรือเทากับคาที่จํ ากัดไว )"); frame.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){System.exit(0);

}});

Container container =frame.getContentPane(); frame.setSize(new Dimension(350,255)); frame.setResizable(false); container.add(new JPanel(),BorderLayout.NORTH); container.add(p5,BorderLayout.CENTER); container.add(limitSlider,BorderLayout.WEST); container.add(new JPanel(),BorderLayout.EAST); container.add(new JPanel(),BorderLayout.SOUTH); frame.setVisible(true); p5.run();

} public static void main(String[] args) {

Controls5 frame= new Controls5 ();

frame.Controls ();}

} // End Controls class

Page 92: JAVA2D Thai

92

Page5.javaimport java.awt.*;import java.awt.image.*;import java.awt.geom.*;import javax.swing.*;import javax.swing.event.*;import java.awt.event.*;import java.util.Random;import java.awt.font.*;

class Page5 extends APane implements Runnable {

private Image pic ;private int w,h;private int i;private int count=0;int arrayX[] =new int [11];int arrayY[] =new int [11];private Line2D.Double line,line1,line2,lineN ;private Random gen = new Random();private int x,y;private int ystart = 5;private int lastX,lastY;private int currentX,currentY;private boolean warn = false;public int alarm ;private boolean firsttime = true;private boolean stop = false;private int iw, ih;private int inputY;private Dimension d ;

Page 93: JAVA2D Thai

93

private Thread thread;

public Page5(){

addMouseListener(new MouseAdapter() {public void mouserPressed(MouseEvent e){

}// close mouserPressedpublic void mouseClicked(MouseEvent e) {

}// close mouseClickedpublic void mouseReleased(MouseEvent e) { if ((e.getModifiers()& InputEvent.BUTTON1_MASK)!=0)

{ stop = true;}if ((e.getModifiers()& InputEvent.BUTTON3_MASK)!=0){ stop = false; warn =false;}repaint();

}// close mouseReleased

}// close MouseAdapter );

addMouseMotionListener (new MouseMotionAdapter() {public void mouseMoved(MouseEvent e) {

}// close mouseMoved

Page 94: JAVA2D Thai

94

public void mouseDragged(MouseEvent e) {}// close mouseDragged

} );}//close Page5 ()

public void paintComponent(Graphics g) {//-----------------------------------------------------------------

super.paintComponent(g); //-----------------------------------------------------------------

d = getSize(); w=d.width; h=d.height ;

}

public void drawimg(int w, int h, Graphics2D g2) { super.drawimg(w,h,g2);

//----------------------------------------------------------------- generate Input value 0-10 if (stop == false){

if (firsttime == true ){ arrayX[0]=20; arrayY[0]=gen.nextInt(11)*(20)+ystart;

firsttime = false;

}count++;currentX=20*count+20;

Page 95: JAVA2D Thai

95

currentY=gen.nextInt(11)*(20)+ystart;arrayX[count] = currentX;arrayY[count] = currentY;

}//------------------------------------------------------------------------------------------XY AXIS g2.setColor(Color.red);

g2.setStroke(new BasicStroke(5)); line1 =new Line2D.Double(20,0+ystart,20,200+ystart); line2 =new Line2D.Double(20,200+ystart,220,200+ystart); g2.draw(line1); g2.draw(line2); g2.setColor(new Color(0,102,204,80)); g2.setStroke(new BasicStroke(1)); for ( int n=0;n<=10 ;n++ ) {

lineN =new Line2D.Double(20,20*n+ystart,220,20*n+ystart); g2.draw(lineN);

} for ( int n=1;n<=11 ;n++ ) {

lineN =new Line2D.Double(20*n,200+ystart,20*n,0+ystart); g2.draw(lineN);

}

//--------------------------------------------------------------show Limit

g2.setPaint(new Color(240,0,0,80));g2.fill(new Rectangle2D.Double(20,ystart,200,alarm*20));

//-----------------------------------------------------------------------------------------Show Graph

Page 96: JAVA2D Thai

96

g2.setColor(Color.black);g2.setStroke(new BasicStroke(2));for (int i = 1;i<=count ;i++ ){

line =new Line2D.Double(arrayX[i -1], arrayY[i-1],arrayX[i],arrayY[i]);g2.draw(line);

}//----------------------------------------------------------------------------------------check alarm

inputY = (arrayY[count]-ystart)/20;if ( alarm >= inputY){FontRenderContext frc = g2.getFontRenderContext();Font font = new Font("CordiaUPC", Font.BOLD, 25);TextLayout tl = new TextLayout("ระวัง", font, frc);g2.setColor(Color.red);tl.draw(g2, 230, 100);warn = true;}if (count==10)

{ stop = true;}

//------------------------------------------------------------------------------------------------------g2.dispose();}

public void run() {

while (true) {if (count <=10) {

repaint(); try { thread.sleep(500);

} catch (InterruptedException e) { } }else { count = 0;

Page 97: JAVA2D Thai

97

firsttime = true;repaint();

} }

}

public synchronized void stop() { thread = null; }}//Close Panel

Page 98: JAVA2D Thai

98

รูปท่ี(9-1)แสดงรูป 1.gif

รูปท่ี(9-2)แสดงรูป 2.png

Page 99: JAVA2D Thai

99

รูปท่ี(9-3)แสดงรูป MAP.jpg กวาง2251สูง1660 ขนาด2.7Mb

รูปท่ี(9-4)แสดงรูป frame.jpg

Page 100: JAVA2D Thai

100

รูปท่ี(9-5)แสดงการทํ างาน Page1.class

Page 101: JAVA2D Thai

101

รูปท่ี(9-6)แสดงการทํ างาน Controls2.class

Page 102: JAVA2D Thai

102

รูปท่ี(9-7)แสดงการทํ างาน Controls3.class

Page 103: JAVA2D Thai

103

รูปท่ี(9-8)แสดงการทํ างาน Page4.class

Page 104: JAVA2D Thai

104

รูปท่ี(9-9)แสดงการทํ างาน Controls5.class