



<html>
<head>
  <title>javabog.dk -  - Grafiktegning (Java2D)</title>
  <link rev="stylesheet" type="text/css" href="../typografi.css">
  <meta name="description" content="Lærebog i Java. Af Jacob Nordfalk. Udkommet hos Forlaget Globe">
  <meta name="keywords" content="designmønster, programmering, OOP, objekter, klasser, objektorienteret programmering, Java, JSP, lærebog, UML, IT">
</head>
<body bgcolor="#ffffff">



<a href='http://javabog.dk/'>javabog.dk</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel4.jsp'>&lt;&lt; forrige</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='indhold.jsp'>indhold</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel6.jsp'>n&aelig;ste &gt;&gt;</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kode/'>programeksempler</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='../index_VP.html'>om bogen</a>

<H1 CLASS="western" STYLE="">5 <a name='afsn5'></a><SPAN LANG="da-DK">Grafiktegning</SPAN>
(Java2D)</H1>
<DIV ID="Indholdsfortegnelse13">
  <P STYLE="margin-top: 0.3cm; margin-bottom: 0cm"><BR>
  </P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>5.1
  Java2D kort fortalt  94</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">5.1.1
  Geometriske figurer  94</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">5.1.2
  Geometriske operationer  95</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">5.1.3
  Transformationer  96</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">5.1.4
  Linjetyper  96</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">5.1.5
  Tegnekvalitet  96</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">5.1.6
  Videre l&aelig;sning  96</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>5.2
  Eksempel  96</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>5.3
  Eksempel fra JDK'et  98</B></FONT></FONT></P>
</DIV>

<P CLASS="western" STYLE="">Java2D giver
mulighed for mere avanceret <SPAN LANG="da-DK">grafikmanipulering.</SPAN>
Blandt faciliteterne er:</P>
<UL>
  <LI><P CLASS="western">Klasser til en r&aelig;kke geometriske
  grundfigurer, s&aring;som linjer, kurver, rektangler, ellipser og
  mekanismer til at tegne n&aelig;sten enhver &oslash;nskelig
  geometrisk form.</P>
  <LI><P CLASS="western">Transformationer (<SPAN LANG="da-DK">skalering</SPAN>,
  <SPAN LANG="da-DK">rotering</SPAN>, vridning) af figurer, tekster og
  billeder.</P>
  <LI><P CLASS="western"><SPAN LANG="da-DK">Halvgennemsigtig</SPAN>
  tegning (hvor det, der var bag ved det tegnede, stadig kan skimtes).</P>
  <LI><P CLASS="western">Trappeudj&aelig;vning (udj&aelig;vnede
  farveovergange, eng.: antialiasing).</P>
  <LI><P CLASS="western">Mekanismer til at afg&oslash;re, om et punkt
  er inden eller uden for en vilk&aring;rlig geometrisk figur, tekst
  eller billede (f.eks. klik med musen).</P>
</UL>

<H2 CLASS="western">5.1 <a name='afsn5.1'></a>Java2D kort fortalt</SPAN></H2>
<P CLASS="western">Java2D virker ved, at paint()-metoden f&aring;r
overf&oslash;rt et Graphics-objekt, som i virkeligheden er et
Graphics2D-objekt (Graphics2D arver fra Graphics). 
</P>
<P CLASS="western">Det <SPAN LANG="da-DK">typekonverterer</SPAN> man
til Graphics2D og har s&aring; adgang til de ekstra funktioner i
Java2D:</P>
<PRE CLASS="kode-western">  public void paint(Graphics g)
  {
    Graphics2D g2 = (Graphics2D) g;
    ...
  }</PRE><P CLASS="western">
Man kan derefter tegne med de normale funktioner fra
Graphics-klassen, men ogs&aring; med nogle af de mange nye metoder i
Graphics2D-klassen.</P>
<P CLASS="western">De gamle tegnemetoder (som <SPAN LANG="da-DK">drawLine</SPAN>(),
<SPAN LANG="da-DK">drawRect</SPAN>(), ...) er erstattet med en
enkelt, draw(), der kan tegne alle mulige geometriske figurer
repr&aelig;senteret af Shape-objekter:</P>
<PRE CLASS="kode-western">  Shape s = new Line2D.Float(0, 0, 100, 100);
  g2.draw(s);</PRE><H3 CLASS="western">
5.1.1 <a name='afsn5.1.1'></a>Geometriske figurer</H3>
<P CLASS="western">Shape-objekter (der findes i pakken <SPAN LANG="da-DK">java.awt.geom</SPAN>)
repr&aelig;senterer en eller anden geometrisk figur p&aring; sk&aelig;rmen.
Der findes disse grundl&aelig;ggende Shape-objekter:</P>
<UL>
  <LI><P CLASS="western">Rektangler - Rectangle2D og RoundRectangle2D</P>
  <LI><P CLASS="western">Linjer - Line2D (en ret linje), CubicCurve2D
  (en linje, der er buet efter et ankerpunkt) og QuadCurve2D (en
  linje, der er buet efter to ankerpunkter)</P>
  <LI><P CLASS="western">Ellipse2D og Arc2D (buestykke)</P>
</UL>
<P CLASS="western">Klassen <SPAN LANG="da-DK">GeneralPath</SPAN>
repr&aelig;senterer en vilk&aring;rlig figur, der er en kombination
af ovenst&aring;ende figurer (Shape-objekter):</P>
<PRE CLASS="kode-western">  GeneralPath figur = new GeneralPath();
  <SPAN LANG="da-DK">figur.append</SPAN>( new Line2D.Float(0, 0, 100, 100), false );
  figur.append( new CubicCurve2D.Float(0, 0, 80, 15, 10, 90, 100, 100), false );
  figur.append( new Arc2D.Float(-30, 0, 100, 100, 60, -120, Arc2D.PIE), false );</PRE><P CLASS="western">
Metoden append() tager et Shape-objekt og en boolean, der afg&oslash;r
om det nye Shape-objekt skal forbindes med den eksisterende figur
eller ej.  
</P>
<P CLASS="western">GeneralPath har ogs&aring; metoderne <SPAN LANG="da-DK">moveTo</SPAN>(x,
y), <SPAN LANG="da-DK">lineTo</SPAN>(x, y), <SPAN LANG="da-DK">quadTo</SPAN>(x,y,x2,y2)
og <SPAN LANG="da-DK">curveTo</SPAN>(x, y, x1, y1, x2, y2) til at
bygge en figur op med.</P>
<P CLASS="western">Man kan derefter tegne den resulterende figur med
&eacute;n kommando:</P>
<PRE CLASS="kode-western">  g2.draw( figur );</PRE><P CLASS="western">
Det samme GeneralPath-objekt kan med fordel bruges igen i hver
gentegning for hurtigere k&oslash;rselstid (hvis det oprettes et
andet sted end i paint()-metoden). 
</P>
<H3 CLASS="western">5.1.2 <a name='afsn5.1.2'></a>Geometriske operationer</H3>
<P CLASS="western">Med klassen Area kan man hurtigt udf&oslash;re en
r&aelig;kke handlinger med <SPAN LANG="da-DK">shapeobjekter</SPAN>
uden at beskrive hvert linjesegment eller kurve, som f.eks.:</P>
<UL>
  <LI><P CLASS="western"><B>add</B>        finder foreningsm&aelig;ngden
  af A og B</P>
</UL>
<UL>
  <LI><P CLASS="western"><B>intersect</B>      finder f&aelig;llesm&aelig;ngden
  af A og B</P>
</UL>
<UL>
  <LI><P CLASS="western"><B>subtract</B>      tr&aelig;kker f&aelig;llesm&aelig;ngden
  af A og B fra A</P>
  <LI><P CLASS="western"><B><SPAN LANG="da-DK">exclusiveOr</SPAN></B>
    finder foreningsm&aelig;ngden af A og B, men <SPAN STYLE="font-weight: medium">fjerner
  f&aelig;llesm&aelig;ngden</SPAN></P>
</UL>

<P CLASS="western"><SPAN STYLE="font-weight: medium">  <IMG SRC="bog6_html_6318464b.gif" NAME="Grafik21" BORDER=0></SPAN></P>
<P CLASS="western" STYLE="font-weight: medium">    add              intersect</P>

<P CLASS="western" STYLE="font-weight: medium"><IMG SRC="bog6_html_2aadd5a2.gif" NAME="Grafik19" BORDER=0>
      
<IMG SRC="bog6_html_m7d5b568c.gif" NAME="Grafik45" BORDER=0></P>
<P CLASS="western" STYLE="font-weight: medium">    subtract            exclusiveOr</P>

<P CLASS="western">Nedenfor er vist et lille eksempel p&aring; brugen
af klassen Area.</P>
<PRE CLASS="kode-western">import java.awt.*;
import java.awt.geom.*;  <I>// indeholder klasser der er specielle for Java2D</I>

public class FigurLeg extends Frame
{
  public void paint(Graphics g)
  {
    Graphics2D g2 = (Graphics2D)g;
    Area a = new Area(new Rectangle2D.Double(10,30,60,60));
    g2.draw(a);          

    Area b = new Area(new Ellipse2D.Double(10,10,90,50));
    g2.translate(100,0); // tegn i midten
    g2.draw(b);

    <SPAN LANG="da-DK">a.intersect</SPAN>(b);      <I>// find f&aelig;llesm&aelig;ngde af a og b og tegn yderst til h&oslash;jre</I>
    g2.translate(100,0);<IMG SRC="bog6_html_184012be.png" NAME="Grafik51" ALIGN=RIGHT BORDER=0>
    g2.draw(a);
  }

  public static void main(String[] args) {
    FigurLeg fl = new FigurLeg();
    <SPAN LANG="da-DK">fl.setSize</SPAN>(300,100);
    <SPAN LANG="da-DK">fl.setVisible</SPAN>(true);
  }
}</PRE><P CLASS="western">
Yderst til h&oslash;jre ses f&aelig;llesm&aelig;ngden af firkanten og
cirklen.</P>

<H3 CLASS="western">5.1.3 <a name='afsn5.1.3'></a>Transformationer</H3>
<P CLASS="western">Klassen <SPAN LANG="da-DK">AffineTransform</SPAN>
repr&aelig;senterer en line&aelig;r (<SPAN LANG="da-DK">affin</SPAN>)
transformation af koordinatsystemet. Med den kan man lave <SPAN LANG="da-DK">skaleringer</SPAN>
(st&oslash;rre/mindre), drejninger (med/mod uret) og vridninger
(&quot;v&aelig;lte&quot; figuren).</P>
<P CLASS="western">Ved at kalde transform() p&aring;
Graphics2D-objektet &aelig;ndres dets koordinatsystem s&aring;dan, at
alt det, der efterf&oslash;lgende tegnes, bliver skaleret, drejet og
vredet i henhold til transformationen. Hvis man &aelig;ndrer
transformationen, b&oslash;r man huske den gamle (f&aring;s med
<SPAN LANG="da-DK">getTransform</SPAN>()) og s&aelig;tte den tilbage
igen (med <SPAN LANG="da-DK">setTransform</SPAN>()), f&oslash;r
paint() returnerer.</P>
<H3 CLASS="western">5.1.4 <a name='afsn5.1.4'></a>Linjetyper</H3>
<P CLASS="western">Med <SPAN LANG="da-DK">setStroke</SPAN>() s&aelig;tter
man bredden af linjen, der skal tegnes, om linjerne skal have kantede
eller afrundede endestykker og kn&aelig;k, om de skal v&aelig;re
punkterede (og hvordan).</P>
<H3 CLASS="western">5.1.5 <a name='afsn5.1.5'></a>Tegnekvalitet</H3>
<P CLASS="western">Med <SPAN LANG="da-DK">setRenderingHint</SPAN>()
s&aelig;tter man forskellige vink til tegnealgoritmen: om der skal
laves trappeudj&aelig;vning, om hastighed eller kvalitet skal
prioriteres og meget andet. 
</P>
<H3 CLASS="western">5.1.6 <a name='afsn5.1.6'></a>Videre l&aelig;sning</H3>
<P CLASS="western"><a href='kapitel12.jsp#afsn12.4.2'>Afsnit 12.4.2</a> giver et overblik over de mange
klasser, der er til r&aring;dighed i Java2D.</P>
<P CLASS="western">P&aring;
<SPAN STYLE="font-weight: medium"><A CLASS="western" HREF="http://java.sun.com/docs/books/tutorial/2d">http://java.sun.com/docs/books/tutorial/2d</A></SPAN>
findes en god introduktion til Java2D.</P>

<H2 CLASS="western">5.2 <a name='afsn5.2'></a>Eksempel</SPAN></H2>
<P CLASS="western">I eksemplet herunder opretter vi en figur og
tegner den, f&oslash;rst almindeligt, derefter med en linjetykkelse
p&aring; 2 punkter, derefter med trappeudj&aelig;vning og til sidst
med mere og mere rotation, skalering og vridning.</P>

<P CLASS="western">Resultatet bliver f&oslash;lgende figurer:</P>
<P CLASS="western"><IMG SRC="bog6_html_134372a0.png" NAME="Graphic9" ALIGN=BOTTOM BORDER=0></P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>  almindelig  2-<SPAN LANG="da-DK">pkt</SPAN>
linjetykkelse  trappeudj&aelig;vning  transformation  x2  x3</I></FONT></P>


<PRE CLASS="kode-western">import java.awt.*;
import java.awt.geom.*;
public class Java2DDemo extends Frame
{
  GeneralPath fig;

  AffineTransform trans;

  <SPAN LANG="da-DK">BasicStroke</SPAN> stregtype = <I>// 2-<SPAN LANG="da-DK">punktsstreg</SPAN> med kantede ender og runde kn&aelig;k</I>
    new BasicStroke(2, <SPAN LANG="da-DK">BasicStroke.CAP</SPAN>_SQUARE, <SPAN LANG="da-DK">BasicStroke.JOIN</SPAN>_ROUND);

  public Java2DDemo()
  {
    <SPAN LANG="da-DK">setBackground</SPAN>(<SPAN LANG="da-DK">Color.white</SPAN>);

    <I>// Lav 'smiley' - cirkel, to &oslash;jne og glad &aring;ben mund</I>
    fig = new GeneralPath( new Ellipse2D.Float(0, 0, 100, 100) );
    <SPAN LANG="da-DK">fig.append</SPAN>( new Ellipse2D.Float(20, 20, 10, 10), false );
    fig.append( new Ellipse2D.Float(70, 20, 10, 10), false );
    fig.append( new Arc2D.Float(10,10, 80,80, 330,-120,Arc2D.CHORD), false );

    trans = <SPAN LANG="da-DK">AffineTransform.getScaleInstance</SPAN>(0.7, 0.7); <I>// formindsk</I>
    <SPAN LANG="da-DK">trans.rotate</SPAN>(0.3);                                  <I>// roter</I>
    <SPAN LANG="da-DK">trans.shear</SPAN>(0.3,0);                                 <I>// <SPAN LANG="da-DK">vrid</SPAN></I>
    <SPAN LANG="da-DK">trans.translate</SPAN>(160,-50);                           <I>// flyt til siden</I>
  }

  public void paint(Graphics g)
  {
    Graphics2D g2 = (Graphics2D) g;              <I>// brug Java2D</I>

    // koordinattransformation
    AffineTransform <SPAN LANG="da-DK">orgTrans</SPAN> = g2.getTransform();<I>// husk original transformation</I>
    g2.translate(10,30);

    g2.draw( fig );                           <I>// tegn almindelig</I>
    g2.translate( 110, 0 );

    g2.setStroke( stregtype );
    g2.draw( fig );                           <I>// tegn med 2-pkt linjetykkelse</I>
    g2.translate( 110, 0 );

    g2.setRenderingHint( <I>// s&aelig;t tegnevink til trappeudj&aelig;vning (antialias)</I>
      <SPAN LANG="da-DK">RenderingHints.KEY</SPAN>_ANTIALIASING, <SPAN LANG="da-DK">RenderingHints.VALUE</SPAN>_ANTIALIAS_ON);
    g2.draw( fig );                           <I>// tegn med trappeudj&aelig;vning</I>


    g2.transform( trans );
    g2.draw( fig );                           <I>// tegn med transformation</I>

    g2.transform( trans );
    g2.draw( fig );                           <I>// tegn med transformation  x2</I>

    g2.transform( trans );
    g2.draw( fig );                           <I>// tegn med transformation  x3</I>

    g2.setTransform( orgTrans );                 <I>// genskab orig. transformation</I>
  }

  public static void main(String[] arg)
  {
    Java2DDemo vindue = new Java2DDemo();
    vindue.setSize(500,150);
    vindue.setVisible(true);
  }
}</PRE>
<H2 CLASS="western" STYLE="">5.3 <a name='afsn5.3'></a>Eksempel
fra JDK'et</SPAN></H2>
<P CLASS="western" STYLE="margin-top: 0cm; margin-bottom: 0cm">Sammen
med Java f&oslash;lger et program, der illustrerer de fleste af
mulighederne med Java2D. Det ligger i
jdk1.4/demo/jfc/Java2D/Java2Demo.jar og startes ved at <SPAN LANG="da-DK">dobbeltklikke</SPAN>
p&aring; jar-filen eller fra kommandolinjen skrive: java -jar
Java2Demo.jar. Her ses nogle sk&aelig;rmbilleder:</P>
<P CLASS="western" ALIGN=CENTER STYLE="margin-top: 0cm; margin-bottom: 0cm">
 
<IMG SRC="bog6_html_m7b7de1a6.png" NAME="Grafik69" ALIGN=BOTTOM BORDER=0>
</P>
<P CLASS="western" STYLE="margin-top: 0cm; margin-bottom: 0cm"><IMG SRC="bog6_html_m2696c256.png" NAME="Grafik70" ALIGN=BOTTOM BORDER=0>
<IMG SRC="bog6_html_78057d5d.png" NAME="Grafik71" ALIGN=BOTTOM BORDER=0></P>
<P CLASS="western" STYLE="margin-top: 0cm; margin-bottom: 0cm"><IMG SRC="bog6_html_6e6cdf10.png" NAME="Grafik73" ALIGN=BOTTOM BORDER=0>
<IMG SRC="bog6_html_5457912.png" NAME="Grafik74" ALIGN=BOTTOM BORDER=0></P>

<a href='http://javabog.dk/'>javabog.dk</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel4.jsp'>&lt;&lt; forrige</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='indhold.jsp'>indhold</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel6.jsp'>n&aelig;ste &gt;&gt;</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kode/'>programeksempler</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='../index_VP.html'>om bogen</a>
<hr>
<font size=-2>http://javabog.dk/ - <b></b> af Jacob Nordfalk.
<br>
  Licens og kopiering under <a href='http://www.linuxbog.dk/licens.html'>&Aring;ben Dokumentlicens</a> (&Aring;DL)
  hvor intet andet er nævnt (71% af værket).
</font>
<br>
Ønsker du at se de sidste 29% af dette værk (362838 tegn)
skal du købe bogen. Så får du pæne figurer og layout, stikordsregister og en trykt bog med i købet.
<!-- netlæser: Wget/1.10, autoHent: true  -->
     

</body>
</html>
