Exkurs: Geschwindigkeit von java
In der Kürze der Zeit lässt sich natürlich nicht die ganze Sprache Java erschöpfend behandeln. Das Ziel des Kurses ist vielmehr, die grundlegenden Konzepte verstanden zu haben und einfache Anwendungsprogramme schreiben zu können.
Ein Javaprogramm wird mit dem Befehl
javac Klassenname.java
in eine Form übersetzt, die später von verschiedenen Programmen auf verschiedenen Rechnern ausgefuehrt werden kann.
Einfache Programme ohne Graphik können mit dem Befehl
java Klassenname
ausgeführt werden.
Programme mit Graphik (sogenannte Applets) können mit Programmen wie appletviewer oder netscape ausgeführt werden (darauf wird später noch mal eingegangen).
Übung 1:
Speichern Sie das folgende einfache HelloWorld-Programm unter dem Namen HelloWorld.java ab, compilieren Sie es und führen Sie es aus.
class HelloWorld { public static void main (String args[]) { System.out.println("Hello World!"); } }Download HelloWorld.java
javac HelloWorld.java
java HelloWorld
java -classpath `echo $CLASSPATH | sed 's/\:\.//g' | sed 's/\.\://g'` HelloWorldautomatisieren)
Welche Fehlermeldung tritt auf ?
Java ist der Sprache C sehr ähnlich, hat aber eine leicht veränderte Syntax.
Die wichtigsten Unterschiede:
Sinn und Zweck des Schutzmechanismus Datenkapselung ist es, verschiedenen
Programmteilen eine gemeinsame Daten- und Methoden(d.h. Funktionen)-basis
zu geben, aber trotzdem zu verhindern, dass ein fremdes Anwendungsprogramm
die Daten durch direkten Zugriff inkonsistent macht.
Die Sprache Java fordert, dass jede Datendeklaration und jede Funktion
innerhalb einer solchen Datenkaspel (Klasse) definiert sein muss.
In Java kann man sich eine Klasse ("class") als einen zusammengesetzten
Datentyp ("struct" in C) vorstellen, der zusätzlich noch Methoden (sprich
Funktionen) enthält.
Eine spezielle Methode ist der sogenannte Constructor. Er wird dazu
benutzt, um am Anfang die internen Daten zu initialisieren.
Dazu entsprechend gibt es auch einen Destructor, der aufgerufen wird,
wenn die Klasse gelöst wird.
Das Wort "Vererbung" ist eigentlich ein bisschen unglücklich gewählt.
In der Informatik ist weniger der finanzielle Aspekt des Erbens gemeint,
sondern man sollte das Wort "vererben" besser im Zusammenhang
"Familienähnlichkeit" oder "tritt in die Fußstapfen von" verstehen.
Polymorphie heißt griechisch "Vielgestaltigkeit", und beschreibt in java
erstens die Tatsache, daß 2 Funktionen den gleichen Namen haben können
wenn Sie verschiedene Aufrufargumente haben.
Kopieren Sie das folgende Codestück in ein File namens daten.java
und übersetzen Sie es NICHT.
Kopieren Sie das folgende Programm (ohne Vererbung) in ein File
haupt1.java und übersetzen Sie es.
Kopieren Sie das folgende Programm (mit Vererbung) in ein File
haupt2.java und übersetzen Sie es.
Beachten Sie, dass bei der Übersetzung von haupt1.java oder
haupt2.java auch daten.class entstanden ist.
Versuchen Sie zu verstehen, was das Programm macht.
Testen Sie, was beim Compilieren passiert, wenn sie die Kommentare (//)
vor den "illegalen" Befehlen weglassen.
Im oberen Beispiel mußten die Daten als "static" deklariert werden,
weil eine java-Sonderregel die Vererbung sonst verhindert hätte.
Vor allem das Fehlen der Pointer hat im Vergleich mit C natürlich
größere Auswirkungen auf wichtige Sprachbestandteile:
int myarray[] = new int[arraylaenge];
Eine expliziete Rückgabe von Speicher ist in java weder möglich noch
nötig. Speicher wird automatisch zurückgegeben, wenn der Compiler
merkt, daß keine Referenz auf die angeforderte Speicherstelle mehr im
Programm vorhanden ist (z.B. im oberen Beispiel, wenn "myarray" der
Universalwert "null" zugewiesen wird).
In der Sprache C werden Arrays häufig als pointer üebergeben.
In Java geschrieben, sieht das gleiche Programm so aus:
In C macht beim Unterprogrammaufruf immer Call by Value, d.h. die
Argumente, die an ein Unterprogramm üebergeben werden, können nur
gelesen, aber nicht zurück in den aufrufenden Programmteil geschrieben
werden. Will man die Argumente in das aufrufende Programmteil
zurückschreiben, muß man in C einen Pointer als Wert übergeben
und entsprechend behandeln.
Um das Problem zu zeigen, hier ein fehlerhaftes Java Programm, das
versucht, die übergebenen Funktionsargumente zurückzuschreiben.
Die von den Javaentwicklern vorgeschlagene Lösung für solche Probleme
sieht so aus, daß für mehrere Parameter die von einer Funktion
geschrieben wird, eine neue Klasse benutzt wird.
// Mehrere Argumente einer Funktion, die wieder zurueckgeschrieben werden
// muessen, werden in java am besten in eine gemeinsame Klasse geschrieben
Die wichtigsten Unterschiede zwischen Java und C bei den grundlegenden
Datentypen sind.
Versuchen Sie, das folgende falsche Programm zu compilieren und
korrigieren Sie dann den Fehler.
Da in Java alles objektorientiert ist, sind auch die Systemlibraries
(Packages) objektorientiert. Damit eine solches Package genutzt werden
kann, muß sie erst mit dem Schlüsselwort "import" importiert werden.
Bei der Benutzung einer Funktion muß nicht nur deren Name (z.B. println)
sonder auch deren Objekt(e) mitangegeben werden (z.B. System.out.println),
in denen die Funktion enthalten ist.
Ein Übersicht über sämptliche Packages finden Sie in
Die wichigsten Packete sind in java.lang enthalten (z.B. java.lang.Math)
oder beschäftigen sich mit Java-Applets, graphische Anwendungen.
Im nächsten Kapitel über Java-Applets sind Beispiele enthalten.
Die derzeit wichtigste Anwendung von Java sind graphisch (bzw. musikalisch)
aufwendige Programme, die über das World-Wide-Web verbreitet werden
können.
Java-Applets funktionieren wie viele andere GUI-(Graphical User Interface)
Packete (z.B. Motif) nach dem "Callback"-Prinzip. Dabei wird im
Programm dauernd eine sogenannte "Eventloop" abgearbeitet, bei der
auf auftretende Ereignisse ("Events" z.B. Mausklick auf ein bestimmtes
Feld oder Fensterneuzeichnen notwendig) reagiert wird. Der Programmierer
muß nur festlegen, welche was beim Auftreten dieses Events
ausgeführt werden muss.
In Java wird die Funktion, die festlegt, was beim Auftreten des Events
passiert, von der Klasse "Applet" geerbt und über Polymorphie
überschrieben. Dadurch gestaltet sich die Programmierung besonders
einfach.
Ein einfaches "HelloWorld"-Beispiel, das als Callback für das
Neuzeichnen des Fensters implementiert ist, sieht als Applet so aus:
Dieses Programm zählt ausserdem noch die Variable "redrawcounter"
pro Fensterneuzeichnen hoch und gibt sie aus.
Kopieren Sie die folgenden Zeilen in ein File "HelloWorldApplet.java"
und compilieren Sie es mit
Um das graphische Applet auszuführen, müssen Sie zuerst ein html-File
basteln. In diesem File wird über die <Applet> -Anweisung das
Javaprogramm eingebunden. Kopieren Sie das folgende html-File
als "HelloWorldApplet.html".
Das Javaprogramm kann nun mit
oder
gestartet werden.
Testen Sie, wann ein Neuzeichnen des Fensters nötig wird, indem
Sie das netscape/appletviewer iconisieren und wieder aufklappen,
ein anderes (kleines) Fenster darüberschieben und wieder wegziehen
usw.
Ein häufiges Dilemma bei GUI-Programmen ist die Tatsache, daß
beim Abarbeiten der Eventloop keine eigenen Programmteile ausgeführt
werden können und beim Aufruf der Callback -Funktionen die
Eventloop gestoppt ist, so daß die graphische Oberfläche
"einzufrieren" scheint, weil vom Benutzer veranlasste Events nicht
mehr bedient werden können.
Als Beispiel wird dazu das "Hello World" Applet um einen "sleep"-Aufruf
(und das nach Standart nötige
Java besitzt deshalb ein Sprachkonzept, um mehrere Programmstränge
gleichzeitig ablaufen zu lassen.
Um die Ausfuehrung von threads zu ermöglichen, muss der
Spezifikation der Appletklasse der Zusatz "implements runnable"
und eine "run()"-Funktion sowie eine "start()" und "stop()"-Funktion
für den Appletviewer hinzugefügt werden.
Kopieren Sie das folgende Javaapplet und compilieren und starten Sie es.
Klicken Sie bei der Ausführung mit der Maus in das Fenster
und beobachten Sie die Reaktion.
Download aimBeispiel.java
Compilieren Sie das Programm mit
Da das Programm fü die Javaversion 1.0 geschrieben wurde (derzeit
ist Version 1.2 aktuell), kann es nötig sein, dass Sie gegebenenfalls
mit
compilieren müssen.
Nachdem Sie das Programm ausprobiert haben,
entfernen Sie aus dem Programm alles was man für Threads braucht.
Wiederholen Sie das Experiment mit der Maus.
Schieben Sie auch mal ein anderes Fenster über das Applet und
ziehen Sie es wieder weg.
Kopieren Sie sich das urspüngliche Javaapplet erneut.
Benutzen Sie es als Basis für eine Programmieraufgabe, bei der
Sie ein Java-Applet programmieren, bei dem zumindest die Javafunktion
"drawOval" benutzt werden muss.
Eine Beschreibung der Funktion "drawOval" findet sich in der
Beschreibung der "Applet API Packages"
Tip: Schauen Sie sich mal den Aufruf von "drawString" im Programm etwas
genauer an...
Eine kurze Beschreibung weiterer Events findet sich in:
Um ein Testat für diesen Teil des AIM-Praktikums zu bekommen, schicken
Sie bitte Ihr Programm per mail an
scheurich@csv.ica.uni-stuttgart.de
und vergessen Sie nicht, ihren Namen mit anzugeben.
Der Zugriff auf Daten und Methoden kann so beschränkt werden, daß
nur Methoden, die in der selben Klasse enthalten sind, zugreifen
dürfen ("private"), während es natürlich auch öffentliche Funktionen
geben muß, die von allen Klassen aus aufgerufen werden können ("public").
Bei der ojektorientierten Programmierung spricht man von Vererbung,
wenn eine neue Klasse Bestandteil einer bestehenden alten Klasse wird.
Dabei werden Methoden der alten Klasse für die neue Klasse zugänglich,
oder Methoden der alten Klasse können sogar überschieben werden.
Vererbung wird sinnvoll eingesetzt, um die Beziehung "IST EIN"
nachbilden zu können (z.B. ein Mercedes IST EIN Auto), während
die "HAT EIN"-Beziehung (z.B. ein Auto HAT EIN Rad) besser mit der
normalen Benutzung einer Klasse programmiert wird.
Vererbung wird uns später noch einmal bei den graphischen java-Programmen
(applets) begegnen.
Als Polymorphie wird es außerdem bezeichnet, wenn eine
Funktion einer vererbten Klasse durch eine entsprechende Funktion
der neuen Klasse überschrieben wird. Später wird man sehen, dass Applets
nach diesem Prinzip funktionieren.
Übung 2:
class daten
{
// Auf private Mitglieder der Klasse kann nur von innerhalb der Klasse
// zugegriffen werden
static private String private_variable;
static private void private_funktion()
{
System.out.println("vor private_funktion: private_variable"
+"=<"+private_variable+">");
private_variable+=" [private funktion war hier] ";
System.out.println("nach private_funktion: private_variable"
+"=<"+private_variable+">");
}
// Auf oeffentliche Mitglieder der Klasse kann von ueberall zugegriffen werden
static public String oeffentliche_variable;
static public void oeffentliche_funktion()
{
System.out.println("vor oeffentliche funktion: oeffentliche_variable"
+"=<"+oeffentliche_variable+">");
System.out.println("vor oeffentliche_funktion: private_variable"
+"=<"+private_variable+">");
private_funktion();
private_variable+=" [oeffentliche funktion war hier] ";
oeffentliche_variable+=" [oeffentliche funktion war hier] ";
System.out.println("nach oeffentliche_funktion: private_variable"
+"=<"+private_variable+">");
System.out.println("nach oeffentliche funktion: oeffentliche_variable"
+"=<"+oeffentliche_variable+">");
}
// Konstruktoren
daten()
{
private_variable="[default privat] ";
oeffentliche_variable="[default oeffentlich] ";
}
daten(String priv,String pub)
{
private_variable=priv+" ";
oeffentliche_variable=pub+" ";
}
}
Download daten.java
class haupt1
{
public static void main (String args[])
{
daten meinedaten; // normale Benutzung der Klasse "daten"
meinedaten=new daten("[privat]","[offentlich]"); // Kontruktor
// meinedaten.private_variable+="[illegaler Zugriff]" ; // illegal
// meinedaten.private_funktion(); // illegal
meinedaten.oeffentliche_variable+="[legaler Zugriff]"; // legal
meinedaten.oeffentliche_funktion(); // legal
}
}
Download haupt1.java
public class haupt2 extends daten // Vererbung der Klasse "daten"
{
static public void main (String args[])
{
// private_variable+="[legaler oder illegaler Zugriff ?]"; // illegal ?
// private_funktion(); // illegal ?
oeffentliche_variable+="[legaler Zugriff]"; // legal
oeffentliche_funktion(); // legal
}
}
Download haupt2.java
Probieren Sie mal aus, warum sie das Javabytecode-Programm daten.class
nicht mit
java daten
ausführen können.
In java wird Speicher über die "new"-Konstruktion angefordert
definierte_klasse myclass = new definierte_klasse(argumente_konstruktor);
Da es in Java keine Pointer gibt, kann immer sicher festgestellt werden,
ob noch eine Referenz auf eine Speicherstelle existiert.
#include <stdio.h>
void myarraytest(int *myarrayptr)
{
int i;
for (i=0;i<5;i++)
printf("%d\n",myarrayptr[i]);
}
void main(int argc,char** argv)
{
int myarray[5];
int i;
for (i=0;i<5;i++)
myarray[i]=i;
myarraytest(myarray);
}
class arraytest
{
static void myarraytest(int myarrayref[])
{
int i;
for (i=0;i<5;i++)
System.out.println(myarrayref[i]);
}
public static void main (String args[])
{
int myarray[]= new int[5];
int i;
for (i=0;i<5;i++)
myarray[i]=i;
myarraytest(myarray);
}
}
Java macht genauso "Call by Value" aber es gibt keine Pointer.
Deshalb bleibt bei diesem Problem nur die Rückgabe der Werte
mit einer neuem Klasse als Funktionsergebnis.
class swaptestfalsch
{
// In java geht folgender Versuch 2 Zahlen zu tauschen schief,
// weil java keinen call by reference macht
static void swap(int a,int b)
{
int temp;
temp=b;
b=a;
a=temp;
System.out.println(a+" "+b);
}
public static void main (String args[]) {
int a,b;
a=5;
b=8;
System.out.println(a+" "+b);
swap(a,b);
System.out.println(a+" "+b);
}
}
Download swaptestfalsch.java
class swapclass
{
int a;
int b;
swapclass(int inita,int initb)
{
a=inita;
b=initb;
}
void swap()
{
int temp;
temp=b;
b=a;
a=temp;
System.out.println(a+" "+b);
}
}
class swaptestrichtig
{
public static void main (String args[])
{
swapclass swapper=new swapclass(5,8);
System.out.println(swapper.a+" "+swapper.b);
swapper.swap();
System.out.println(swapper.a+" "+swapper.b);
}
}
Download swaptestrichtig.java
Im Gegensatz zu C ist ein string in Java kein Array von einzelnen
Zeichen. Ein Zugriff auf einzelne Zeichen erfolgt über Funktionen.
Strings lassen sich mit anderen Datentypen über den "+" -Operator
verketten.
Eine Liste der Stringfunktionen findet sich unter
Im Gegensatz zu C, wo der Integer-Datentyp für logische Vergleiche
benutzt wird, hat Java einen Datentyp "boolean". Damit ist der
Compiler in der Lage, typische C-Fehler durch Verwechseln von
"=" und "==" zu erkennen.
Übung 3:
class booleanfalsch
{
public static void main (String args[])
{
int i;
i=4;
if (i=4)
System.out.println("booleantest "+i);
}
}
Download booleanfalsch.java
Applets: Graphische Java Anwendungen
Übung 4:
import java.applet.Applet;
import java.awt.Graphics;
// HelloWorldApplet erbt die Funktion paint, die fuer das Neuzeichnen
// des Fensters verantwortlich ist
public class HelloWorldApplet extends Applet
{
int redrawcounter=0;
public void paint(Graphics g)
{
g.drawString("Hello world! redraw # "+ ++redrawcounter, 50, 25);
}
}
Download HelloWorldApplet.java
javac HelloWorldApplet.java
<html>
<head>
<title>Hello World</title>
</head>
<BODY>
<applet code="HelloWorldApplet.class" width=300 height=300>
</applet>
</html>
Download HelloWorldApplet.html
appletviewer HelloWorldApplet.html
netscape HelloWorldApplet.html
Exceptionshandling) ergänzt.
import java.applet.Applet;
import java.awt.Graphics;
import java.lang.*;
// HelloSleepApplet erbt die Funktion paint, die fuer das Neuzeichnen
// des Fensters verantwortlich ist
public class HelloSleepApplet extends Applet
{
int redrawcounter=0;
public void paint(Graphics g)
{
try { Thread.currentThread().sleep(5000); } // 5 Sekunden warten
catch (InterruptedException e) {}
g.drawString("Hello world! redraw # "+ ++redrawcounter, 50, 25);
}
}
Download HelloSleepApplet.java
Download HelloSleepApplet.html
Übung 5:
/*
Ein kleineres Beispiel in der Sprache Java
Das folgende stellt ein sogenanntes Applet dar, ein Programm, das
ueber das world wide web (www) verteilt werden kann und mit
html-Browsern wie z.B. netscape oder appletviewer geladen/gestartet
werden kann.
Applets funktionieren wie andere GUI-programmiertools mit der sogenannten
Callback-methode.
Das heisst, dass fuer ein bestimmtes Ereignis (Event z.B. Tastatur,
Fensterneuzeichnen noetig, Mausklick usw.) eine damit verbundene Funktion
aufgerufen wird. Die Verbindung mit diesen Funktionen funktioniert
bei Java-Applets ueber Vererbung.
Ausserdem benutzt dieses Applet die Java Multitasking-Features, damit
die Callbacks nicht das Abarbeiten von Events (Eventloop) behindert.
Das Programm rechnet in der Initialisierung Daten aus,
die dann spaeter fuer das Zeichnen auf eine Flaeche benutzt werden
Ausserdem benutzt sie noch ein paar andere interessante Zeichenfunktionen
*/
// Import von fertigen Java-Klassen/Unterprogrammen
// Grundlegende Appletklasse fuer die Eventloop
import java.applet.Applet;
// Alle Klassen des "applet window toolkit"
import java.awt.*;
// Mathematische Funktionen
import java.lang.Math;
// Die eigene Klasse erbt mit der Applet-Klasse die Funktion
// "paint", der Callback fuer das Neuzeichnen des Fensters
// (ausserdem noch "init" und "start" fuer einen Neustart des Programms)
// Die Klasse "runnable" stellt die Funktion "run" fuer Threads zur Verfuegung
// die unabhaengig von der Applet-eventloop benutzt wird
public class aimBeispiel extends Applet implements Runnable
{
// eigene Daten
// Daten fuer ein gif-bild
Image gifpicture;
// Fenstergroesse
int AppletWidth, AppletHeight;
// eigene Daten fuer das Zeichnen auf die Flaeche
int NUM_POINTS = 100;
int xPoints[][] = new int[NUM_POINTS][2];
int yPoints[][] = new int[NUM_POINTS][2];
int xPolygon[] = new int[4];
int yPolygon[] = new int[4];
int NUM_ARCS=60;
int arc=0;
// Farben fuer das Zeichnen auf die Flaeche
Color mycolors[] = new Color[NUM_POINTS];
// Daten fuer die Position des letzten Mausklicks
int mousex=-1;
int mousey=-1;
// Datentyp fuer das Starten/Stoppen eines zweiten Programmtasks
Thread mytask=null;
// Initialierung
public void init()
{
double Width1,Height1;
double Width2,Height2;
double ElipseWidth,ElipseHeight;
int i;
double degree;
float x,y;
// Daten fuers gifbild einlesen
gifpicture=null;
// getImage ist asynchron, Bild ist erst da vorhanden, wenn gifpicture!=null
gifpicture = getImage(getDocumentBase(),"maschine.gif");
// Fenstergroesse und Ellipsengroesse festlegen
AppletWidth = size().width;
if (AppletWidth>300)
ElipseWidth=300;
else
ElipseWidth=AppletWidth;
AppletHeight = size().height;
if (AppletHeight>=100)
ElipseHeight=100;
else
ElipseHeight=AppletHeight;
// Daten fuer das Zeichnen in "paint" aufbereiten
// auessere Ellipse
Width1=ElipseWidth-30;
Height1=ElipseHeight-30;
// innere Ellipse
Width2=ElipseWidth-40;
Height2=ElipseHeight-40;
// Punkte fuer Elipsen innerhalb x=-Width1|2...Width1|2 y=-Height1|2...Height1|2
for (i=0;i<NUM_POINTS;i++)
{
// auessere Ellipse
xPoints[i][0] = (int)((Math.sin((i*2*Math.PI)/NUM_POINTS))*Width1/2.0);
yPoints[i][0] = (int)((Math.cos((i*2*Math.PI)/NUM_POINTS))*Height1/2.0);
// innere Ellipse
xPoints[i][1] = (int)((Math.sin((i*2*Math.PI)/NUM_POINTS))*Width2/2.0);
yPoints[i][1] = (int)((Math.cos((i*2*Math.PI)/NUM_POINTS))*Height2/2.0);
}
// Ellipsen kippen
for (i=0;i<NUM_POINTS;i++)
{
degree=7.0/360.0*2*Math.PI;
x=xPoints[i][0];
y=yPoints[i][0];
xPoints[i][0] = (int)( x*Math.cos(degree)+y*Math.sin(degree));
yPoints[i][0] = (int)(-x*Math.sin(degree)+y*Math.cos(degree));
x=xPoints[i][1];
y=yPoints[i][1];
xPoints[i][1] = (int)( x*Math.cos(degree)+y*Math.sin(degree));
yPoints[i][1] = (int)(-x*Math.sin(degree)+y*Math.cos(degree));
}
// Ellipsen in das Fenster verschieben
for (i=0;i<NUM_POINTS;i++)
{
xPoints[i][0] = (int)(xPoints[i][0]+ElipseWidth/2.0);
yPoints[i][0] = (int)(yPoints[i][0]+ElipseHeight/2.0);
xPoints[i][1] = (int)(xPoints[i][1]+ElipseWidth/2.0);
yPoints[i][1] = (int)(yPoints[i][1]+ElipseHeight/2.0);
}
// Farben definieren
for (i=0;i<NUM_POINTS;i++)
{
// RGB-Werte
mycolors[i]=new Color(255,255,(int)((i*255.0)/(2.0*NUM_POINTS)));
// Ausgabe der Punkte auf stdout (funktioniert nicht mit netscape)
// System.out.println("start "+i+" "+xPoints[i][0]+" "+yPoints[i][0]
// +" "+xPoints[i][1]+" "+yPoints[i][1]);
}
}
// Start des Applets
public void start()
{
// Neuen Task starten
mytask = new Thread(this);
mytask.start();
// Fenster neu malen
repaint();
}
// Stop des Applets
public void stop()
{
// diese Zuweisung führt dazu, daß der java-Garbagecollector
// den bei start() angeforderten Thread automatisch entsorgt
mytask = null;
}
// Starten der Anwendung
public void run ()
{
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
// immer wieder Flaeche neuzeichnen, dann warten
while (true)
{
repaint();
try
{
Thread.currentThread().sleep(100);
}
catch (Exception e)
{
System.out.println("da war was !");
}
}
}
// Callback fuer Flaeche neu malen
public void paint(Graphics graph)
{
Color mycolor;
// gif-bild malen
if (gifpicture!=null)
graph.drawImage(gifpicture,0,60,this);
// schwarze Farbe setzen
graph.setColor(Color.black);
// line ziehen
graph.drawLine(arc,arc,arc+22,arc);
// Text schreiben
graph.drawString("Java Beispiel",arc,arc);
// rote Farbe setzen
graph.setColor(Color.red);
// Mausklickposition schreiben
if (mousex>0)
graph.drawString("Mausklick bei "+mousex+" "+mousey,AppletWidth/2,10);
// Ellipse malen
for (int i=arc; i < arc+NUM_ARCS; i++)
{
if (i<NUM_POINTS-1)
{
// Farbe setzen
graph.setColor(mycolors[i]);
// polygonzug besetzen
xPolygon[0]=xPoints[i][0];
xPolygon[1]=xPoints[i][1];
xPolygon[2]=xPoints[i+1][1];
xPolygon[3]=xPoints[i+1][0];
yPolygon[0]=yPoints[i][0];
yPolygon[1]=yPoints[i][1];
yPolygon[2]=yPoints[i+1][1];
yPolygon[3]=yPoints[i+1][0];
}
else if (i==NUM_POINTS-1)
{
// Farbe setzen
graph.setColor(mycolors[i]);
// polygonzug besetzen
xPolygon[0]=xPoints[i][0];
xPolygon[1]=xPoints[i][1];
xPolygon[2]=xPoints[0][1];
xPolygon[3]=xPoints[0][0];
yPolygon[0]=yPoints[i][0];
yPolygon[1]=yPoints[i][1];
yPolygon[2]=yPoints[0][1];
yPolygon[3]=yPoints[0][0];
}
else
{
// Farbe setzen
graph.setColor(mycolors[i-NUM_POINTS]);
// polygonzug besetzen
xPolygon[0]=xPoints[i-NUM_POINTS+1][0];
xPolygon[1]=xPoints[i-NUM_POINTS+1][1];
xPolygon[2]=xPoints[i-NUM_POINTS][1];
xPolygon[3]=xPoints[i-NUM_POINTS][0];
yPolygon[0]=yPoints[i-NUM_POINTS+1][0];
yPolygon[1]=yPoints[i-NUM_POINTS+1][1];
yPolygon[2]=yPoints[i-NUM_POINTS][1];
yPolygon[3]=yPoints[i-NUM_POINTS][0];
}
// Gefuelltes Polygon malen
graph.fillPolygon(xPolygon,yPolygon,4);
}
if (arc<NUM_POINTS)
arc++;
else
arc=0;
}
// callback fuer das Druecken einer Maustaste
public boolean mouseDown(Event e, int x, int y)
{
mousex=x;
mousey=y;
return true;
}
}
Download aimBeispiel.html
Download Grafikdaten
javac aimBeispiel.java
javac -deprecation aimBeispiel.java
Tip: Entfernen sie die Variable "mytask" vom Datentyp "Thread" und alles
was zu ihr gehoert.