



<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 LANG="da-DK" CLASS="kapiteloversigt-western">Indhold:</P>
<UL>
  <LI VALUE=1><P LANG="da-DK" CLASS="kapiteloversigt-western">Oprettelse
  og brug af grafiske vinduer</P>
  <LI VALUE=1><P LANG="da-DK" CLASS="kapiteloversigt-western">At tegne
  grafik med Graphics-objektet</P>
  <LI><P LANG="da-DK" CLASS="kapiteloversigt-western">St&oslash;rre
  opgave: Matador-spillet som et grafisk program</P>
</UL>
<P LANG="da-DK" 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 LANG="da-DK" 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 LANG="da-DK" CLASS="western" STYLE="">Vi
kan tegne grafik p&aring; sk&aelig;rmen ved at skrive en klasse, der
arver fra klassen JPanel og definere metoden paintComponent(). Dette
metode vil systemet kalde for at f&aring; grafikken tegnet p&aring;
sk&aelig;rmen. Systemet overf&oslash;rer et Graphics-objekt
(beskrevet i <a href='kapitel9.jsp#afsn9.1'>afsnit 9.1</a>), som vi kan bruge til at tegne med.</P>
<P LANG="da-DK" 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.*;
import javax.swing.*;

public class Grafikpanel <B>extends JPanel</B>
{
<B>  public void paintComponent(Graphics g)</B>
  {
<I>    // Herunder referer g til et Graphics-objekt man kan tegne med</I>

    super.paintComponent(g);                <I>// tegn f&oslash;rst baggrunden p&aring; panelet</I>

    g.drawLine(0,0,50,50);

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

    g.setColor(Color.GREEN);

    g.drawString(&quot;Hej grafiske verden!&quot;,100,30);
  }
}</PRE><P LANG="da-DK" CLASS="western">
For at vise grafikken p&aring; sk&aelig;rmen skal vi definere en
main()-metode, der opretter et Grafikpanel-objekt og et vindue, som
viser panelet:</P>
<PRE CLASS="kode-western">import javax.swing.*;

public class BenytGrafikpanel
{
  public static void main(String[] arg)
  {
    Grafikpanel panel = new Grafikpanel();        <I>// opret panelet</I>

    JFrame vindue = new JFrame(&quot;Grafikpanel&quot;);    <I>// opret et vindue p&aring; sk&aelig;rmen</I>
    vindue.add( panel );                          <I>// vis panelet i vinduet</I>

    vindue.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); <I>// reag&eacute;r p&aring; luk</I>
    vindue.setSize(350,70);                       <I>// s&aelig;t vinduets st&oslash;rrelse</I>
    vindue.setVisible(true);                      <I>// &aring;bn vinduet</I>
  }
}</PRE>
<P LANG="da-DK" CLASS="western">Her ses, hvordan vinduet ser ud p&aring;
sk&aelig;rmen (under Linux):</P>
<P LANG="da-DK" CLASS="western"><IMG SRC="bog10_html_m33873599.png" NAME="grafik13" ALIGN=LEFT BORDER=0><BR CLEAR=LEFT><BR><BR>
</P>
<P LANG="da-DK" CLASS="western">Vinduets &oslash;verste venstre
hj&oslash;rne er i (0,0) og koordinaterne regnes mod h&oslash;jre og
nedad.</P>

<H2 CLASS="western" STYLE="">9.1 <a name='afsn9.1'></a>Klassen
Graphics</SPAN></H2>
<P LANG="da-DK" 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 LANG="da-DK" 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 LANG="da-DK" CLASS="klasseoversigt-western"><B>Metoder</B></P>
<P LANG="da-DK" 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 LANG="da-DK" 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 objektet selv (this).</SPAN></P>
<P LANG="da-DK" 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 LANG="da-DK" 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 LANG="da-DK" 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 LANG="da-DK" 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 LANG="da-DK" 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> <I><SPAN STYLE="font-weight: medium">startvinkel</SPAN></I><SPAN STYLE="font-weight: medium">
og </SPAN><I><SPAN STYLE="font-weight: medium">vinkel</SPAN></I>
grader rundt (mellem 0 og 360).</P>
<P LANG="da-DK" 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 LANG="da-DK" CLASS="klasseoversigt-western">Tilsvarende findes
<SPAN STYLE="font-style: normal"><B>fillRect</B></SPAN><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">,
</SPAN></SPAN><SPAN STYLE="font-style: normal"><B>fillRoundRect</B></SPAN><SPAN STYLE="font-style: normal"><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 LANG="da-DK" CLASS="klasseoversigt-western">v<SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">oid
</SPAN></SPAN><SPAN STYLE="font-style: normal"><B>clearRect</B></SPAN><SPAN STYLE="font-style: normal"><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 LANG="da-DK" CLASS="klasseoversigt-western"><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">Rectangle
</SPAN></SPAN><SPAN STYLE="font-style: normal"><B>getClipBounds</B></SPAN><SPAN STYLE="font-style: normal"><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 LANG="da-DK" CLASS="klasseoversigt-western"><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">void
</SPAN></SPAN><SPAN STYLE="font-style: normal"><B>translate</B></SPAN><SPAN STYLE="font-style: normal"><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 LANG="da-DK" CLASS="klasseoversigt-western"><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">void
</SPAN></SPAN><SPAN STYLE="font-style: normal"><B>setColor</B></SPAN><SPAN STYLE="font-style: normal"><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 LANG="da-DK" CLASS="klasseoversigt-western" STYLE="font-style: normal; font-weight: medium">
Color <B>getColor</B>()<BR>afl&aelig;ser tegningsfarven. 
</P>

<P LANG="da-DK" CLASS="klasseoversigt-western"><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">void
</SPAN></SPAN><SPAN STYLE="font-style: normal"><B>setFont</B></SPAN><SPAN STYLE="font-style: normal"><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 LANG="da-DK" CLASS="klasseoversigt-western"><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">Font
</SPAN></SPAN><SPAN STYLE="font-style: normal"><B>getFont</B></SPAN><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">()<BR>afl&aelig;ser
skrifttypen. </SPAN></SPAN>
</P>
<P LANG="da-DK" CLASS="western">Har man brug for flere faciliteter
til tegning af 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:
Grafikdemo</H3>
<P LANG="da-DK" 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.*;
import javax.swing.*;

public class Grafikdemo extends JPanel
{
  public void paintComponent(Graphics g)
  {
    super.paintComponent(g);                <I>// tegn f&oslash;rst baggrunden p&aring; panelet</I>

    <B>g.drawRoundRect</B>(10,10,80,80,25,25);     <I>// tegn rektangel med runde hj&oslash;rner</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><IMG SRC="bog10_html_m6492783d.png" NAME="grafik14" ALIGN=LEFT BORDER=0>
  }
}</PRE>






<P LANG="da-DK" CLASS="western">Og main()-metode:</P>
<PRE CLASS="kode-western">import javax.swing.*;

public class BenytGrafikdemo
{
  public static void main(String[] arg)
  {
    JFrame vindue = new JFrame(&quot;Grafikdemo&quot;);     <I>// opret et vindue p&aring; sk&aelig;rmen</I>
    vindue.add( new Grafikdemo() );               <I>// vis panelet i vinduet</I>
    vindue.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); <I>// reag&eacute;r p&aring; luk</I>
    vindue.setSize(500,200);                      <I>// s&aelig;t vinduets st&oslash;rrelse</I>
    vindue.setVisible(true);                      <I>// &aring;bn vinduet</I>
  }
}</PRE><H3 CLASS="western">
9.1.2 <a name='afsn9.1.2'></a>Eksempel: Kurvetegning</H3>
<P LANG="da-DK" CLASS="western">Her er en klasse, der tegner en
farvet kurve over sinus-funktionen.</P>
<P LANG="da-DK" CLASS="western">I konstrukt&oslash;ren bestemmer vi
farverne (opretter Color-objekter) for punkterne, der skal tegnes (vi
bruger heltalsdivision med %, se <a href='kapitel2.jsp#afsn2.11.4'>afsnit 2.11.4</a>, for at f&aring; nogle
gode farvev&aelig;rdier). 
</P>
<P LANG="da-DK" CLASS="western">Her opretter vi ogs&aring; et vindue
og viser panelet p&aring; sk&aelig;rmen (bem&aelig;rk, at fordi vi
g&oslash;r det inden i panel-objektet, skal vi skrive
vindue.add(this) i stedet for vindue.add(panel)).</P>
<P LANG="da-DK" CLASS="western">Vi tegner punkterne i
paintComponent(), der er gjort s&aring; lille og hurtig som muligt
(bl.a. ved ikke at oprette objekter i denne metode) - den kaldes jo
hver gang sk&aelig;rmen skal opdateres.</P>
<P LANG="da-DK" CLASS="western">Farverne huskes i listen <FONT FACE="Courier, monospace"><FONT SIZE=2 STYLE="font-size: 9pt"><SPAN STYLE="font-weight: medium"><SPAN STYLE="background: transparent">farver</SPAN></SPAN></FONT></FONT>,
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 overf&oslash;rt fra konstrukt&oslash;r til
paintComponent().</P>
<PRE CLASS="kode-western">import java.awt.*;
import javax.swing.*;
import java.util.*;

public class Kurvetegning extends JPanel
{
  <B>ArrayList&lt;Color&gt; farver;</B><I>//objektvariabel kendt i konstrukt&oslash;r og paintComponent</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>;
    }

    JFrame vindue = new JFrame(&quot;Kurvetegning&quot;);   <I>// opret et vindue p&aring; sk&aelig;rmen</I>
    vindue.add( this );                           <I>// vis dette panel i vinduet</I>
    vindue.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); <I>// reag&eacute;r p&aring; luk</I>
    vindue.setSize(400,300);                      <I>// s&aelig;t vinduets st&oslash;rrelse</I>
    vindue.setVisible(true);                      <I>// &aring;bn vinduet</I>
  }

  public void paintComponent(Graphics g) <I>// tegn punkterne</I>
  {
    super.paintComponent(g);            <I>// tegn f&oslash;rst baggrunden p&aring; panelet</I>

    g.drawString(&quot;Kurvetegning&quot;, forskydning%400, forskydning%300);
    for (int x=0; x&lt;farver.size(); x++)
    {
      int y = 140 - (int) (130*Math.sin(0.05*x));
      int i = (x+forskydning)%400;<IMG SRC="bog10_html_mea27f7.png" NAME="Grafik16" ALIGN=LEFT BORDER=0>
      Color <B>farve = farver.get(i)</B>;
      g.setColor(farve);
      g.fillRect(x, y, 5, 5);
    }
  }
}</PRE>
<P LANG="da-DK" CLASS="western">Her er klassen, der opretter
Kurvetegning-objektet:</P>
<PRE CLASS="kode-western">public class BenytKurvetegning
{
  public static void main(String[] arg)
  {
    Kurvetegning kt = new Kurvetegning();
  }
}</PRE>

<H2 CLASS="western" STYLE="">9.2 <a name='afsn9.2'></a>Metoder du
kan kalde</SPAN></H2>
<P LANG="da-DK" CLASS="western">Ud over at tegne grafik har man ogs&aring;
ofte brug for at p&aring;virke selve vinduet eller panelet, f.eks
s&aelig;tte vinduets st&oslash;rrelse eller titel eller bede systemet
om at gentegne sk&aelig;rmen.</P>
<P LANG="da-DK" ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm">
<FONT SIZE=2 STYLE="font-size: 9pt"><I>JFrame-klassens metoder -
(generel) betyder, at metoden ogs&aring; findes i andre grafiske
klasser.</I></FONT></P>
<P LANG="da-DK" CLASS="klasseoversigt-western"><B>repaint</B>()    (generel)<BR>for&aring;rsager,
at systemet kalder paintComponent() lidt senere, hvorved
vinduet/panelet bliver gentegnet.</P>

<P LANG="da-DK" CLASS="klasseoversigt-western">void <B>setSize</B>(int
bredde, int h&oslash;jde)  (generel)<BR>s&aelig;tter bredden og
h&oslash;jden.</P>
<P LANG="da-DK" CLASS="klasseoversigt-western">void <B>setLocation</B>(int
x, int y)  (kun JFrame)<BR>s&aelig;tter vinduets position p&aring;
sk&aelig;rmen.</P>
<P LANG="da-DK" CLASS="klasseoversigt-western">void <B>setTitle</B>(String
titel)  (kun JFrame)<BR>s&aelig;tter vinduets titel.</P>
<P LANG="da-DK" CLASS="klasseoversigt-western">void
<B>setVisible</B>(boolean synlig)  (generel)<BR>bestemmer, om
vinduet/panelet/komponenten er synlig. <BR>Kald setVisible(true) for
at &aring;bne et vindue og setVisible(false) for at lukke det.</P>
<P LANG="da-DK" 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 LANG="da-DK" CLASS="klasseoversigt-western">void
<B>setForeground</B>(Color forgrundsfarve)  (generel)<BR>s&aelig;tter
forgrundfarven, som er den farve, Graphics-objektet normalt tegner
med.</P>
<P LANG="da-DK" CLASS="klasseoversigt-western">void
<B>setBackground</B>(Color baggrundsfarve)  (generel)<BR>s&aelig;tter
baggrundfarven, som er den farve, baggrunden bliver udfyldt med.</P>
<P LANG="da-DK" CLASS="klasseoversigt-western"><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">void
</SPAN></SPAN><SPAN STYLE="font-style: normal"><B>setFont</B></SPAN><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: medium">(Font
nySkrifttype)  (generel)<BR>s&aelig;tter skrifttypen (som er den
skrifttype, Graphics-objektet normalt tegner med).</SPAN></SPAN></P>

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

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

<P LANG="da-DK" CLASS="western">Bem&aelig;rk at det er <I>systemet</I>
og ikke dig, der kalder paintComponent().</P>
<BLOCKQUOTE LANG="da-DK" CLASS="definition-western">Metoden
paintComponent() kaldes af systemet n&aring;r vinduet skal gentegnes</BLOCKQUOTE>
<BLOCKQUOTE LANG="da-DK" CLASS="definition-western">Det er n&aelig;sten
altid en fejl at kalde paintComponent() fra sin egen kode</BLOCKQUOTE>
<BLOCKQUOTE LANG="da-DK" CLASS="definition-western">&Oslash;nsker man
at vinduet skal gentegnes, kalder man repaint()</BLOCKQUOTE>
<P LANG="da-DK" CLASS="western">I <a href='kapitel9.jsp#afsn9.4.4'>afsnit 9.4.4</a>, Passiv versus aktiv visning,
vil dette blive uddybet.</P>

<P LANG="da-DK" CLASS="western" STYLE="">Bem&aelig;rk
ogs&aring;, 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 <FONT FACE="Courier, monospace"><FONT SIZE=2 STYLE="font-size: 9pt"><SPAN STYLE="font-weight: medium"><SPAN STYLE="background: transparent">this</SPAN></SPAN></FONT></FONT>).
Dette er forklaret i <a href='kapitel4.jsp'>kapitel 4</a>, Definition af klasser.</P>
<P LANG="da-DK" CLASS="western">S&aring;dan kaldes en metode <I>inde</I>
fra panelet:</P>
<PRE CLASS="ikke-javakode-western">public class Grafikpanel extends JPanel
{
  public void paintComponent(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 LANG="da-DK" CLASS="western">
S&aring;dan kaldes en metode <I>udefra</I>:</P>
<PRE CLASS="ikke-javakode-western">public class BenytGrafikpanel
{
  public static void main(String[] arg)
  {
    Grafikpanel panel = new Grafikpanel();

    ...

    Dimension d = <B>panel.getSize()</B>;
    System.out.println(&quot;Panelet har st&oslash;rrelsen: &quot;+d);
  }
}</PRE>
<H2 CLASS="western">9.3 <a name='afsn9.3'></a>Opgaver</SPAN></H2>
<OL>
  <LI><P LANG="da-DK" CLASS="western">&AElig;ndr Grafikpanel til at
  tegne nogle andre figurer. 
  </P>
  <LI><P LANG="da-DK" CLASS="western">Skriv noget ud n&aring;r
  paintComponent() bliver kaldt (med System.out.println()) og se
  hvorn&aring;r paintComponent() bliver kaldt (pr&oslash;v f.eks. at
  minimere og gendanne vinduet eller d&aelig;kke det halvt over). 
  </P>
  <LI><P LANG="da-DK" 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 LANG="da-DK" 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><FONT FACE="Courier, monospace"><FONT SIZE=1 STYLE="font-size: 8pt"><SPAN STYLE="font-weight: medium"><SPAN STYLE="background: #e6e6e6">x
  = r*Math.sin(2*Math.PI*s/60); y = r*Math.cos(2*Math.PI*s/60) </SPAN></SPAN></FONT></FONT><BR>Lad
  urets st&oslash;rrelse afh&aelig;nge af panelets st&oslash;rrelse
  (vink: Brug getSize()).</P>
  <LI><P LANG="da-DK" CLASS="western">&AElig;ndr Grafikpanel, s&aring;
  den tegner et skakbr&aelig;t med sorte og hvide felter. <BR>Et t&aring;rn
  og en bonde tegnes derefter p&aring; br&aelig;ttet. 
  </P>
  <LI><P LANG="da-DK" CLASS="western">&AElig;ndr programmet, s&aring;dan
  at det er nemt at &aelig;ndre brikkernes koordinater. <BR>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: #e6e6e6">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 LANG="da-DK" CLASS="western">Udvid matadorspillet fra <a href='kapitel5.jsp'>kapitel 5</a>,
Nedarvning, til at kunne vises grafisk i et vindue.</P>
<H4 CLASS="western">Vink</H4>
<P LANG="da-DK" 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 LANG="da-DK" CLASS="western">Hent kildeteksten til
  matadorspillet (version 2: Felt.java, Gade2.java, Grund2.java,
  Helle.java, Rederi2.java, Start.java, Spiller.java,
  BenytMatadorspil.java og Matadorspil.java &aelig;ndret til at bruge
  Gade2 og Rederi2) og pr&oslash;v det.</P>
  <LI><P LANG="da-DK" CLASS="western" STYLE="">
  Genbrug Grafikpanel 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). Tjek om spillet stadig kan k&oslash;re.</P>
  <LI><P LANG="da-DK" CLASS="western">Udbyg derefter Grafikpanel til
  at tegne felternes navne og evt ogs&aring; spillerne og bilerne.</P>
  <LI><P LANG="da-DK" CLASS="western">Felterne b&oslash;r tegnes
  specielt afh&aelig;ngigt af deres type, s&aring;dan at f.eks. en
  gade ogs&aring; kan vise hvor mange huse, der er p&aring; den.
  Defin&eacute;r tegn(Graphics g, int x, int y) p&aring; Felt.</P>
</OL>
<P LANG="da-DK" 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 LANG="da-DK" 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 LANG="da-DK" 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.<BR><BR><BR>
  </P>
  <LI><P LANG="da-DK" CLASS="western">Struktur i et grafisk
  program.<BR>Lav en reference i Grafikpanel til Matadorspil (evt.
  overf&oslash;rt i konstrukt&oslash;ren):</P>
</OL>
<PRE CLASS="ikke-javakode-western">import java.awt.*;
import javax.swing.*;

public class MatadorGrafikpanel extends JPanel
{
  Matadorspil spil;</PRE><P LANG="da-DK" 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
konstrukt&oslash;ren, tager det lang tid, f&oslash;r systemet kalder
paintComponent()!</P>

<OL START=3>
  <LI><P LANG="da-DK" CLASS="western">Defin&eacute;r panelets
  paintComponent()-metode til at tegne felternes navne:</P>
</OL>
<PRE CLASS="kode-western">  public void paintComponent(Graphics g) 
  {
    super.paintComponent(g);    <I>// tegn f&oslash;rst baggrunden p&aring; panelet</I>

    for (int i = 0; i &lt; felter.size(); i++) {
      Felt felt = felter.get(i);

      double v = Math.PI * 2 * i / felter.size(); <I>// vinkel i radianer</I>
      int x = 100 + (int) (100 * Math.cos(v));
      int y = 110 + (int) (100 * Math.sin(v));

      g.setColor(Color.BLACK);
      g.drawString(felt.navn, x, y);              <I>// tegn feltets navn</I></PRE>
<OL START=4>
  <LI><P LANG="da-DK" CLASS="western" STYLE="">
  Nu &aelig;ndrer du s&aring;dan, at felterne har deres egen
  tegnemetode (der tegner navnet):</P>
</OL>
<PRE CLASS="ikke-javakode-western">public class Felt
{
  String navn;

  public void tegn(Graphics g, int x, int y) 
  {
    g.drawString(f.navn, x, y);
  }</PRE>
<P LANG="da-DK" CLASS="western" STYLE="margin-left: 0.5cm">... og i
Grafikpanel definerer lader vi paintComponent()-metoden kalde tegn():</P>
<PRE CLASS="kode-western">      g.setColor(Color.BLACK);
      felt.tegn(g, x, y);</PRE>
<P LANG="da-DK" CLASS="western" STYLE="margin-left: 0.5cm">Grund2
skal ogs&aring; tegne en ejer, s&aring; den f&aring;r sin egen
tegn()-metode</P>
<PRE CLASS="kode-western">  public void tegn(Graphics g, int x, int y) 
  {
    super.tegn(g, x, y);  <I>// kald Felts tegn() for at tegne navnet</I>
    if (ejer != null) g.drawString(ejer.navn, x, y+15);
  }</PRE>
<P LANG="da-DK" CLASS="western" STYLE="margin-left: 0.5cm">Ligeledes
med Gade2, der ogs&aring; skal vise et antal huse:</P>
<PRE CLASS="kode-western">  public void tegn(Graphics g, int x, int y) 
  {
    super.tegn(g, x, y);  <I>// kald Grund2s tegn() for at tegne navnet og ejeren</I>
    if (antalHuse &gt; 0) g.drawString(antalHuse + &quot; huse&quot;, x, y+30);
  }</PRE>

<H2 CLASS="western">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/OOP/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/OOP/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/OOP/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">9.4.3 <a name='afsn9.4.3'></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/OOP/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>Passiv versus aktiv visning</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/OOP/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">9.4.5 <a name='afsn9.4.5'></a>Fuldsk&aelig;rmstegning</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/OOP/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>Dobbeltbuffer</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/OOP/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>

	  
<DIV ID="sdfootnote1">
  <P LANG="da-DK" CLASS="sdfootnote-western"><A CLASS="sdfootnotesym" NAME="sdfootnote1sym" HREF="#sdfootnote1anc">1</A>Det
  er dog muligt at lave en blanding af aktiv og passiv visning. Havde
  tegn() <I>kun</I> optegnet billedet, dvs <I>ikke</I> ogs&aring;
  ventet og opdateret koordinater, kunne vi kalde tegn() fra
  paintComponent().</P>
</DIV>
<DIV ID="sdfootnote2">
  <P LANG="da-DK" CLASS="sdfootnote-western"><A CLASS="sdfootnotesym" NAME="sdfootnote2sym" HREF="#sdfootnote2anc">2</A>Bliver
  grafikken vist i et vindue vil det billede blive kopieret hen til
  det rigtige sted i hukommelsen. I fuldsk&aelig;rmstilstand vil
  grafikkortet i stedet blive dirigeret til at vise det nye
  hukommelsesomr&aring;de (hvis grafikkortet og styresystemet
  underst&oslash;tter det), hvilket er meget hurtigere,</P>
</DIV>

<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 (79% af værket).
</font>
<br>
Ønsker du at se de sidste 21% af dette værk (226970 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>
