



<html>
<head>
  <title>javabog.dk -  - Grafiske programmer</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='kapitel8.jsp'>&lt;&lt; forrige</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='indhold.jsp'>indhold</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel10.jsp'>n&aelig;ste &gt;&gt;</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kode/'>programeksempler</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='../index_OOP.html'>om bogen</a>

<H1 CLASS="western" STYLE="">9 <a name='afsn9'></a>Grafiske
programmer</H1>
<P CLASS="kapiteloversigt-western">Indhold:</P>
<UL>
  <LI><P CLASS="kapiteloversigt-western">Oprettelse og brug af
  grafiske vinduer</P>
</UL>
<UL>
  <LI><P CLASS="kapiteloversigt-western">At tegne grafik med
  Graphics-objektet</P>
  <LI><P CLASS="kapiteloversigt-western">St&oslash;rre opgave:
  Matador-spillet som et grafisk program</P>
</UL>
<P CLASS="kapiteloversigt-western">Kapitlet foruds&aelig;ttes i
<a href='kapitel10.jsp'>kapitel 10</a>, Appletter, <a href='kapitel11.jsp'>kapitel 11</a>, Grafiske standardkomponenter og
<a href='kapitel12.jsp'>kapitel 12</a>, Interfaces.</P>
<P CLASS="kapiteloversigt-western">Foruds&aelig;tter <a href='kapitel3.jsp'>kapitel 3</a>, Objekter
(4, Definition af klasser og 5, Nedarvning er en fordel). Den st&oslash;rre
opgave foruds&aelig;tter <a href='kapitel5.jsp'>kapitel 5</a>, Nedarvning.</P>


<P CLASS="western" STYLE="">Vi kan f&aring;
et vindue op p&aring; sk&aelig;rmen ved at skrive en klasse, der
arver fra klassen Frame og definere metoden paint(), som systemet vil
kalde n&aring;r vinduet skal tegnes op p&aring; sk&aelig;rmen.
paint() f&aring;r et Graphics-objekt (beskrevet i <a href='kapitel9.jsp#afsn9.1'>afsnit 9.1</a>)
overf&oslash;rt, som vi kan tegne med.</P>
<P CLASS="western">I eksemplet nedenfor tegner vi en linje, en fyldt
oval og noget tekst med gr&oslash;n skrift.</P>
<PRE CLASS="kode-western">import java.awt.*;

public class GrafiskVindue <B>extends Frame</B>
{
<B>  public void paint(Graphics g)</B>
  {
<I>    // Herunder referer g til et Graphics-objekt man kan tegne med</I>
    g.drawLine(0,0,50,50);

    g.fillOval(5,20,300,30);

    g.setColor(Color.GREEN);

    g.drawString(&quot;Hej grafiske verden!&quot;,100,40);
  }
}</PRE><P CLASS="western">
For at vise det grafiske vindue p&aring; sk&aelig;rmen skal vi
definere en main()-metode, der opretter et GrafiskVindue-objekt,
s&aelig;tter vinduets st&oslash;rrelse og g&oslash;r det synligt p&aring;
sk&aelig;rmen:</P>
<PRE CLASS="kode-western">public class VisGrafiskVindue
{
  public static void main(String[] arg)
  {
    GrafiskVindue vindue = new GrafiskVindue();   <I>// opret vinduet</I>
    vindue.setSize(350,60);                       <I>// s&aelig;t vinduets st&oslash;rrelse</I>
    vindue.setTitle(&quot;GrafiskVindue&quot;);             <I>// s&aelig;t vinduets titel</I>
    vindue.setVisible(true);                      <I>// &aring;bn vinduet</I>
  }
}</PRE>
<P CLASS="western">Her ses, hvordan vinduet ser ud p&aring; sk&aelig;rmen
(under Linux):</P>
<P CLASS="western"><IMG SRC="bog10_html_3471df0f.png" NAME="Grafik31" ALIGN=LEFT BORDER=0><BR CLEAR=LEFT><BR><BR>
</P>
<P CLASS="western">Vinduets &oslash;verste venstre hj&oslash;rne er i
(0,0) og koordinaterne regnes mod h&oslash;jre og nedad.</P>
<P CLASS="western">Netop i en Frame regnes koordinaterne inklusiv
vinduets dekoration, s&aring; (0,0) er d&aelig;kket af titellinjen p&aring;
vinduet. &Oslash;nskes det, kan nulpunktet forskydes i paint() med
kommandoerne</P>
<PRE CLASS="kode-western">    Insets in = getInsets();                <I>// kun Frame: forskyd nulpunktet</I>
    g.translate(in.left,in.top);            <I>// (0,0) til under titellinjen</I></PRE>
<P CLASS="western">Hvis man k&oslash;rer programmet, opdager man, at
vinduet ikke reagerer, n&aring;r man fors&oslash;ger at lukke det.
Man kan i stedet stoppe programmet (f.eks. v&aelig;lge 'Stop' i
udviklingsv&aelig;rkt&oslash;jet eller trykke Ctrl-C fra
kommandolinjen). Man kan ogs&aring; bruge klassen LukProgram,
defineret i <a href='kapitel13.jsp#afsn13.4.1'>afsnit 13.4.1</a>, og tilf&oslash;je f&oslash;lgende linje i
main()-metoden:</P>
<PRE CLASS="kode-western">    vindue.addWindowListener( new LukProgram() );</PRE>
<H2 CLASS="western" STYLE="">9.1 <a name='afsn9.1'></a>Klassen
Graphics</SPAN></H2>
<P CLASS="western">Graphics er beregnet til at tegne grafik (p&aring;
sk&aelig;rm eller printer). Man skal ikke selv oprette
Graphics-objekter med new, i stedet f&aring;r man givet et &quot;i
h&aring;nden&quot; af styresystemet. Herunder gengives kun nogle af
metoderne - se Javadokumentationen for en komplet liste. 
</P>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>java.awt.Graphics
- til tegning af grafik</I></FONT></P>
<P CLASS="klasseoversigt-western"><B>Metoder</B></P>
<P CLASS="klasseoversigt-western"><SPAN STYLE="font-weight: medium">void
</SPAN><B>drawString</B><SPAN STYLE="font-weight: medium">(String
tekst, int x, int y)<BR>tegner en tekst med &oslash;verste venstre
hj&oslash;rne i (x,y).</SPAN></P>
<P CLASS="klasseoversigt-western"><SPAN STYLE="font-weight: medium">void
</SPAN><B>drawImage</B><SPAN STYLE="font-weight: medium">(Image
billede, int x, int y, ImageObserver observat&oslash;r)<BR>tegner et
billede med &oslash;verste venstre hj&oslash;rne i (x,y); observat&oslash;r
b&oslash;r v&aelig;re vinduet (this).</SPAN></P>
<P CLASS="klasseoversigt-western"><SPAN STYLE="font-weight: medium">void
</SPAN><B>drawLine</B><SPAN STYLE="font-weight: medium">(int x1, int
y1, int x2, int y2)<BR>tegner en linje mellem punkterne (x1, y1) og
(x2, y2).</SPAN></P>
<P CLASS="klasseoversigt-western" STYLE="font-weight: medium">void
<B>drawRect</B>(int x, int y, int bredde, int h&oslash;jde) <BR>tegner
omridset af et rektangel.</P>
<P CLASS="klasseoversigt-western"><SPAN STYLE="font-weight: medium">void
</SPAN><B>drawRoundRect</B><SPAN STYLE="font-weight: medium">(int x,
int y, int bredde, int h&oslash;jde, int buebredde, int
bueh&oslash;jde)<BR>tegner omridset af et rektangel, der er afrundet
i hj&oslash;rnerne</SPAN>.</P>
<P CLASS="klasseoversigt-western"><SPAN STYLE="font-weight: medium">void
</SPAN><B>drawOval</B><SPAN STYLE="font-weight: medium">(int x, int
y, int bredde, int h&oslash;jde)<BR>tegner en oval med &oslash;verste
venstre hj&oslash;rne i (x,y). Er bredde==h&oslash;jde, tegnes en
cirkel.</SPAN></P>
<P CLASS="klasseoversigt-western"><SPAN STYLE="font-weight: medium">void
</SPAN><B>drawArc</B><SPAN STYLE="font-weight: medium">(int x, int y,
int bredde, int h&oslash;jde, int startvinkel, int vinkel)<BR>tegner
en del af en oval, men kun buen fra</SPAN> <SPAN STYLE="font-weight: medium"><I>startvinkel</I>
og <I>vinkel</I></SPAN> grader rundt (mellem 0 og 360).</P>
<P CLASS="klasseoversigt-western"><SPAN STYLE="font-weight: medium">void
</SPAN><B>drawPolygon</B><SPAN STYLE="font-weight: medium">(Polygon
p)<BR>tegner en polygon</SPAN> (mangekant) ud fra et Polygon-objekt.</P>

<P CLASS="klasseoversigt-western">Tilsvarende findes <SPAN STYLE="font-style: normal"><B>fillRect</B><SPAN STYLE="font-weight: medium">,
</SPAN><B>fillRoundRect</B><SPAN STYLE="font-weight: medium">,
</SPAN></SPAN><B>fillOval</B><SPAN STYLE="font-weight: medium">,
</SPAN><B>fillArc</B><SPAN STYLE="font-weight: medium"> og
</SPAN><B>fillPolygon</B>.</P>

<P CLASS="klasseoversigt-western">v<SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">oid
</SPAN><B>clearRect</B><SPAN STYLE="font-weight: medium">(int x, int
y, int bredde, int h&oslash;jde)<BR>udfylder et rektangel med
baggrundsfarven.</SPAN></SPAN></P>

<P CLASS="klasseoversigt-western"><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">Rectangle
</SPAN><B>getClipBounds</B><SPAN STYLE="font-weight: medium">()<BR>giver
klipnings-omridset. Kun punkter inden for dette omrids bliver faktisk
tegnet, ting uden for omridset bliver besk&aring;ret til den del, der
er inden for omridset.</SPAN></SPAN></P>
<P CLASS="klasseoversigt-western"><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">void
</SPAN><B>translate</B><SPAN STYLE="font-weight: medium">(int x, int
y)<BR>forskyder koordinatsystemet, s&aring;dan at (x,y) bliver (0,0)</SPAN></SPAN></P>

<P CLASS="klasseoversigt-western"><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">void
</SPAN><B>setColor</B><SPAN STYLE="font-weight: medium">(Color
nyFarve)<BR>s&aelig;tter  tegningsfarven  til nyFarve. Alt bliver
herefter tegnet med denne farve. </SPAN></SPAN>
</P>
<P CLASS="klasseoversigt-western" STYLE="font-style: normal; font-weight: medium">
Color <B>getColor</B>()<BR>afl&aelig;ser tegningsfarven. 
</P>

<P CLASS="klasseoversigt-western"><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">void
</SPAN><B>setFont</B><SPAN STYLE="font-weight: medium">(Font
nySkrifttype)<BR>s&aelig;tter skrifttypen til nySkrifttype. Dette
p&aring;virker tekster skrevet med drawString() herefter.</SPAN></SPAN></P>
<P CLASS="klasseoversigt-western"><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">Font
</SPAN><B>getFont</B><SPAN STYLE="font-weight: medium">()<BR>afl&aelig;ser
skrifttypen. </SPAN></SPAN>
</P>
<P CLASS="western">Har man brug for flere faciliteter til tegning af
2D-grafik end ovenst&aring;ende giver, kan man g&aring; over til at
bruge Java2D (se avanceret-afsnittet i slutningen af kapitlet).</P>
<H3 CLASS="western" STYLE="">9.1.1 <a name='afsn9.1.1'></a>Eksempel</H3>
<P CLASS="western">Her f&oslash;lger et eksempel, der viser mange af
mulighederne, der er med Graphics-objektet.</P>
<PRE CLASS="kode-western">import java.awt.*;
public class Grafikdemo extends Frame
{
  public void paint(Graphics g)
  {
    Insets in = getInsets();                <I>// kun Frame: forskyd nulpunktet</I>
    g.translate(in.left,in.top);            <I>// (0,0) til under titellinjen</I>

    <B>g.drawRoundRect</B>(10,10,80,80,25,25);     <I>// tegn rektangel med runde hj&oslash;rer</I>

    <B>g.drawArc</B>(110,10,80,80,20,320);         <I>// tegn buestykke</I>

    <B>g.fillArc</B>(210,10,80,80,20,320);         <I>// tegn lagkagestykke (udfyldt)</I>

    Polygon p = new Polygon();<I>              // lav polygon, der viser en pil:</I>
    p.addPoint(0,13);  p.addPoint(45,13);                    <I>// frem</I>
    p.addPoint(45,0);  p.addPoint(60,15); p.addPoint(45,30); <I>// spidsen</I>
    p.addPoint(45,17); p.addPoint(0,17);                     <I>// tilbage</I>

    p.translate(300,10);                    <I>// flyt polygonen</I>
    <B>g.drawPolygon</B>(p);                       <I>// tegn polygonen</I>

    p.translate(0,50);                      <I>// flyt polygonen mere</I>
    <B>g.fillPolygon</B>(p);                       <I>// tegn polygonen udfyldt</I>

    for (int i=0; i&lt;4; i++)                 <I>// tegn forskellige skriftst&oslash;rrelser</I>
    {
      int st&oslash;rrelse = 10+i*4;
      <B>Font skrifttype = </B>new Font(&quot;Serif&quot;, Font.ITALIC, st&oslash;rrelse);
      <B>g.setFont</B>(<B>skrifttype</B>);
      g.drawString(&quot;Skrift &quot;+st&oslash;rrelse, 400, 15+25*i);
    }

<I>    // Indl&aelig;s billede. Foruds&aelig;tter at &quot;bog.gif&quot; er der, hvor programmet k&oslash;res.</I>
<I>    // Bem&aelig;rk: I en applet, skriv i stedet getImage(getCodeBase(), &quot;bog.gif&quot;)</I>
<I>    // Bem&aelig;rk: Billedformatet skal v&aelig;re platformsneutralt, f.eks GIF, JPG, PNG.</I>
    Image billede = Toolkit.getDefaultToolkit().getImage(&quot;bog.gif&quot;);

    <B>g.drawImage</B>(billede, 110, 100, this);        <I> // tegn billedet</I>

    <B>g.drawImage</B>(billede, 0, 100, 100, 160, this);<I> // tegn billedet skaleret</I>
  }
}</PRE>
<P CLASS="western"><IMG SRC="bog10_html_68def7d5.png" NAME="Grafik15" ALIGN=LEFT BORDER=0><BR><BR>
</P>









<P CLASS="western" STYLE="; ">
Herunder er en klasse med en main()-metode, der &aring;bner vinduet.</P>
<PRE CLASS="kode-western" STYLE="">public class VisGrafikdemo
{
  public static void main(String[] arg)
  {
    Grafikdemo vindue = new Grafikdemo();
    vindue.setSize(500,200);
    vindue.setTitle(&quot;Grafikdemo&quot;);
<I>    // vindue.addWindowListener( new LukProgram() ); // defineret i <a href='kapitel13.jsp'>kapitel 13</a></I>
    vindue.setVisible(true);
  }
}</PRE><H2 CLASS="western" STYLE="">
9.2 <a name='afsn9.2'></a>Metoder i vinduer, som du kan kalde</SPAN></H2>
<P CLASS="western">Ud over at tegne grafik har man ogs&aring; ofte
brug for at p&aring;virke selve vinduet, f.eks s&aelig;tte vinduets
st&oslash;rrelse eller titel eller bede systemet om at gentegne
vinduet.</P>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Frame-klassens
metoder - (generel) betyder, at metoden ogs&aring; findes i andre
grafiske klasser.</I></FONT></P>
<P CLASS="klasseoversigt-western"><B>repaint</B>()    (generel)<BR>for&aring;rsager,
at systemet kalder paint() lidt senere, hvorved sk&aelig;rmen bliver
gentegnet.</P>

<P CLASS="klasseoversigt-western">void <B>setSize</B>(int bredde, int
h&oslash;jde)<BR>s&aelig;tter vinduets bredde og h&oslash;jde.</P>
<P CLASS="klasseoversigt-western">void <B>setLocation</B>(int x, int
y)<BR>s&aelig;tter vinduets position p&aring; sk&aelig;rmen.</P>
<P CLASS="klasseoversigt-western">void <B>setVisible</B>(boolean
synlig)<BR>bestemmer, om vinduet er synligt. <BR>Kald
setVisible(true) for at &aring;bne vinduet og setVisible(false) for
at lukke det.</P>
<P CLASS="klasseoversigt-western">void <B>setTitle</B>(String
titel)<BR>s&aelig;tter vinduets titel.</P>
<P CLASS="klasseoversigt-western">void <B>setCursor</B>(Cursor
museudseende)  (generel)<BR>bestemmer musens udseende (muligheder er
bl.a.: Cursor.DEFAULT_CURSOR, <BR>Cursor.HAND_CURSOR,
Cursor.CROSSHAIR_CURSOR, Cursor.MOVE_CURSOR)</P>
<P CLASS="klasseoversigt-western">void <B>setForeground</B>(Color
forgrundsfarve)  (generel)<BR>s&aelig;tter vinduets forgrundfarve, som
er den farve, Graphics-objektet normalt tegner med.</P>
<P CLASS="klasseoversigt-western">void <B>setBackground</B>(Color
baggrundsfarve)  (generel)<BR>s&aelig;tter vinduets baggrundfarve, som
er den farve, baggrunden bliver udfyldt med.</P>
<P CLASS="klasseoversigt-western"><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">void
</SPAN><B>setFont</B><SPAN STYLE="font-weight: medium">(Font
nySkrifttype)  (generel)<BR>s&aelig;tter vinduets skrifttype (som er
den skrifttype, Graphics-objektet normalt tegner med).</SPAN></SPAN></P>

<P CLASS="klasseoversigt-western">Dimension
<B>getSize</B>()<SPAN STYLE="font-weight: medium"><SPAN STYLE="font-style: normal">  (generel)</SPAN></SPAN><BR>returnerer
vinduets st&oslash;rrelse som et Dimension-objekt med bredde og
h&oslash;jde.</P>
<P CLASS="klasseoversigt-western">Tilsvarende findes <B>getLocation</B>,
<B>getTitle</B>, <B>getCursor</B>, <B>getForeground</B>,
<B>getBackground</B> og <B><SPAN STYLE="font-style: normal">getFont</SPAN></B>.</P>

<P CLASS="klasseoversigt-western">Insets <B>getInsets</B>()<BR>for
netop en Frame regnes koordinaterne inklusiv vinduets dekoration, s&aring;
(0,0) er normalt d&aelig;kket af titellinjen p&aring; vinduet. Denne
metode giver startkoordinaterne for <I>indholdet</I> af vinduet.</P>

<P CLASS="klasseoversigt-western">De af ovenst&aring;ende metoder,
der ogs&aring; findes i andre grafiske objekter, er  markeret med
<SPAN STYLE="font-weight: medium"><SPAN STYLE="font-style: normal">(generel)</SPAN></SPAN></P>

<P CLASS="western"><BR>Bem&aelig;rk, at der er forskel p&aring;, om
en metode p&aring; et objekt kaldes inde fra objektet, eller udefra.
Udefra kalder man metoden med en variabel, der peger p&aring;
objektet, det g&oslash;r man ikke indefra (man kan dog bruge 'this').
Dette er forklaret i <a href='kapitel4.jsp'>kapitel 4</a>, Definition af klasser.</P>
<P CLASS="western">S&aring;dan kaldes en metode <I>inde</I> fra
vinduet:</P>
<PRE CLASS="ikke-javakode-western">public class Grafikdemo extends Frame
{
  public void paint(Graphics g)
  {
    Dimension d = <B>this.getSize()</B>;                   <I>// eller bare: getSize()</I>
    System.out.println(&quot;Jeg har st&oslash;rrelsen: &quot;+d);</PRE>
<P CLASS="western">S&aring;dan kaldes en metode <I>udefra</I>:</P>
<PRE CLASS="ikke-javakode-western">public class VisGrafikdemo
{
  public static void main(String[] arg)
  {
    Grafikdemo vindue = new Grafikdemo();
    Dimension d = <B>vindue.getSize()</B>;
    System.out.println(&quot;Vinduet har st&oslash;rrelsen: &quot;+d);</PRE>
<H3 CLASS="western">9.2.1 <a name='afsn9.2.1'></a>Eksempel: Kurvetegning</H3>
<P CLASS="western">Her er en klasse, der tegner en farvet kurve over
sinus-funktionen.</P>
<P CLASS="western">I konstrukt&oslash;ren bestemmer vi farverne
(opretter Color-objekter) for punkterne, der skal tegnes. Her kalder
vi ogs&aring; setSize() og setVisible(true) for at &aring;bne
vinduet.</P>
<P CLASS="western">Vi tegner punkterne i paint(), der er gjort s&aring;
lille og hurtig som muligt (bl.a. ved ikke at oprette objekter i dene
metode) - den kaldes jo hver gang vinduet bliver gentegnet.</P>
<P CLASS="western">Farverne huskes i en liste, der er defineret som
objektvariabel (s&aring;dan at den er kendt, s&aring; l&aelig;nge
Kurvetegning-objektet findes). P&aring; den m&aring;de f&aring;r vi
data fra konstrukt&oslash;r til paint().</P>
<PRE CLASS="kode-western">import java.util.*;
import java.awt.*;
public class Kurvetegning extends Frame
{
  <B>ArrayList<I>&lt;Color&gt; farver</I></B><I>;//objektvariabel kendt i b&aring;de konstrukt&oslash;ren og paint()</I>
  int forskydning = 50;  <I>// en forskydning i farvevalget (bruges i <a href='kapitel9.jsp#afsn9.4.1'>afsnit 9.4.1</a>)</I>

  public Kurvetegning()  <I>// forbered punkterne i konstrukt&oslash;ren</I>
  {
    <B>farver = new ArrayList&lt;Color&gt;()</B>;
    for (int i=0; i&lt;400; i++)
    {
      Color farve = new Color(i%256, (i*2)%256, (i*4)%256);
      <B>farver.add(farve)</B>;
    }

    this.setSize(400,300);  <I>// eller fra main(): vindue.setSize(400,300)</I>
    this.setVisible(true);  <I>// eller fra main(): vindue.setVisible(true)</I>
  }

  public void paint(Graphics g) <I>// tegn punkterne</I>
  {
    g.drawString(&quot;Kurvetegning&quot;, forskydning%400, forskydning%300);
    for (int x=0; x&lt;farver.size(); x++)
    {
      int y = 150 - (int) (120*Math.sin(0.05*x));
      int i = (x+forskydning)%400;
      Color <B>farve = farver.get(i)</B>;
      g.setColor(farve);
      g.fillRect(x, y, 5, 5);
    }
  }
}</PRE>
<P CLASS="western"><IMG SRC="bog10_html_m5c80685d.png" NAME="Grafik16" ALIGN=RIGHT BORDER=0>Her
er klassen, der opretter Kurvetegning-objektet:</P>
<PRE CLASS="kode-western">public class VisKurvetegning
{
  public static void main(String[] arg)
  {
    Kurvetegning vindue = new Kurvetegning();
  }
}</PRE>

<H2 CLASS="western">9.3 <a name='afsn9.3'></a>Opgaver</SPAN></H2>
<OL>
  <LI><P CLASS="western">&AElig;ndr GrafiskVindue til at tegne nogle
  andre figurer. 
  </P>
  <LI><P CLASS="western">Skiv noget ud n&aring;r paint() bliver kaldt
  (med System.out.println()) og se hvorn&aring;r paint() bliver kaldt
  (pr&oslash;v f.eks. at minimere og gendanne vinduet eller d&aelig;kke
  det halvt over). 
  </P>
  <LI><P CLASS="western">Lav et program, der viser et digitalur som
  tekst (vink: Brug et Date-objekt).<BR>S&oslash;rg for, at uret
  opdateres hvert sekund (vink: se 9.4.1, Simple animationer)).</P>
  <LI><P CLASS="western">Lav et program, der viser et analogt
  ur.<BR>Vink: Du kan benytte f&oslash;lgende formler til at beregne
  viserens l&aelig;ngde i de to retninger: <BR>x =
  r*Math.sin(2*Math.PI*s/60); y = r*Math.cos(2*Math.PI*s/60) <BR>Lad
  urets st&oslash;rrelse afh&aelig;nge af vinduets st&oslash;rrelse
  (vink: Brug getSize()).</P>
  <LI><P CLASS="western">&AElig;ndr GrafiskVindue, s&aring; den tegner
  et skakbr&aelig;t med sorte og hvide felter. <BR>En springer og en
  bonde tegnes derefter p&aring; br&aelig;ttet. 
  </P>
  <LI><P CLASS="western">&AElig;ndr programmet, s&aring;dan at det er
  nemt at &aelig;ndre brikkernes koordinater. Koordinaterne gemmes i
  to Point-objekter: <BR><FONT FACE="Courier, monospace"><FONT SIZE=1 STYLE="font-size: 8pt"><SPAN STYLE="font-weight: medium"><SPAN STYLE="background: #d9d9d9">Point
  t&aring;rn  = new Point(100,200);                                   
             <BR>Point bonde = new Point(200,200);                    
                            </SPAN></SPAN></FONT></FONT>
  </P>
</OL>
<H3 CLASS="western">9.3.1 <a name='afsn9.3.1'></a>Opgave: Grafisk Matador-spil</H3>
<P CLASS="western">Udvid matadorspillet fra <a href='kapitel5.jsp'>kapitel 5</a>, Nedarvning,
til at kunne vises grafisk i et vindue.</P>
<P CLASS="western">&AElig;ndr SpilMatador s&aring;dan, at den ogs&aring;
opretter et grafisk vindue, der viser br&aelig;ttet. <BR>Lad
programmet spille en tur hvert sekund, eller lad brugeren styre (se
f.eks <a href='kapitel2.jsp#afsn2.12.3'>afsnit 2.12.3</a>).</P>

<H4 CLASS="western">Vink</H4>
<P CLASS="western">N&aring;r du skal programmere, s&aring; v&aelig;r
systematisk og del opgaven op i sm&aring; delopgaver. L&oslash;s en
delopgave ad gangen og afpr&oslash;v om det fungerer, f&oslash;r du
g&aring;r videre.</P>
<OL>
  <LI><P CLASS="western">Hent kildeteksten til matadorspillet (version
  2: Felt.java, Gade2.java, Grund2.java, Helle.java, Rederi2.java,
  Start.java, Spiller.java og SpilMatador.java &aelig;ndret til at
  bruge Gade2 og Rederi2) og pr&oslash;v det.</P>
  <LI><P CLASS="western">Genbrug GrafiskVindue ovenfor. Lad
  initialisering ske i konstrukt&oslash;ren. Variabler, der skal deles
  mellem flere metoder, skal v&aelig;re objektvariabler (de
  lokale eksisterer jo kun i den metode, de er defineret i).</P>
  <LI><P CLASS="western">F&oslash;j en metode til Felt, der tegner
  feltet. Hvert felt skal ogs&aring; have en position (den er en del
  af initialiseringen, s&aring; s&aelig;t den fra konstrukt&oslash;ren).
    </P>
  <LI><P CLASS="western">L&oslash;b igennem alle felter og tegn dem i
  paint().</P>
  <LI><P CLASS="western">Udbyg derefter spillet efter egen smag. Tegn
  f.eks. ogs&aring; spillerne og deres biler.</P>
</OL>


<P CLASS="western" ALIGN=CENTER><IMG SRC="bog10_html_m60d186b8.png" NAME="Grafik11" ALIGN=BOTTOM BORDER=0></P>

<H4 CLASS="western">Flere vink og l&oslash;sningsforslag</H4>
<P CLASS="western">Det er bedst, at du bruger hovedet og kun ser p&aring;
vinkene, hvis du er g&aring;et i st&aring;.</P>
<OL>
  <LI><P CLASS="western">Pr&oslash;ve programmet.<BR>Har du ikke
  allerede pr&oslash;vet matadorspillet, s&aring; pr&oslash;v at k&oslash;re
  programmet og forst&aring; hvordan det virker. Herefter er det
  naturligvis meget lettere, at lave en grafisk udgave! Brug trinvis
  gennemgang (trace into/step over), indtil du f&oslash;ler, du har
  forst&aring;et programkoden. F&oslash;rst da er du klar til at pr&oslash;ve
  grafisk.</P>
</OL>

<OL START=2>
  <LI><P CLASS="western">Struktur i et grafisk vindue.<BR>Flyt
  initialiseringen fra SpilMatador.java til konstrukt&oslash;ren af
  GrafiskVindue. Husk at importere java.util.* &oslash;verst for at f&aring;
  adgang til ArrayList-klassen. Variablerne felter, sp1, sp2 skal nu
  v&aelig;re objektvariabler (f&oslash;r var de lokale variabler), for
  at de kan ses i resten af objektet:</P>
</OL>
<PRE CLASS="ikke-javakode-western">import java.awt.*;
import java.util.*;
public class GrafiskVindue extends Frame
{
<I>  // objektvariabler:</I>
  Spiller sp1=new Spiller(&quot;S&oslash;ren&quot;,50000,Color.GREEN); <I>   // opret spiller 1 </I>
  Spiller sp2=new Spiller(&quot;Gitte&quot;,50000,Color.YELLOW);<I>   // opret spiller 2 </I>
  ArrayList felter=new ArrayList(); 

  public GrafiskVindue()
  { 
    felter.add(new Start(5000)); 
    felter.add(new Gade2(&quot;Gade 1&quot;,10000, 400,1000)); 
    felter.add(new Gade2(&quot;Gade 2&quot;,10000, 400,1000)); 
<I>    //... osv. </I></PRE><P CLASS="western" STYLE="margin-left: 0.5cm">
Husk, at vinduet f&oslash;rst tegnes, n&aring;r initialiseringen er
f&aelig;rdig, s&aring; hvis du f.eks. k&oslash;rer 20 runder i
initialiseringen, tager det lang tid, f&oslash;rend systemet n&aring;r
til at kalde paint()!</P>


<OL START=3>
  <LI><P CLASS="western">Hvert felt skal have en position. F&oslash;j
  en position (af typen Point) til Felt-klassen:</P>
</OL>
<PRE CLASS="ikke-javakode-western">import java.awt.*; 
public class Felt 
{ 
  String navn; 
  Point position = new Point();</PRE><P CLASS="western">
  og defin&eacute;r metoden tegn(Graphics g) p&aring; Felt, der tegner
feltets navn p&aring; positionen: 
</P>
<PRE CLASS="kode-western">  public void tegn(Graphics g) 
  { 
    g.setColor(Color.BLACK); 
    g.drawString(navn,position.x,position.y); 
  }</PRE><P CLASS="western" STYLE="margin-left: 0.5cm">
Husk at importere java.awt.* &oslash;verst for at f&aring; adgang til
Point- og Graphics-klassen. 
</P>
<P CLASS="western" STYLE="margin-left: 0.5cm">L&oslash;b alle
felterne igennem i konstrukt&oslash;ren og s&aelig;t koordinaterne p&aring;
felterne:</P>
<PRE CLASS="kode-western">    felter.add(new Gade2(&quot;Gade 8&quot;,20000,1100,2000)); 
    felter.add(new Gade2(&quot;Gade 9&quot;,30000,1500,2200)); 
    for (int i=0; i&lt;felter.size(); i++)
    {
      double v = Math.PI*2*i/felter.size(); <I>// vinkel i radianer</I>
      Felt f = felter.get(i); 
      f.position = new Point( 
        100 + (int) (100*Math.cos(v)),  
        110 + (int) (100*Math.sin(v)) 
      ); 
    }</PRE>
<OL START=4>
  <LI><P CLASS="western">Defin&eacute;r vinduets paint()-metode til at
  kalde felternes tegn() for at tegne br&aelig;ttet:</P>
</OL>
<PRE CLASS="kode-western">  public void paint(Graphics g) 
  {
    for (int i=0; i&lt;felter.size(); i++) 
    {
      Felt f = felter.get(i); 
      f.tegn(g); 
    }</PRE><P CLASS="western" STYLE="margin-left: 0.5cm">
En grund skal ogs&aring; have tegnet ejeren nedenunder, s&aring; den
skal have en anderledes tegn(). Defin&eacute;r tegn() i Grund2. En
gade skal ogs&aring; vise antallet af huse. Defin&eacute;r ogs&aring;
tegn() i Gade2.</P>
<H2 CLASS="western" STYLE="">9.4 <a name='afsn9.4'></a>Avanceret</SPAN></H2>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_OOP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/OOP3/kapitel9.jsp#afsn9.4">
  <input type='checkbox' name='vis' value='9.4'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='9.4'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H3 CLASS="western">9.4.1 <a name='afsn9.4.1'></a>Simple animationer</H3>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_OOP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/OOP3/kapitel9.jsp#afsn9.4.1">
  <input type='checkbox' name='vis' value='9.4.1'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='9.4.1'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H3 CLASS="western">9.4.2 <a name='afsn9.4.2'></a>Animationer med en separat tr&aring;d</H3>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_OOP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/OOP3/kapitel9.jsp#afsn9.4.2">
  <input type='checkbox' name='vis' value='9.4.2'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='9.4.2'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H3 CLASS="western" STYLE="">9.4.3 <a name='afsn9.4.3'></a>Undg&aring;
blinkeri ved ikke at slette gammel grafik</H3>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_OOP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/OOP3/kapitel9.jsp#afsn9.4.3">
  <input type='checkbox' name='vis' value='9.4.3'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='9.4.3'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H3 CLASS="western">9.4.4 <a name='afsn9.4.4'></a>Undg&aring; blinkeri ved kun at slette det
n&oslash;dvendige</H3>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_OOP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/OOP3/kapitel9.jsp#afsn9.4.4">
  <input type='checkbox' name='vis' value='9.4.4'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='9.4.4'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H3 CLASS="western" STYLE="">9.4.5 <a name='afsn9.4.5'></a>Grafikbuffer
(double buffering)</H3>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_OOP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/OOP3/kapitel9.jsp#afsn9.4.5">
  <input type='checkbox' name='vis' value='9.4.5'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='9.4.5'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H3 CLASS="western">9.4.6 <a name='afsn9.4.6'></a>Java2D - avanceret grafiktegning</H3>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_OOP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/OOP3/kapitel9.jsp#afsn9.4.6">
  <input type='checkbox' name='vis' value='9.4.6'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='9.4.6'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  

<a href='http://javabog.dk/'>javabog.dk</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel8.jsp'>&lt;&lt; forrige</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='indhold.jsp'>indhold</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel10.jsp'>n&aelig;ste &gt;&gt;</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kode/'>programeksempler</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='../index_OOP.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 (82% af værket).
</font>
<br>
Ønsker du at se de sidste 18% af dette værk (199974 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>
