14
Tags:
java
Skrevet af
Bruger #4487
@ 27.12.2010
Indledning
Indtil videre har vi kun kigget på tekst baserede applikationer/programmer, men kan man overhovedet ikke lave noget grafisk i Java? Svaret er, selvfølgelig kan man det! Java er et højt udviklet sprog, og kan i dag bruges til stort set alle typer af programmer, lige fra vores tekst baserede eksempler, til kontor programmer, og end dog spil. I denne artikel, skal vi med andre ord til at kigge på hvordan man kan lave nogle grafiske applikationer. Til dette skal vi først kende lidt til en klasse som hedder
Graphics.
Graphics Klassen
Klassen
Graphics er en abstrakt klasse, hvilket simpelthen betyder at man ikke kan lave objekter af klassen, og den kun eksisterer til at assisterer andre klasser med nogle specielle ting, i dette tilfælde nemlig metoder til at tegne grafik af forskellig art. Denne klasse ligger i bibliotekstien -
java.awt.Graphics; - og skal selvfølgelig importeres i starten af vores klasser, ellers kan vi ikke benytte os af dens metoder.
Opgave - I dit
Java Bibliotek, skal du finde klassen Graphics (Husk den ligger i pakken java.awt). Find herefter ud af hvilke metoder denne klasse har til at tegne forskellige ting med. Kan du også regne ud hvad forskellen på draw og fill metoderne er? Når opgaven er løst så læs videre.
I dit Java Bibliotek, kan vi finde metode som
drawOval(),
drawRect(),
drawString(),
fillOval() og
fillRect() (Parametrene er udeladt her for læsevenlighedens skyld). Forskellen på en draw og en fill metode er at draw kun tegner kanten af vores grafik (f.eks. kanten af rektanglet), mens fill metoderne tegner både kanten og indholdet i en farve. Vores
drawString() metode tegner en streng (tekst) som grafik, oftest i et vindue af en slags.
Nu har vi hørt lidt om Graphics klassen, og det er på tide at gå lidt videre, fordi vi skal nemlig have lidt mere teoretisk, før vi kan begynde på vores kode eksempler. Fordi vi skal nemlig høre lidt om
JFrame og
JPanel klasserne.
JFrame og JPanel
JFrame er en klasse til et vindue. Denne klasse ligger i et nyere java bibliotek, som hedder javax.swing. Oftest når man skal bruge disse klasser fra Swing klassen, importerer man bare alle klasserne direkte, da man oftest bruger flere end Jframe og for den sags skyld også JPanel. Som sagt før, så er JFrame en klasse til et vindue, som vi blandt andet kender dem i Windows. Vinduet kan vi så lægge et JPanel ind i. Et JPanel er så en slags kasse, som ligger inde i vores vindue (JFrame), og man kan på en måde kalde den vores container, som vi kan smide indhold ind i (I dette tilfælde grafik). Som en sidste ting før vi går i krig med koden, er at JPanel er en underklasse til klassen JComponent, som har en metode, som vi skal bruge senere der hedder
paintComponent(Graphics g). Med denne metode og lille viden omkring JFrame og JPanel, kan vi nu gå igang med vores eksempel.
Vores første grafiske program
Det første vi skal gøre er at lave en klasse, som kan tegne vores forskellige grafiske komponenter. Jeg har valgt at kalde klassen for Tegn, men du kan selvfølgelig kalde din hvad du ønsker. Vores nye klasse Tegn, skal udvide (extends) fra klassen JPanel. Vi skal derfor selvfølgelig skrive -
extends JPanel - i vores klassedefinition (Husk endelig også at importere Swing klassen fra javax.swing). I vores nye klasse skal vi så lave en metode, som skal præcis denne signatur -
public void paintComponent(Graphics g) - Da den så vil override metoden som eksisterede i klassen JComponent, da JPanel var en underklasse til denne. Da parameteren er med datatypen Graphics, skal vi også huske at importere klassen Graphhics fra pakken java.awt. Vores metodes krop, skal du lade stå tom indtil videre. Når alt dette er udført, skulle din kode gerne se således ud.
- import java.awt.Graphics;
- import javax.swing.*;
- /**
- * Klassen Tegn - Denne klasse vil tegne grafiske komponenter
- * for os, som blandt andet kan blive vist i et JFrame,
- * også kendt som et almindeligt vindue.
- *
- * @author Martin Rohwedder
- * @version 27-12-2010
- */
- public class Tegn extends JPanel {
-
- /**
- * Denne metode overrider metoden fra klassen JComponent,
- * som er tilgængelig fordi vores JPanel arver metoderne
- * fra JComponent.
- */
- public void paintComponent(Graphics g)
- {
-
- }
-
- }
Nu skal vi så putte noget kode ind i vores metode, som hedder
paintComponent(Graphics g). Det første vi skal gøre er at kalde super klassens metode som hedder paintComponent, ligesom vores egen og give den parameteren g. Dette vil tegne baggrunden til vores JPanel (container). Måden vi gjorde for at kalde en super klasses metode, var at bruge nøgleordet
super, også bruge dot notation, til at kalde metoden vi skal bruge.
Herefter kan vi tage vores parameters navn (som jo var, g) og kalde metoder fra vores
Graphics klasse. Vi kunne jo f.eks. prøve at tegne et rektangel, så vi kan kalde metoden fillRect() via dot notation. Hvis du allerede har fundet den i Java biblioteket, kan du se at metoden har fire parametre. De første to er x og y værdier, og angiver positionen på skærmen, og i dette tilfælde i vores container (JPanel). Positionen starter altid fra øverste venstre hjørne af skærmen. De to sidste angiver bredden, og til sidst højden på vores rektangel (i pixels). Vi kunne f.eks. tegne et rektangel på positionen x=10, y=10, bredde=300 og højde=100. Vores kode ser nu således ud.
- import java.awt.Graphics;
- import javax.swing.*;
- /**
- * Klassen Tegn - Denne klasse vil tegne grafiske komponenter
- * for os, som blandt andet kan blive vist i et JFrame,
- * også kendt som et almindeligt vindue.
- *
- * @author Martin Rohwedder
- * @version 27-12-2010
- */
- public class Tegn extends JPanel {
-
- /**
- * Denne metode overrider metoden fra klassen JComponent,
- * som er tilgængelig fordi vores JPanel arver metoderne
- * fra JComponent.
- */
- public void paintComponent(Graphics g)
- {
- //Tegn vores bagrrund på vores container, så vi kan lægge grafik ind på den.
- super.paintComponent(g);
-
- //Tegn et fyldt rektangel - x = 10, y = 10, b = 300, h = 100.
- g.fillRect(10, 10, 300, 100);
- }
-
- }
Nå er vores Tegn klasse færdig, i hvert fald foreløbigt. Den vil nu kunne tegne et rektangel. Vi skal nu til at lave en Main klasse, med en main metode. Main klassen skal importere alle klasserne i javax.swing pakken. Main metoden skal lave et nyt objekt af vores klasse Tegn, og gemme objektet i en lokal variabel. Vores kode ser nu således ud.
- import javax.swing.*;
- /**
- * Main Klassen
- *
- * @author Martin Rohwedder
- * @version 27-12-2010
- */
- public class Main {
-
- /**
- * Main metoden.
- */
- public static void main(String[] args)
- {
- Tegn tegnePanel = new Tegn();
- }
-
- }
Herefter skal vi lave vores Vindue, hvor vi skal lægge vores panel (container) ind i. Husk at containeren, som vi vil benytte, allerede er defineret i vores Tegn klasse, og det er derfor vi har lavet et objekt af denne klasse og gemt objektet i en lokal variabel. Du kan sikkert huske at JFrame var klassen man brugte til at lave et vindue med, så vi skal lave et objekt af klassen JFrame, og gemme denne i en lokal variabel. Vi kan nu via dot notation kalde metoden add(), hvor vi lægger objektet fra klassen Tegn, som vi gemte i en lokal variabel, ind som parameter til denne metode. Når dette er gjort ser vores kode således ud.
- import javax.swing.*;
- /**
- * Main Klassen
- *
- * @author Martin Rohwedder
- * @version 27-12-2010
- */
- public class Main {
-
- /**
- * Main metoden.
- */
- public static void main(String[] args)
- {
- Tegn tegnePanel = new Tegn();
-
- //Parameteren i JFrame, som er en string angiver vinduets titel.
- JFrame vindue = new JFrame("Grafisk Rektangel");
-
- //Læg vores panel/container ind i vores vindue.
- vindue.add(tegnePanel);
- }
-
- }
Nå mangler vi kun tre små men meget vigtige ting. Det første er at sætte en standard funktion for hvad der skal ske, når vi klikker på krydset i vores vindue. Dette gøres ved at kalde metoden setDefaultCloseOperation() i vores JFrame objekt. Parameteren i denne metode, skal være -
(JFrame.DISPOSE_ON_CLOSE); - og DISPOSE_ON_CLOSE skal være med store bogstaver. Det næste vi skal er at sætte vinduets størrelse (bredde og højde). Dette gøres med metoden setSize(), hvor parametrene er bredden og højden. Den sidste er en metode, som hedder setVisible(), som gør at vinduet bliver synligt på din skærm. Parameteren i denne metode, skal være en boolean, og i dette tilfælde true, da det er sandt at vinduet skal være visible (synligt). Vores kode ser nu således ud.
- import javax.swing.*;
- /**
- * Main Klassen
- *
- * @author Martin Rohwedder
- * @version 27-12-2010
- */
- public class Main {
-
- /**
- * Main metoden.
- */
- public static void main(String[] args)
- {
- Tegn tegnePanel = new Tegn();
-
- //Parameteren i JFrame, som er en string angiver vinduets titel.
- JFrame vindue = new JFrame("Grafisk Rektangel");
-
- //Læg vores panel/container ind i vores vindue.
- vindue.add(tegnePanel);
-
- //Sæt lukke funktion, størrelsen på vinduet og at det skal være synligt på skærmen.
- vindue.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- vindue.setSize(340, 160);
- vindue.setVisible(true);
- }
-
- }
Nu kan du så i kommandoprompt kompilerer dine Java filer, og herefter køre din Main klasse. Resultatet skulle gerne være at der popper et vindue op, som ligner billedet nedenunder.

Nu kunne en af de ting du tænker være, hvordan får jeg ændret farven på mit grafiske rektangel? Det er den næste ting vi skal kigge på.
Læg farve på din grafik
For at farvelægge vores grafiske komponenter, skal vi benytte klassen
Color. Denne klasse ligger i pakken java.awt, og vi skal derfor importere den i vores Tegn klasse, for at kunne benytte den. Hvis du finder Color klassen i dit java bibliotek, vil du se at den har mere end en konstruktør. Vi kan vælge konstruktør alt afhængig af hvor meget vi vil gå i detaljen over hvilken farve vi ville have. En anden ting der er værd at ligge mærke til ved Color klassens dokumentation, er at vi her kan se nogle af dens felter. Dette er normalt ikke noget man gør, men med denne klasse har man valgt at gøre det lovligt for folk at tage en farve direkte via at felt, uden at bruge en metode først. Måden man kalder et felt på er akkurat, som hvis vi skulle kalde en metode i color klassen, bortset fra at man ikke laver paranteser efter felter. Lad os f.eks. prøve at give vores rektangel farven rød, ved hjælp af dot notation direkte til et af felterne.
Mini Opgave - I Tegn klassen, skal du før den linje hvor du tegner dit rektangel kalde metoden setColor() fra Graphics klassen. Parameteren i denne metode, skal være dot notation til feltet 'RED' i vores Color klasse, så du skriver som parameter - Color.RED - Husk herefter også at importere Color klassen fra stien java.awt. Din kode skulle nu gerne se således ud.
- import java.awt.Graphics;
- import java.awt.Color;
- import javax.swing.*;
- /**
- * Klassen Tegn - Denne klasse vil tegne grafiske komponenter
- * for os, som blandt andet kan blive vist i et JFrame,
- * også kendt som et almindeligt vindue.
- *
- * @author Martin Rohwedder
- * @version 27-12-2010
- */
- public class Tegn extends JPanel {
-
- /**
- * Denne metode overrider metoden fra klassen JComponent,
- * som er tilgængelig fordi vores JPanel arver metoderne
- * fra JComponent.
- */
- public void paintComponent(Graphics g)
- {
- //Tegn vores bagrrund på vores container, så vi kan lægge grafik ind på den.
- super.paintComponent(g);
-
- //Sæt farven på vores komponenter efterfølgende i koden.
- g.setColor(Color.RED);
-
- //Tegn et fyldt rektangel - x = 10, y = 10, b = 300, h = 100.
- g.fillRect(10, 10, 300, 100);
- }
-
- }
Når du kompilere Tegn klassen, og herefter kører din Main klasse i kommandoprompt, vil du se at din rektangel, pludselig er blevet rød i stedet for sort. Den vil altså se ud ligesom billedet nedenfor.

Lad os prøve at lave noget mere grafik, som har en anden farve. I din tegn klasse skal du nederst i metoden paintComponent, skrive først en ny setColor (Brug en anden farve en rød), og derefter laver du en drawString(), med følgende parametre - ("Her er noget tekst!", 100, 60) - Den første er den tekst, som skal vises som grafik. De to næste er henholdsvis x og y positionen i vores container (JPanel). Din kode ser nu således ud.
- import java.awt.Graphics;
- import java.awt.Color;
- import javax.swing.*;
- /**
- * Klassen Tegn - Denne klasse vil tegne grafiske komponenter
- * for os, som blandt andet kan blive vist i et JFrame,
- * også kendt som et almindeligt vindue.
- *
- * @author Martin Rohwedder
- * @version 27-12-2010
- */
- public class Tegn extends JPanel {
-
- /**
- * Denne metode overrider metoden fra klassen JComponent,
- * som er tilgængelig fordi vores JPanel arver metoderne
- * fra JComponent.
- */
- public void paintComponent(Graphics g)
- {
- //Tegn vores bagrrund på vores container, så vi kan lægge grafik ind på den.
- super.paintComponent(g);
-
- //Sæt farven på vores komponenter efterfølgende i koden.
- g.setColor(Color.RED);
-
- //Tegn et fyldt rektangel - x = 10, y = 10, b = 300, h = 100.
- g.fillRect(10, 10, 300, 100);
-
- //Sæt farven på vores komponenter efterfølgende i koden.
- g.setColor(Color.GREEN);
-
- //Tegn en tekst som grafik - Vores streng, x = 100, y = 60.
- g.drawString("Her er noget tekst!", 100, 60);
- }
-
- }
Og dit output ville så se således ud (farven til teksten her jeg brugt grøn).

Som en sidste ting skal vi prøve at lave vores helt egen farve, i stedet for at bruge en af de standardiserede farver, som er angivet i Color klassens felter. Vi kunne prøve at lave en fyldt oval ( metoden fillOval() ), og give den en selv lavet kongeblå farve (Red: 65 Green: 105 Blue: 225). Måden vi giver den vores egen farve på, er ved i stedet at kalde et felt (Som faktisk i øvrigt var static, hvilket gør at vi faktisk ikke behøvede at lave et objekt af Color klassen), men ved at lave et objekt af Color klassen, ved at bruge en konstruktør, som kan indeholde et int tal til rød, grøn og blå. Vi kan ved at granske vores Color klasses dokumentation se at den har en metode, som skal bruge tre parametre, nemlig en int til henholdsvis r (red), g (green) og b (blue). Så når vi laver et objekt af klassen, giver vi bare vores konstruktør disse tre parametre, og den laver automatisk vores selv valgte farve. Husk at RGB'en for konge blå er r=65, g=105, b=225. Vi kalder så bare navnet på vores lokale variabel, hvor vi gemmer vores selvlavede Color objekt i, når vi skal sætte farven med setColor metoden. Herefter laver vi en fyldt Oval, med parametrene - (x=240, y=35, b=40, h=40) - Og vores kode ser nu således ud.
- import java.awt.Graphics;
- import java.awt.Color;
- import javax.swing.*;
- /**
- * Klassen Tegn - Denne klasse vil tegne grafiske komponenter
- * for os, som blandt andet kan blive vist i et JFrame,
- * også kendt som et almindeligt vindue.
- *
- * @author Martin Rohwedder
- * @version 27-12-2010
- */
- public class Tegn extends JPanel {
-
- /**
- * Denne metode overrider metoden fra klassen JComponent,
- * som er tilgængelig fordi vores JPanel arver metoderne
- * fra JComponent.
- */
- public void paintComponent(Graphics g)
- {
- //Tegn vores bagrrund på vores container, så vi kan lægge grafik ind på den.
- super.paintComponent(g);
-
- //Sæt farven på vores komponenter efterfølgende i koden.
- g.setColor(Color.RED);
-
- //Tegn et fyldt rektangel - x = 10, y = 10, b = 300, h = 100.
- g.fillRect(10, 10, 300, 100);
-
- //Sæt farven på vores komponenter efterfølgende i koden.
- g.setColor(Color.GREEN);
-
- //Tegn en tekst som grafik - Vores streng, x = 100, y = 60.
- g.drawString("Her er noget tekst!", 100, 60);
-
- //Gem vores konge blå (Royal Blue), i en lokal variabel.
- Color royalBlue = new Color(65, 105, 225);
-
- //Sæt farven på vores komponenter efterfølgende i koden.
- g.setColor(royalBlue);
-
- //Tegn en fyldt oval - x = 240, y = 35, b = 40, h = 40.
- g.fillOval(240, 35, 40, 40);
- }
-
- }
Når du kompilere Tegn klassen, og kører din Main fil, skulle du gerne få følgende output.

Lidt mere grafik
For at vise lidt mere grafisk skal vi nu lave en grafisk 'linje', som tegnes op og ned, mens den skifter farve efterhånden som den tegnes. Til dette skal vi benytte to klasser, en til at tegne 'linjen' og lave vinduet som den tegnes i (Før tegnede vi vinduet i main klassen), og en Main klasse, med en main metode, som laver et objekt af vores 'linje' klasse, vi kunne kalde denne for Kurve, eller KurveTegning.
Lad os starte med vores 'KurveTegning' klasse, som skal være en underklasse til JPanel. Importer hele pakken java.awt, og hele javax.swing. Importer også et ArrayList fra java.util pakken. Lav så en konstruktør, og herefter to metoder. Den første skal have signaturen - public void paintComponent(Graphics g) - Og den anden skal være en private mutator metode, som du kan navngive lavVindue(). Indtil nu skal metoderne være tomme. Lav så to felter, et felt til at indeholde et ArrayList med objekter af typen Color, og et felt som er med typen int og hedder forskydning. Da vi ikke vil have at indholdet i feltet skal kunne ændres, benytter vi et nøgleord, som hedder
final, og sætter feltet til en konstant værdi af 50. Ordet Final gør at værdien i feltet er konstant, og derfor ikke kan ændres. Husk at initialisere ArrayListen til at holde et objekt af ArrayList i konstruktøren. Vores kode ser nu således ud.
- import java.awt.*;
- import javax.swing.*;
- import java.util.*;
- /**
- * Klassen KurveTegning - Denne klasse har til formål at
- * tegne en kurve i et vindue. Kurven vil automatisk få en
- * forskellig farve jo mere af kurven der tegnes.
- * Kurven tegnes ved hjælp af små fyldte rektangler,
- * som har en bredde og højde på 5 pixels.
- *
- * @author Martin Rohwedder
- * @version 27-12-2010
- */
- public class KurveTegning extends JPanel {
-
- private ArrayList<Color> farver;
- private final int FORSKYDNING = 50;
-
- public KurveTegning()
- {
- farver = new ArrayList<Color>();
- }
-
- /**
- * Overrider paintComponent overrider metoden fra JComponent,
- * som er nedarvet til JPanel.
- */
- public void paintComponent(Graphics g)
- {
-
- }
-
- /**
- * Lav vores vindue (JFrame).
- */
- private void lavVindue()
- {
-
- }
-
- }
Lad os først lave vores vindue, da vi allerede har set hvordan det skal gøres. Sæt vinduets størrelse til 300 (bredde) og 400 (højde), og husk at lave et internt kald til metoden i konstruktøren. Hvor vi før skrev - vindue.add(tegnePanel) - Skal du istedet for tegnePanel skrive nøgleordet
this, da dette nøgleord refererer til et objekt af den samme klasse, som den er skrevet i (I dette tilfølde refererer this til et objekt af klassen KurveTegning). Vores kode ser nu således ud.
- import java.awt.*;
- import javax.swing.*;
- import java.util.*;
- /**
- * Klassen KurveTegning - Denne klasse har til formål at
- * tegne en kurve i et vindue. Kurven vil automatisk få en
- * forskellig farve jo mere af kurven der tegnes.
- * Kurven tegnes ved hjælp af små fyldte rektangler,
- * som har en bredde og højde på 5 pixels.
- *
- * @author Martin Rohwedder
- * @version 27-12-2010
- */
- public class KurveTegning extends JPanel {
-
- private ArrayList<Color> farver;
- private final int FORSKYDNING = 50;
-
- public KurveTegning()
- {
- farver = new ArrayList<Color>();
- lavVindue();
- }
-
- /**
- * Overrider paintComponent overrider metoden fra JComponent,
- * som er nedarvet til JPanel.
- */
- public void paintComponent(Graphics g)
- {
-
- }
-
- /**
- * Lav vores vindue (JFrame).
- */
- private void lavVindue()
- {
- JFrame vindue = new JFrame("Kurve Tegning");
- vindue.add(this);
- vindue.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- vindue.setSize(400, 300);
- vindue.setVisible(true);
- }
-
- }
Vi kan nu gå igang med at tegne vores grafik. Det første vi skal gøre er at kalde super klassens paintComponent(g), så vi for tegnet baggrundet til panelet. Herefter skal vi bruge en for løkke, som skal have signaturen - for (int i = 0; i < 400; i++) - da vi gerne vil have den til at køre løkken 400 gange. I løkkens krop skal vi lave en lokal variabel med datatypen Color, og lave en ny farve hver eneste gang ved at kalde konstruktøren, som skal bruge tre parametre (RGB). Men før vi skriver lidt om dette, skal vi vide lidt om en operator, som hedder modulo.
Modulo Operatoren
En modulo ser således ud i java (%). Operatoren/tegnet for dette er nemlig et procent tegn, og hvis vi skal forstå en modulo er vi nødt til at tage et par matematiske eksempler, med division. Det skal vi fordi modulo angiver 'resterne' af brøkken, og derfor virker en modulo også kun med hele tal. Du ved sikkert fra din matematik undervisning, at hvis vi har regnestykket 20/5, så er resultatet i hele tal 4, og vi har ingen rest til overs. Men hvad nu hvis stykket istedet for hed 19/5, så ville du sikkert sige at det blev et komma tal, og du derfor måske ikke kunne regne det i hovedet. Dette er også sandt, undtagen, når vi snakker i hele tal, fordi divisionsstykket 19/5 i hele tal giver resultatet 3 og 4 i rest. Hvis vi brugte divisionstegnet (/), ville vi få resultatet af divisionen i hele tal (nemlig 3), men hvis vi derimod skrev stykket således - 19%5 (nitten modulo fem) - Ville Java give resultatet 4, altså ikke resultatet af divisionen, men resultatet af divisionens rest. Hvis vi skulle sammenkæde lidt, kan vi sige at en modulo bruges når vi gerne vil have resten som resultat af en division. Jeg har herunder lavet fem eksempler på resultatet af en division og en modulo.
- Division: 11/5 (resultat: 2) - Modulo: 11%5 (resultat: 1)
- Division: 49/7 (resultat: 7) - Modulo: 49%7 (resultat: 0)
- Division: 43/3 (resultat: 14) - Modulo: 43%3 (resultat: 1)
- Division: 4/20 (resultat: 0) - Modulo: 4%20 (resultat: 20)
- Division: 33/34 (resultat: 0) - Modulo: 33%34 (resultat: 34)
Når vi nu ved dette med modulo operatoren, kan vi gå tilbage til vores KurveTegning. Vi skulle jo i vores Color konstruktør angive tre parametre (RGB), og vi skal altså skrive -
Color farve = new Color(i%256, (i*2)%256, (i*4)%256); - Herefter kalder vi vores add metode fra ArrayListen, og tilføjer Color objektet som er gemt i vores lokale variabel. Vores kode ser nu således ud.
- import java.awt.*;
- import javax.swing.*;
- import java.util.*;
- /**
- * Klassen KurveTegning - Denne klasse har til formål at
- * tegne en kurve i et vindue. Kurven vil automatisk få en
- * forskellig farve jo mere af kurven der tegnes.
- * Kurven tegnes ved hjælp af små fyldte rektangler,
- * som har en bredde og højde på 5 pixels.
- *
- * @author Martin Rohwedder
- * @version 27-12-2010
- */
- public class KurveTegning extends JPanel {
-
- private ArrayList<Color> farver;
- private final int FORSKYDNING = 50;
-
- public KurveTegning()
- {
- farver = new ArrayList<Color>();
- lavVindue();
- }
-
- /**
- * Overrider paintComponent overrider metoden fra JComponent,
- * som er nedarvet til JPanel.
- */
- public void paintComponent(Graphics g)
- {
- super.paintComponent(g);
-
- for (int i = 0; i < 400; i++)
- {
- Color farve = new Color(i%256, (i*2)%256, (i*4)%256);
- farver.add(farve);
- }
- }
-
- /**
- * Lav vores vindue (JFrame).
- */
- private void lavVindue()
- {
- JFrame vindue = new JFrame("Kurve Tegning");
- vindue.add(this);
- vindue.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- vindue.setSize(400, 300);
- vindue.setVisible(true);
- }
-
- }
Løkken har nu lavet 400 farver, og gemt dem i vores ArrayList. Vi kan nu begynde at lave koden, som tegner vores kurve. Vi skal til dette benytte endnu en for løkken, med følgende signatur - for (int x = 0; x < 400; x++) - løkkens krop skal vi have tre lokale variabler. En for y positionen, og en for vores indeks, hvor vi skal hente vores farve i ArrayListen, og en til at gemme den farve vi henter fra vores ArrayList. Vi vil gerne have vores kurve til at ligne en slags sinusrytme, og for at gøre dette skal vi bruge en metode, som hedder sin(), som er at finde i klassen Math. Heldigvis behøver du ikke importerer klassen Math da denne klasse allerede er importeret fra lang pakken (Det er også i denne pakke at String er inkluderet). Da jeg ikke vil gå i detaljer med Sinusrelationerne her, så vil jeg bare skrive indholdet her, som skal puttes ind i den lokale variabel, for y positionen (husk at datatypen for den lokale variabel skal være en int). Vi skriver altså for y positionen -
int y = 140 - (int) (130*Math.sin(0.05*x)); - Grunden til at vi skriver int i en parentes midt i det hele, er at Math.sin() metoden returnerer ikke en int, men en double, og vi vil gerne have at det skulle være en int. Derfor laver vi noget som hedder en casting, ved at skrive int i parentesen. Man kan ikke bare caste som man ønsker, men man kan godt caste fra en double, til en int. Man kan dog ikke caste fra en int til en double.
Nu er vores lokale variabel med y positionen klar, og vi kan nu gå videre med vores variabel for indekset og farven som vi henter. I variablen til indekset, skal vi lægge dette indhold ind i - (x+FORSKYDNING)%400; - og for variablen til at hente farven, skal vi kalde ArrayListens get() metode, og give den vores lokale variabel indeks, som parameter. Vores kode ser nu således ud.
- import java.awt.*;
- import javax.swing.*;
- import java.util.*;
- /**
- * Klassen KurveTegning - Denne klasse har til formål at
- * tegne en kurve i et vindue. Kurven vil automatisk få en
- * forskellig farve jo mere af kurven der tegnes.
- * Kurven tegnes ved hjælp af små fyldte rektangler,
- * som har en bredde og højde på 5 pixels.
- *
- * @author Martin Rohwedder
- * @version 27-12-2010
- */
- public class KurveTegning extends JPanel {
-
- private ArrayList<Color> farver;
- private final int FORSKYDNING = 50;
-
- public KurveTegning()
- {
- farver = new ArrayList<Color>();
- lavVindue();
- }
-
- /**
- * Overrider paintComponent overrider metoden fra JComponent,
- * som er nedarvet til JPanel.
- */
- public void paintComponent(Graphics g)
- {
- super.paintComponent(g);
-
- for (int i = 0; i < 400; i++)
- {
- Color farve = new Color(i%256, (i*2)%256, (i*4)%256);
- farver.add(farve);
- }
-
- for (int x = 0; x < 400; x++)
- {
- int y = 140 - (int) (130*Math.sin(0.05*x));
- int indeks = (x+FORSKYDNING)%400;
- Color farve = farver.get(indeks);
- }
- }
-
- /**
- * Lav vores vindue (JFrame).
- */
- private void lavVindue()
- {
- JFrame vindue = new JFrame("Kurve Tegning");
- vindue.add(this);
- vindue.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- vindue.setSize(400, 300);
- vindue.setVisible(true);
- }
-
- }
Nu har vi vores farve, og vores y position (x positionen er angivet via løkkens betingelse), og vi kan nu i løkken sætte grafikkens farve, med setColor() metoden, og herefter tegne en fyldt rektangel (fillRect()), med parametrene (x, y, 5, 5). Vores kode ser nu således ud.
- import java.awt.*;
- import javax.swing.*;
- import java.util.*;
- /**
- * Klassen KurveTegning - Denne klasse har til formål at
- * tegne en kurve i et vindue. Kurven vil automatisk få en
- * forskellig farve jo mere af kurven der tegnes.
- * Kurven tegnes ved hjælp af små fyldte rektangler,
- * som har en bredde og højde på 5 pixels.
- *
- * @author Martin Rohwedder
- * @version 27-12-2010
- */
- public class KurveTegning extends JPanel {
-
- private ArrayList<Color> farver;
- private final int FORSKYDNING = 50;
-
- public KurveTegning()
- {
- farver = new ArrayList<Color>();
- lavVindue();
- }
-
- /**
- * Overrider paintComponent overrider metoden fra JComponent,
- * som er nedarvet til JPanel.
- */
- public void paintComponent(Graphics g)
- {
- super.paintComponent(g);
-
- for (int i = 0; i < 400; i++)
- {
- Color farve = new Color(i%256, (i*2)%256, (i*4)%256);
- farver.add(farve);
- }
-
- for (int x = 0; x < 400; x++)
- {
- int y = 140 - (int) (130*Math.sin(0.05*x));
- int indeks = (x+FORSKYDNING)%400;
- Color farve = farver.get(indeks);
-
- g.setColor(farve);
- g.fillRect(x, y, 5, 5);
- }
- }
-
- /**
- * Lav vores vindue (JFrame).
- */
- private void lavVindue()
- {
- JFrame vindue = new JFrame("Kurve Tegning");
- vindue.add(this);
- vindue.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- vindue.setSize(400, 300);
- vindue.setVisible(true);
- }
-
- }
Nu er KurveTegning klassen færdig, og vi kan nu lave vores Main klasse. Vi skal som det eneste i Main klassens Main metode, lave et objekt af klassen KurveTegning. Vores Main klasse ser således ud.
- /**
- * Main klassen
- *
- * @author Martin Rohwedder
- * @version 27-12-2010
- */
- public class Main {
-
- /**
- * Main metoden.
- */
- public static void main(String[] args)
- {
- KurveTegning kurve = new KurveTegning();
- }
-
- }
Kompiler nu og kør din Main fil, og resultatet skulle gerne se således ud.

Nu har vi kigget lidt på grafik, og hvordan vi laver vinduer. Vi har også lært lidt om Modulo operatoren, og hvordan vi farvelægger vores grafik. Vi ved nu også at nøgleordet final, kan gøre noget konstant. Følg med i næste artikel, hvor vi skal lære meget mere om Java programmering.
Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.
Del også gerne artiklen med dine Facebook venner:
Kommentarer (3)
Hej er rimelig ny indenfor Java og har fuldt alle de tidligere dele. Jeg har Arbejdet meget med Photoshop de sidste par år, og tænkte så om man ikke kan lave et design i photoshop og importere det til sit java program?
- Jeg har set i en af de andre tut at man skal lave en lommeregner, kan man så ikke lave knapperne i Photoshop så det ikke er de "kedelige" standart knapper?
Du kan sagtens lave 'billed' knapper i Java, og på den måde 'style' dit GUI. Du også lægge baggrund på dit JFrame, eller JPanel, så du kan i princippet sagtens overføre dit photoshop layout til et GUI i java. En måde du f.eks. kan udskifte 'layout' på dine JButtons, er ved at benytte ImageIcon klassen som er med i pakken javax.swing. Her er et eksempel.
- // HUSK at importere fra javax.swing pakken
-
- //Opret dit ImageIcon objekt. Dette objekt vil indeholde dit billede, som skal bruges på din knap.
- ImageIcon img = new ImageIcon("Stien/til/dit/billede.png");
-
- //Opret nu din knap, og giv dit billede som parameter til konstruktøren.
- JButton btn = new JButton( img );
-
- //Ændrer nu din knap til at være usynlig samt have en 'usynlig' border (kant)
- btn.setOpaque( true );
- btn.setBorder( BorderFactory.createEmptyBorder() );
Følgende vil oprette en knap, med dit billede på. Herefter vil den gøre standard Look and Feel for knappen usynlig (undtagen billedet og kanten), og vi er derfor nødt til at give knappen en ny kant, som er en usynlig kant. Vupti, dit billede er ny en JButton

Håber at dette besvarede dit spørgsmål.
Hader ikke at kunne redigere i mine kommentarer, nå men lige meget

Faktisk ville det være mere smart at lave en ny klasse kaldet f.eks. ImageJButton som arver fra JButton. På den måde får du alt funktionaliteten fra en JButton, og du kan i ImageJButton klassen konstruktør lave de ændringer der gør den normale knap usynlig og påfører dit billede. Et eksempel kunne være
ImageJButton.java
- import javax.swing.JButton;
- import javax.swing.BorderFactory;
- import javax.swing.ImageIcon;
-
- /**
- * This class creates an JButton which is only a custom made image.
- *
- * @author Martin Rohwedder
- * @version 1.0
- */
- public class ImageJButton extends JButton {
-
- //Constructor
- public ImageJButton( String imagePath ) {
- super( new ImageIcon( imagePath ) ); //kald til JButtons konstruktør.
- this.setOpaque( true );
- this.setBorder( BorderFactory.createEmptyBorder() );
- }
-
- }
Du kan nu benytte klassen i stedet for Jbutton, når du skal lave dine billedfiler, dette gør du bare ved at oprette objekter af denne klasse i stedet for af JButton klassen.
- //Opret en ny knap med mit billede på.
- ImageJButton btn = new ImageJButton( "Stien/til/dit/billede.png" );
Du skal være
logget ind for at skrive en kommentar.