Für diejenigen, die es interessiert, gibt es hier
den vollständigen Java-Quelltext:
Diesen Textteil kann man auch direkt als HTML-Quelltext lesen,
falls der Browser ihn im Fenster nicht vollständig oder korrekt darstellt.
(< und > werden möglicherweise als Tags interpretiert)
//
/* ** Auge ** Anfang: 15.2.1999, letzte Änderung: 12.2.2000, Java Version 1.0 */
//
// Tab-stop = 4 Zeichen, sonst wird alles unleserlich
// die Kommentare stehen vor oder neben dem entsprechendem Quellcode
import java.awt.*;
import java.applet.*;
import java.net.URL;
public class Auge extends Applet {
Fenster f;
Button but;
// das eigentliche Applet zeigt nur einen Knopf,
// mit dem man dann das Haupt-Fenster öffnet
public void init() {
f = new Fenster(this);
setLayout(new BorderLayout());
setBackground(Color.yellow);
but = new Button("Fenster öffnen");
add("Center", but);
f.normZeit();
}
public Insets insets() { return new Insets(30,15,30,15); }
public void stop() {
if (f.t != null) f.t.stop();
f.hide();
f.diaZeit.hide();
f.diaTast.hide();
f.diaFarb.hide();
}
public boolean action(Event evt, Object arg) {
if (evt.target == but) {
f.show();
f.resize(650,500);
f.move(100,50);
f.requestFocus();
f.initial();
}
return true;
}
}
class Fenster extends Frame implements Runnable { // zentrale Steuer-Klasse
// Objekte aus selbst definierten Klassen, für Referenz-Zwecke
Schirm sch;
Auswert aus;
Korrel kor;
Auge aug;
DialogEi diaTast; // Dialogfenster für Tasten-Einstellungen
DialogEi diaFarb; // Dialogfenster für Farb-Einstellungen
DialogEi diaZeit; // Dialogfenster für Zeit-Einstellungen
// sichtbare Eigenschaften und Menu-Leiste
Dimension dim; // Schirm-Abmessungen bei t.start()
boolean diaAn; // ein Dialogfenster ist geöffnet
Menu mEinst, mInfo, mStart, mKreuz;
MenuItem miZeit, miFarb, miTast, miInfo, miStart, miWeit, miAusw,
miLinks, miMitte, miRechts;
Button butZeit, butFarb, butTast; // die jeweiligen OK-Knöpfe
String aus_but3 = "noch was"; // Aufschrift auf diesem Button
int kreuz; // Kreuz ist links, mitte, rechts (-1,0,+1)
// Variablen des Dialog-Fensters "Zeiten"
Button reset; // Reset-Button im "Zeiten-Fenster"
TextField txZ[]; // die Textfelder im "Zeiten-Fenster"
int iTxZ; // dieses Textfeld hat den Fokus
Label lb; // Fehlerhinweis
// Variablen des Dialog-Fensters "Tasten"
String sTas[] = { // Bezeichnungen für alle verfügbaren Tasten
"Leerzeichen-Taste",
"Enter",
"0 (null)",
"Pfeil nach unten",
"Pfeil nach oben",
"Pfeil nach links",
"Pfeil nach rechts",
"Escape",
"Maus, linke Taste" };
int key[] = {32, 10, 48, 1005, 1004, 1006, 1007, 27, -1};
// key-Schlüssel für diese Tasten und "Maus"
String strStart; // Bezeichnung für die verwendete Taste
String strHalt; // Bezeichnung für die verwendete Taste
Checkbox cb1[], cb2[]; // für Tasten-Aauswahl
Label lb6; // ein Hinweis im Tasten-Fenster
int keyStart; // Taste zum Starten und Reagieren
int keyHalt; // Taste zum Halten und Auswerten
int st=3, ha=4; // Array-Nummern dieser Tasten und Checkbox
// Variablen des Dialog-Fensters "Farben"
CanEi can; // das Farb-Muster-Quadrat, eigene Klasse
Button butF1, butF2; // für Hintergrund- und Punkt-Farbe
Button butF3, butF4; // für "Punkt größer", "Punkt kleiner"
TextFiel tfF1; // zeigt aktuelle Punkt-Größe an
Scrollbar sbF0, sbF1, sbF2, sbF3; // die 4 Schiebe-Regler im Farb-Fenster
int val; // aktueller Wert der Schiebe-Regler
Label lbh, lbr, lbg, lbb; // zeigen Helligkeit, rot, grün, blau
Checkbox lock; // Helligkeit bleibt konstant
int hell, rot, grun, blau; // Farb-Parameter für die Muster-Farben
double h=0, r=0, g=0, b=0; // Zwischenwerte für eine Farbe
Color cBuf; // Muster-Farbe für Punkt
Color bBuf; // Muster-Farbe für Hintergrund
int dBuf; // Muster-Punkt-Größe
boolean punktBol; // wenn die Punkt-Farbe verändert wird
boolean bolr, bolg, bolb, bol // gewisse Erinnerungen für die Regler
// Variablen für den Haupt-Ablauf und Auswertung
Thread t; // steuert die Blink-Abfolge in run()
int dur =10; // Durchmesser vom Blink-Punkt
int dau; // Blink-Dauer
int p_min; // minimaler Zeitabstand beim Blinken
int p_max; // maximaler Zeitabstand beim Blinken
Color c =Color.r // Blink-Farbe
Color back =Color.black; // Hintergrund-Farbe
int i; // fortlaufender Zähler der Blinker
long time; // Blink-Zeitpunkt, Anfang
long anzeit; // Anfangszeit, auch nach Pause
int gezeit; // Gesamtzeit des Versuchs
int gesp; // Anzahl der gesehenen Gespenster-Punkte
int anz; // maximale Anzahl der Blinker
// in diesen Arrays werden die Ergebnisse gespeichert
int res_x[]; // Resultate jedes Blinkens, x-Wert
int res_y[]; // Resultate jedes Blinkens, y-Wert
int res_t[]; // Resultate, Reaktionszeit
int res_g[]; // = 1 wenn Gespenst gesehen
int res_w[]; // die Wartezeit vor dem Blinken
// einige Werte, die den Programm-Zustand kennzeichnen
boolean wert; // wenn das Auswertungs-Fenster zu sehen ist
boolean lauf; // solange run() läuft (auch unterbrochen)
boolean suspend; // wenn Thread unterbrochen
boolean scharf; // scharf für Reaktion nach dem Blinken
boolean ende; // sperrt Start-Taste nach Beenden
// Fenster einrichten, Referenzen zu anderen Objekten festlegen
// auch die Dialog-Fenster werden hier eingerichtet,
// nächstes Mal bekommen sie gleich eigene Klassen
Fenster(Auge aug) {
super(" teste deine Augen");
this.aug = aug;
// Anfangs-Zuweisungen
keyStart = key[st];
keyHalt = key[ha];
strStart = sTas[st];
strHalt = sTas[ha];
// Menu-Leiste einrichten
MenuBar mb = new MenuBar();
setMenuBar(mb);
mStart = new Menu(" Start ");
mb.add(mStart);
miStart = new MenuItem("Neu-Start ( F1 )");
mStart.add(miStart);
miAusw = new MenuItem("unterbrechen");
mStart.add(miAusw);
miWeit = new MenuItem("weiter");
mStart.add(miWeit);
mEinst = new Menu("Einstellungen");
mb.add(mEinst);
miZeit = new MenuItem("Frequenz");
mEinst.add(miZeit);
miFarb = new MenuItem("Farben");
mEinst.add(miFarb);
miTast = new MenuItem("Tasten");
mEinst.add(miTast);
mKreuz = new Menu("Kreuz");
mEinst.add(mKreuz);
miLinks = new MenuItem("links");
mKreuz.add(miLinks);
miMitte = new MenuItem("mitte");
mKreuz.add(miMitte);
miRechts = new MenuItem("rechts");
mKreuz.add(miRechts);
mInfo = new Menu(" I n f o ");
mb.add(mInfo);
miInfo = new MenuItem("zur Web-Seite");
mInfo.add(miInfo);
// Layout-Manager für alle Dialog-Fenster, GridBagLayout ist umständlich
// und unanschaulich, aber man hat die besten Gestaltungs-Möglichkeiten
GridBagLayout gri = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
// Dialog-Fenster "Zeiten" wird eingerichtet
diaZeit = new DialogEi(this, " Frequenz-Einstellungen");
diaZeit.setBackground(new Color(230,230,250));
diaZeit.show(); // ist merkwürdigerweise notwendig,
diaZeit.hide(); // damit resize() und move() funktioniert
diaZeit.resize(350, 300);
diaZeit.move(300, 150);
Label lbZ[] = {
new Label("Blink-Dauer (in m.sek):" // 0
new Label("Blink-Pause, minimal:"), // 1
new Label("Blink-Pause, maximal:"), // 2
new Label("Blink-Anzahl, maximal:") // 3
}; // wenn man hier ein Label hinzufügt,
// wird es automatisch mit Textfeld platziert
txZ = new TextField[lbZ.length];
diaZeit.setLayout(gri);
c.fill=c.HORIZONTAL;
c.weightx=0;
c.weighty=1;
c.insets=new Insets(0,6,0,6);
for (int i=0; i< lbZ.length; i++) {
c.gridwidth=2;
gri.setConstraints(lbZ[i], c);
diaZeit.add(lbZ[i]);
c.gridwidth=c.REMAINDER;
txZ[i]=new TextField(10);
gri.setConstraints(txZ[i], c);
diaZeit.add(txZ[i]);
}
c.insets=new Insets(10,0,10,0);
c.gridwidth=1;
c.weighty=2;
c.fill=c.NONE;
reset = new Button("reset");
gri.setConstraints(reset, c);
diaZeit.add(reset);
c.fill = c.HORIZONTAL;
lb = new Label(" ");
gri.setConstraints(lb, c);
diaZeit.add(lb);
c.fill=c.NONE;
butZeit = new Button(" O K ");
gri.setConstraints(butZeit, c);
diaZeit.add(butZeit);
// Dialog-Fenster "Tasten" wird eingerichtet
diaTast = new DialogEi(this, " Tasten-Einstellungen");
diaTast.setBackground(new Color(240,240,210));
diaTast.show();
diaTast.hide();
diaTast.resize(300, 500);
diaTast.move(300, 150);
diaTast.setLayout(gri);
c.insets=new Insets(0,10,20,10);
c.fill=c.NONE;
c.weightx=1;
c.weighty=0;
c.gridwidth=c.REMAINDER;
Label lb1 = new Label("wähle die Tasten, die am bequemsten sind");
gri.setConstraints(lb1, c);
diaTast.add(lb1);
c.insets=new Insets(20,10,0,30);
c.gridwidth=1;
c.fill=c.HORIZONTAL;
Label lb2 = new Label("Taste zum Starten");
gri.setConstraints(lb2, c);
diaTast.add(lb2);
c.gridwidth=c.REMAINDER;
Label lb3 = new Label("Taste zum Anhalten");
gri.setConstraints(lb3, c);
diaTast.add(lb3);
c.insets=new Insets(0,10,20,30);
c.gridwidth=1;
Label lb4 = new Label("und Reagieren");
gri.setConstraints(lb4, c);
diaTast.add(lb4);
c.gridwidth=c.REMAINDER;
Label lb5 = new Label("und Auswerten");
gri.setConstraints(lb5, c);
diaTast.add(lb5);
CheckboxGroup cg1 = new CheckboxGroup();
CheckboxGroup cg2 = new CheckboxGroup();
cb1 = new Checkbox[sTas.length];
cb2 = new Checkbox[sTas.length];
c.insets=new Insets(0,6,0,6);
for (i=0; i< sTas.length; i++) {
cb1[i] = new Checkbox(sTas[i], cg1, (i == st));
c.gridwidth=1;
gri.setConstraints(cb1[i], c);
diaTast.add(cb1[i]);
cb2[i] = new Checkbox(sTas[i], cg2, (i == ha));
c.gridwidth=c.REMAINDER;
gri.setConstraints(cb2[i], c);
diaTast.add(cb2[i]);
}
butTast = new Button(" O K ");
c.insets=new Insets(0,30,0,30);
lb6 = new Label(" ");
gri.setConstraints(lb6, c);
diaTast.add(lb6);
c.insets=new Insets(0,20,20,20);
c.fill=c.NONE;
gri.setConstraints(butTast, c);
diaTast.add(butTast);
// Dialog-Fenster "Farben" wird eingerichtet
diaFarb = new DialogEi(this, " Farb-Einstellungen (nicht minimieren -->)");
diaFarb.setBackground(new Color(220,250,220));
diaFarb.show();
diaFarb.hide();
diaFarb.resize(350, 520);
diaFarb.move(300, 150);
diaFarb.setLayout(gri);
c.weightx = 1;
c.weighty = 1;
c.fill = c.NONE;
c.gridwidth=c.REMAINDER;
c.insets=new Insets(10,0,0,0);
can = new CanEi(this); // eigene Klasse, siehe unten
can.resize(80, 80);
can.setBackground(Color.black);
gri.setConstraints(can, c);
diaFarb.add(can);
can.ini();
c.fill = c.NONE;
c.gridwidth=1;
c.insets=new Insets(10,0,20,0);
butF1 = new Button("Grund");
gri.setConstraints(butF1, c);
diaFarb.add(butF1);
butF2 = new Button("Punkt");
gri.setConstraints(butF2, c);
diaFarb.add(butF2);
c.anchor=c.EAST;
butF3 = new Button(" -");
gri.setConstraints(butF3, c);
diaFarb.add(butF3);
c.anchor=c.CENTER;
tfF1 = new TextField("xxx",4);
tfF1.setEditable(false);
tfF1.setBackground(Color.white);
gri.setConstraints(tfF1, c);
diaFarb.add(tfF1);
c.gridwidth=c.REMAINDER;
c.anchor=c.WEST;
butF4 = new Button("+");
gri.setConstraints(butF4, c);
diaFarb.add(butF4);
c.anchor=c.CENTER;
c.gridwidth=1;
c.gridheight=1;
c.weighty=7;
c.insets=new Insets(0,0,0,0);
c.fill=c.VERTICAL;
sbF0 = new Scrollbar(1, 40, 0, 0, 255);
sbF0.setBackground(Color.white);
gri.setConstraints(sbF0, c);
diaFarb.add(sbF0);
Label lab = new Label("");
gri.setConstraints(lab, c);
diaFarb.add(lab);
sbF1 = new Scrollbar(1, 40, 0, 0, 255);
sbF1.setBackground(Color.white);
gri.setConstraints(sbF1, c);
diaFarb.add(sbF1);
sbF2 = new Scrollbar(1, 40, 0, 0, 255);
sbF2.setBackground(Color.white);
gri.setConstraints(sbF2, c);
diaFarb.add(sbF2);
c.gridwidth=c.REMAINDER;
sbF3 = new Scrollbar(1, 40, 0, 0, 255);
sbF3.setBackground(Color.white);
gri.setConstraints(sbF3, c);
diaFarb.add(sbF3);
c.gridheight=1;
c.gridwidth=1;
c.weighty=1;
c.fill=c.NONE;
lbh = new Label("xxxxxxxxxx"); // die xxx halten den Platz
gri.setConstraints(lbh, c); // für spätere Text-Zuweisungen
diaFarb.add(lbh);
Label lb14 = new Label("");
gri.setConstraints(lb14, c);
diaFarb.add(lb14);
lbr = new Label("xxxxx");
gri.setConstraints(lbr, c);
diaFarb.add(lbr);
lbg = new Label("xxxxx");
gri.setConstraints(lbg, c);
diaFarb.add(lbg);
c.gridwidth=c.REMAINDER;
lbb = new Label("xxxxx");
gri.setConstraints(lbb, c);
diaFarb.add(lbb);
c.gridwidth=1;
Label hel = new Label("Helligkeit");
gri.setConstraints(hel, c);
diaFarb.add(hel);
lock = new Checkbox("lock");
c.anchor=c.WEST;
gri.setConstraints(lock, c);
diaFarb.add(lock);
c.anchor=c.CENTER;
Label rot = new Label("rot ");
gri.setConstraints(rot, c);
diaFarb.add(rot);
Label gru = new Label("grün");
gri.setConstraints(gru, c);
diaFarb.add(gru);
c.gridwidth=c.REMAINDER;
Label bla = new Label("blau");
gri.setConstraints(bla, c);
diaFarb.add(bla);
c.insets=new Insets(0,0,10,0);
butFarb = new Button(" O K ");
gri.setConstraints(butFarb, c);
diaFarb.add(butFarb);
}
// wird kurz aufgerufen, bevor ein neuer Durchlauf gestartet werden soll
void initial() {
removeAll();
if (t != null) t.stop(); // immer erst Thread stoppen, bevor neu starten
sch = new Schirm(this);
setLayout(new GridLayout(1,1));
add(sch);
show();
Warte.warte(this, 1, 300); // wartet hier 300 ms damit sich
} // in Ruhe das Fenster aufbauen kann
void weiter1() { // siehe unten, class Warte
lauf = false;
suspend = false;
ende = false;
aus_but3 = "noch was";
gezeit = 0;
gesp = 0;
res_x = new int[anz]; // setzt die Werte auch gleichzeitig auf 0
res_y = new int[anz];
res_t = new int[anz];
res_g = new int[anz];
res_w = new int[anz];
sch.ini1();
sch.ini2();
requestFocus();
}
// Dies ist die eigentliche Methode, die die Punkte auf dem Schirm aufblinken lässt
// in Zusammenarbeit mit der Klasse "Schirm". Wird aufgerufen mit "t.start()"
public void run() {
dim = sch.size();
anzeit = System.currentTimeMillis();
for (i=0; i< anz ; i++) {
int pause = p_min+dau+(int)((p_max-p_min)*Math.random());
try {Thread.sleep(pause);}
catch (Exception e) { }
int x = 15+(int)((dim.width-dur-30)*Math.random());
int y = 15+(int)((dim.height-dur-30)*Math.random());
sch.blink(x,y,dur,c,dau);
scharf = true;
res_w[i] = pause;
res_x[i] = x;
res_y[i] = y;
time = System.currentTimeMillis();
// (jetzt wird i erhöht)
}
try {Thread.sleep((p_max+p_min)/2);}
catch (Exception e) { }
suspend = true;
ende = true;
i = i-1;
gezeit = gezeit + (int)(System.currentTimeMillis() - anzeit);
sch.fertig();
}
// setzt die Werte der Zeiten-Einstellungen wieder zurück
void normZeit() {
dau = 200;
p_min 800;
p_max 2400;
anz = 10000;
txZ[0].setText(Integer.toString(dau));
txZ[1].setText(Integer.toString(p_min));
txZ[2].setText(Integer.toString(p_max));
txZ[3].setText(Integer.toString(anz));
}
// setzt die Schiebe-Regler auf die entsprechenden Positionen für eine Farbe
// wenn das Farben-Fenster geöffnet wird
void setBars(Color Buf) {
rot = Buf.getRed();
grun = Buf.getGreen();
blau = Buf.getBlue();
hell = (rot+grun+blau);
lbh.setText(Integer.toString(hell/3));
lbr.setText(Integer.toString(rot));
lbg.setText(Integer.toString(grun));
lbb.setText(Integer.toString(blau));
sbF0.setValue(255-hell/3);
sbF1.setValue(255-rot);
sbF2.setValue(255-grun);
sbF3.setValue(255-blau);
}
// In den Methoden handleEvent(), action() und keyDown() werden die Ereignisse
// vom Haupt-Fenster und auch von den Dialog-Fenstern aufgefangen. Die Anweisungen
// stehen hier überwiegend direkt in den entsprechenden verzweigten if-Blöcken.
public boolean handleEvent(Event evt) {
// Action- und Key-Events weiterleiten
if (evt.id == Event.ACTION_EVENT) { action(evt, evt.arg); }
if (evt.id == 401 || evt.id == 403) { keyDown(evt, evt.key); }
// Fenster schließen
if (evt.id == Event.WINDOW_DESTROY && diaAn == false) {
if (t != null) t.stop();
hide();
}
else if (evt.id == Event.WINDOW_DESTROY && diaAn == true) {
diaAn = false;
diaZeit.hide();
diaFarb.hide();
diaTast.hide();
}
// ***** Farb Einstellungen *****
// weitere Farb-Einstellungen in der action()-Methode
if (evt.target instanceof Scrollbar) {
if (evt.target == sbF1) {
if (bolr == false) { // dieser Block soll nur einmal
g = grun+.1; // pro Regler ausgeführt werden
b = blau+.1;
bolr = true;
bolg = false; bolb = false; bolh = false;
}
val = 255 - sbF1.getValue(); // unten ist doch immer Null? Oder?
rot = val;
if (lock.getState() == true) {
grun = (int)((hell-rot)/(b/g+1));
blau = (int)((hell-rot)/(g/b+1));
}
else
hell = rot+grun+blau;
}
if (evt.target == sbF2) {
if (bolg == false) {
r = rot+.1;
b = blau+.1;
bolg = true;
bolr = false; bolb = false; bolh = false;
}
val = 255 - sbF2.getValue();
grun = val;
if(lock.getState() == true) {
rot = (int)((hell-grun)/(b/r+1));
blau = (int)((hell-grun)/(r/b+1));
}
else
hell = rot+grun+blau;
}
if (evt.target == sbF3) {
if (bolb == false) {
g = grun+.1;
r = rot+.1;
bolb = true;
bolg = false; bolr = false; bolh = false;
}
val = 255 - sbF3.getValue();
blau = val;
if(lock.getState() == true) {
grun = (int)((hell-blau)/(r/g+1));
rot = (int)((hell-blau)/(g/r+1));
}
else
hell = rot+grun+blau;
}
if (evt.target == sbF0) {
if (bolh == false) {
r = rot+.1;
g = grun+.1;
b = blau+.1;
h = hell+.1;
bolh = true;
bolr = false; bolg = false; bolb = false;
}
val = 255 - sbF0.getValue();
rot = (int)(val*3/(g/r+b/r+1));
grun = (int)(val*3/(r/g+b/g+1));
blau = (int)(val*3/(r/b+g/b+1));
hell = val*3;
}
// die Schieberegler und Labels werden auf ihre neuen Werte gesetzt,
// hell verändert die Farben; rot, grün, blau beeinflussen sich gegenseitig
if(rot > 255)rot=255;
if(grun > 255)grun=255;
if(blau > 255)blau=255;
if(rot < 0)rot=0;
if(grun < 0)grun=0;
if(blau < 0)blau=0;
int i = hell-rot-grun-blau;
if (i >= -1 && i <= 2)
lbh.setText(Integer.toString(hell/3));
else
lbh.setText(Integer.toString(hell/3)+" ("+Integer.toString((hell-i)/3)+")");
lbr.setText(Integer.toString(rot));
lbg.setText(Integer.toString(grun));
lbb.setText(Integer.toString(blau));
sbF0.setValue(255-hell/3);
sbF1.setValue(255-rot);
sbF2.setValue(255-grun);
sbF3.setValue(255-blau);
// das Farb-Muster wird gefärbt
if (punktBol) cBuf = new Color(rot,grun,blau);
else bBuf = new Color(rot,grun,blau);
can.fillRect(bBuf);
can.fillOval(cBuf, dBuf);
}
return false;
}
public boolean action(Event evt, Object arg) {
// die Ereignise zu den entsprechenden Tasten weiterleiten,
// dort werden sie dann richtig verarbeitet
if (evt.target == miStart) { keyDown(evt, Event.F1); }
if (evt.target == miWeit) { keyDown(evt, keyStart); }
if (evt.target == miAusw) { keyDown(evt, keyHalt); }
// ***** Zeit Einstellungen *****
// Dialog-Fenster öffnen und Textfelder neu beschriften
if (evt.target == miZeit) {
lb.setText(" ");
diaZeit.show();
diaAn = true;
txZ[0].setText(Integer.toString(dau));
txZ[1].setText(Integer.toString(p_min));
txZ[2].setText(Integer.toString(p_max));
txZ[3].setText(Integer.toString(anz));
iTxZ = 1;
txZ[1].requestFocus();
}
// die neuen Werte übernehmen und prüfen
if (evt.target == butZeit ||
(evt.target instanceof TextField && diaZeit.isShowing())) {
try {
dau = Integer.parseInt(txZ[0].getText());
p_min = Integer.parseInt(txZ[1].getText());
p_max = Integer.parseInt(txZ[2].getText());
anz = Integer.parseInt(txZ[3].getText());
}
catch (Exception ex) {
System.out.println("falsche Eingabe im \"Zeiten\"-Fenster!"+ex);
lb.setText(" falsche Eingabe !");
return true; // hier wird die action()-Methode vorzeitig abgebrochen
}
diaZeit.hide();
if (dau <= 10) dau=10;
if (p_min < 0) p_min=0;
if (p_max < 0) p_max=0;
if (anz <= 1) anz=1;
if (p_min > p_max) {
int buf = p_min;
p_min = p_max;
p_max = buf;
}
if (t != null) t.stop();
initial(); // mit veränderten Werten ist es besser, neu zu starten
}
// veränderte Werte zurücksetzen
if (evt.target == reset) {
lb.setText(" ");
normZeit();
}
// ***** Tasten Einstellungen *****
if (evt.target == miTast) {
diaTast.show();
diaAn = true;
}
// die Check-Box wird abgefragt und die "Key-Array-Nummer" gemerkt
if (evt.target == butTast) {
for (i=0; i< sTas.length; i++) {
if (cb1[i].getState() == true) {
st = i;
}
if (cb2[i].getState() == true) {
ha = i;
}
}
if (st != ha) {
keyStart = key[st];
strStart = sTas[st];
keyHalt = key[ha];
strHalt = sTas[ha];
lb6.setText(" ");
diaTast.hide();
}
else {
lb6.setText("Tasten müssen verschieden sein! O K ");
}
}
// ***** Farb Einstellungen *****
// weitere Farb-Einstellungen in der handleEvant()-Methode
// Fenster anzeigen und aktuelle Werte setzen
if (evt.target == miFarb) {
diaFarb.show();
diaAn = true;
punktBol = true;
can.ini(); // zeigt das Muster-Quadrat
cBuf = new Color(c.getRed(), c.getGreen(), c.getBlue()); // klonen, per Hand
bBuf = new Color(back.getRed(), back.getGreen(), back.getBlue());
dBuf = dur;
setBars(cBuf); // setzt die Schiebe-Regler
tfF1.setText(Integer.toString(dBuf));
}
// Punkt oder Hintergrund wählen, neue Werte vor-merken
if (evt.target == butF1 && punktBol == true) {
punktBol = false;
cBuf = new Color(rot, grun, blau);
setBars(bBuf);
}
if (evt.target == butF2 && punktBol == false) {
punktBol = true;
bBuf = new Color(rot, grun, blau);
setBars(cBuf);
}
// Punkt-Größe wird verändert
if (evt.target == butF3) {
dBuf = dBuf-1;
if (dBuf < 1) dBuf = 1;
tfF1.setText(Integer.toString(dBuf));
can.fillRect(bBuf);
can.fillOval(cBuf, dBuf);
}
if (evt.target == butF4) {
dBuf = dBuf+1;
tfF1.setText(Integer.toString(dBuf));
can.fillRect(bBuf);
can.fillOval(cBuf, dBuf);
}
// neue Farben ins Haupt-Programm übernehmen
if (evt.target == butFarb) {
if (punktBol == true) cBuf = new Color(rot, grun, blau);
else bBuf = new Color(rot, grun, blau);
c = new Color(cBuf.getRed(), cBuf.getGreen(), cBuf.getBlue());
back = new Color(bBuf.getRed(), bBuf.getGreen(), bBuf.getBlue());
dur = dBuf;
diaFarb.hide();
initial();
}
// Kreuz versetzen, links, mitte, rechts
// mit verändertem Kreuz ist ein Neu-Start sinnvoll
if (evt.target == miLinks && kreuz != -1) {
kreuz = -1;
initial();
}
if (evt.target == miMitte && kreuz != 0) {
kreuz = 0;
initial();
}
if (evt.target == miRechts && kreuz != 1) {
kreuz = 1;
initial();
}
// Info anfordern, die HTML-Seite wird im Browser angezeigt
if (evt.target == miInfo){
hide();
// vorübergehend außer Kraft gesetzt
// String a = "allgemein";
// URL theURL;
// try { theURL = new URL(aug.getDocumentBase(),"Auge.html#" + a);
// aug.getAppletContext().showDocument(theURL);
// }
// catch (Exception ex) {System.out.println(ex+" "+ex.getMessage()); }
}
return true;
}
// Drei Tasten werden verwendet für Neu-Start, unterbrechen, weitermachen, auswerten,
// je nach Status des Programms ändern sie oft ihre Bedeutung und Reaktionen, die sie
// auslösen müssen; deshalb die vielen Boolean und if-Abfragen.
// Für den Anwender ist es bequemer, mit nur wenigen Tasten auszukommen
public boolean keyDown(Event evt, int key) {
if (key == keyStart && sch.isShowing()) {
// Reaktions-Eingaben während eines Ablaufs
if (lauf == true && suspend == false) {
if (scharf == true) {
res_t[i-1] = (int)(System.currentTimeMillis() - time);
System.out.println("i= "+(i-1)+" res_t "+res_t[i-1]+" res_w "+res_w[i-1]);
scharf = false;
}
else {
gesp = gesp+1;
res_g[i-1]++;
System.out.println(" Gespenst "+gesp);
}
}
// neu starten oder weitermachen
else {
if (suspend == false && ende == false) {
sch.ini1();
lauf = true;
if (t != null) t.stop();
t = new Thread(this);
t.start();
}
if (suspend == true && ende == false) {
sch.ini1();
suspend = false;
anzeit = System.currentTimeMillis();
try {Thread.sleep(p_min);}
catch (Exception e) { }
t.resume();
}
}
}
// Schirm-Fenster wieder anzeigen und weitermachen
if (key == keyStart && !sch.isShowing() && wert == true && ende == false) {
wert = false;
mehr();
}
// unterbrechen und dann auch auswerten
if (key == keyHalt && lauf == true) {
if (suspend == false) {
if(t.isAlive()) t.suspend();
suspend = true;
gezeit = gezeit + (int)(System.currentTimeMillis() - anzeit);
if (i >=2) i = i-2;
sch.susp();
}
else {
wert = true;
wertung(); // die Auswertung wird vorgenommen
}
}
// Neu-Start, immer mit F1 (oder anderen Knöpfen)
if (key == 1008) { // F1
if (t != null) t.stop();
initial();
}
// bewegt den Fokus im Zeiten-Fenster (in Java 1.1 nicht mehr nötig)
if (key == 9) { //tab
iTxZ++;
if (iTxZ >= txZ.length) iTxZ=0;
txZ[iTxZ].requestFocus();
}
return true;
}
// die Auswertung in der Klasse Auswert wird eingeleitet und angezeigt
void wertung() {
removeAll();
aus = new Auswert(this);
setLayout(new GridLayout(1,1));
add(aus);
show();
}
// die extra Auswertung "Korrelation" wird aufgerufen und angezeigt
// ähnlich wie wertung()
void korrel() {
removeAll();
kor = new Korrel(this);
setLayout(new GridLayout(1,1));
add(kor);
show();
}
// vom Auswerte-Fenster aus wird der gleiche Versuch wieder aufgenommen
void mehr() {
removeAll();
sch = new Schirm(this);
setLayout(new GridLayout(1,1));
add(sch);
setTitle(" teste deine Augen");
show();
Warte.warte(this, 3, 300); // wartet hier 300 ms damit sich
} // in Ruhe das Fenster aufbauen kann
void weiter3() { // siehe unten, class Warte
sch.ini1();
sch.susp();
}
}
// erzeugt den (schwarzen) Schirm mit den blinkenden Punkten
class Schirm extends Canvas implements Runnable {
Fenster f;
Thread t;
Graphics g;
Dimension dim; // Abmessungen des Schirms
int mit_x, mit_y; // x und y für die Bildmitte
int x; int y; int d; Color c; int zeit; // aus "Fenster" übertragene Daten
Schirm(Fenster f) {
super();
this.f = f;
setBackground(f.back);
}
// "löscht" den Schirm und zeichnet das Kreuz (nur ein mal)
void ini1() {
dim = size();
setBackground(f.back);
g = getGraphics();
g.setColor(f.back);
g.fillRect(0, 0, dim.width, dim.height);
mit_x = dim.width/2+(int)(dim.width*0.34*f.kreuz);
mit_y = dim.height/2;
g.setColor(Color.lightGray);
g.drawLine(mit_x-8, mit_y, mit_x+8, mit_y);
g.drawLine(mit_x, mit_y-8, mit_x ,mit_y+8);
}
// schreibt die drei Zeilen zentriert (nur ein mal)
void ini2() {
g = getGraphics();
dim = size();
String s1 = "Mit \""+f.strStart+"\" starten";
String s2 = "und dann damit jedes Blinken bestätigen";
String s3 = "Mit \""+f.strHalt+"\" stoppen und auswerten";
Font fo = new Font("Helvetica", Font.PLAIN, 16);
FontMetrics fm = getFontMetrics(fo);
int x1, x2, x3, la;
la = fm.stringWidth(s1);
x1 = (dim.width-la)/2;
la = fm.stringWidth(s2);
x2 = (dim.width-la)/2;
la = fm.stringWidth(s3);
x3 = (dim.width-la)/2;
g.setFont(fo);
g.setColor(Color.lightGray);
g.drawString(s1, x1, mit_y+50);
g.drawString(s2, x2, mit_y+80);
g.drawString(s3, x3, mit_y+110);
}
// schreibt die drei Zeilen (ein mal)
void susp() {
String s1 = "angehalten";
String s2 = "weiter mit \""+f.strStart+"\"";
String s3 = "auswerten mit \""+f.strHalt+"\"";
Font f = new Font("Helvetica", Font.PLAIN, 16);
FontMetrics fm = getFontMetrics(f);
int x1, x2, x3, la;
la = fm.stringWidth(s1);
x1 = (dim.width-la)/2;
la = fm.stringWidth(s2);
x2 = (dim.width-la)/2;
la = fm.stringWidth(s3);
x3 = (dim.width-la)/2;
g.setFont(f);
g.setColor(Color.lightGray);
g.drawString(s1, x1, mit_y+50);
g.drawString(s2, x2, mit_y+80);
g.drawString(s3, x3, mit_y+110);
}
// schreibt die zwei Zeilen (ein mal)
void fertig() {
String s1 = "f e r t i g";
String s3 = "auswerten mit \""+f.strHalt+"\"";
Font f = new Font("Helvetica", Font.PLAIN, 16);
FontMetrics fm = getFontMetrics(f);
int x1, x2, x3, la;
la = fm.stringWidth(s1);
x1 = (dim.width-la)/2;
la = fm.stringWidth(s3);
x3 = (dim.width-la)/2;
g.setFont(f);
g.setColor(Color.lightGray);
g.drawString(s1, x1, mit_y+50);
g.drawString(s3, x3, mit_y+110);
}
// die Parameter für den Blink-Vorgang werden hier übergeben
// direkt in run() kann man keine Parameter übergeben
public void blink(int x, int y, int d, Color c, int zeit) {
this.x=x; this.y=y; this.d=d; this.c=c; this.zeit=zeit;
t = new Thread(this);
t.start();
}
// ein mal blinken, bitte !
public void run() {
int x=this.x; int y=this.y; int d=this.d; int zeit=this.zeit;
g.setColor(c);
g.fillOval(x, y, d, d);
try {Thread.sleep(zeit);}
catch (Exception e) {}
g.setColor(f.back);
g.fillRect(x, y, d, d);
g.setColor(Color.lightGray);
g.drawLine(mit_x-8, mit_y, mit_x+8, mit_y);
g.drawLine(mit_x, mit_y-8, mit_x, mit_y+8);
}
// verwandelt den Mausklick in ein Key-Event mit dem Schlüssel "-1"
public boolean mouseDown(Event evt, int x, int y) {
f.keyDown(evt, -1);
return true;
}
// wird das Fenster verändert, werden die jeweils aktuellen Schriftzüge erneuert
public void paint(Graphics g) {
if (f.suspend == true) {
ini1();
susp();
}
if (f.lauf == false && f.suspend == false) {
ini1();
ini2();
}
requestFocus();
}
}
// hier werden die Daten ausgewertet und am Monitor aufbereitet angezeigt
class Auswert extends Panel {
Fenster f;
Graphics g;
Dimension dim, dimS; // Abmessungen des Schirms
Button but1, but2, but3; // Knöpfe auf dem Auswert-Schirm
Color c = Color.red; // Farbe der Diagramm-Punkte
int mit_x, mit_y; // x und y für die Bildmitte
int inx, iny, ind; // Rand oben und links und mitte
int nicht; // nicht gesehene Punkte
int dopp; // doppelt gesehene Punkte
int rzeit; // mittlere Reaktionszeit
int res_x[]; int res_y[]; int res_t[]; int res_g[]; int res_w[]; int i_in;
// Daten aus "Fenster" übernommen
// Daten übertragen , Knöpfe einrichten
Auswert(Fenster f) {
super();
this.f = f;
this.res_x = f.res_x;
this.res_y = f.res_y;
this.res_t = f.res_t;
this.res_g = f.res_g;
this.res_w = f.res_w;
dim = f.dim;
i_in = f.i;
setBackground(new Color(255,245,206));
but1 = new Button(" weiter ");
but2 = new Button("Neu-Start");
but3 = new Button(f.aus_but3);
add(but1);
add(but2);
add(but3);
}
// Farbe und Abstände festlegen
void ini() {
c = f.c;
if ((c.getRed()+c.getGreen()+c.getBlue()) > 510) c = Color.gray;
g = getGraphics();
dimS = size();
inx = (int)(dimS.width*0.05);
iny = (int)(dimS.width*0.05);
if (iny< 20) iny=20;
ind = (int)(dimS.width*0.05);
}
// das Netzhaut-Abbild mit den gesehenen Punkten wird gemacht
void retina() {
// Quadrat und Kreuzchen werden gezeichnet
g.setColor(Color.white);
g.fillRect(inx, iny, dim.width/2, dim.height/2);
g.setColor(Color.black);
g.drawRect(inx, iny, dim.width/2, dim.height/2);
mit_x = dim.width/4+(int)(dim.width*0.17*f.kreuz)+inx;
mit_y = dim.height/4+iny;
g.setColor(new Color(128,128,128));
g.drawLine(mit_x-5, mit_y, mit_x+5, mit_y);
g.drawLine(mit_x, mit_y-5, mit_x ,mit_y+5);
// Punkte werden gezeichnet und entsprechend gefärbt
int dur = f.dur/2;
if (dur < 4) dur = 4;
for (int i=0; i<=i_in; i++) {
if (res_t[i] == 0) {
g.drawOval(res_x[i]/2+inx, res_y[i]/2+iny, dur+1, dur+1);
}
}
g.setColor(c);
for (int i=0; i<=i_in; i++) {
if (res_t[i] != 0) {
g.fillOval(res_x[i]/2+inx, res_y[i]/2+iny, dur, dur);
}
}
}
// das Reaktions-Diagramm wird gemacht
void graph() {
// Lage und größe festlegen
int posx = inx;
int posy = 2*iny+dim.height/2+25;
int lang = dimS.width-2*inx;
int hoch = dimS.height-posy-25;
Color gr = new Color(255,130,0);
g.setColor(Color.white);
g.fillRect(posx, posy, lang, hoch);
g.setColor(Color.black);
g.drawRect(posx, posy, lang, hoch);
String s1 = "Reaktions-Verlauf :";
Font fo = new Font("Helvetica", Font.BOLD, 14);
g.setFont(fo);
g.drawString(s1, inx, posy-8);
// mittlere Reaktions-Zeit und (nicht)gesehene Anzahl ermitteln
int sum=0; int zahl=0;
nicht = 0;
dopp = 0;
for (int i=0; i<=i_in; i++) {
if (res_t[i] > 0) {
sum = sum + res_t[i];
zahl = zahl + 1;
}
if (res_t[i] == 0) { nicht++; }
if (res_g[i] >= 1) { dopp++; }
}
int tmax = 0;
if (zahl != 0) {
tmax = 2*(sum/zahl);
rzeit = sum/zahl;
}
else { tmax = 1000; }
// Diagramm-Faktoren für X- und Y-Achse festlegen
double fy = 0;
if (tmax > 0) fy = (hoch-20)/(double)(tmax);
double fx = 0;
if (i_in >1) fx = (lang-45)/(double)(i_in);
// die Kurve zeichnen
g.setColor(gr);
int zt1, zt2; // vorherige Zeit, diese Zeit
int x1, x2, y1, y2; // Parameter für jeden Strich
for (int i=1; i<=i_in; i++) {
boolean leer = false; // für nicht gesehene Punkte
zt2 = res_t[i];
if (zt2 > (int)(tmax*1.2)) zt2=(int)(tmax*1.2);
if (zt2 == 0) {zt2=tmax/2; leer=true;}
zt1 = res_t[i-1];
if (zt1 == 0) zt1 = tmax/2;
if (zt1 > (int)(tmax*1.2)) zt1=(int)(tmax*1.2);
x1 = (int)((i-1)*fx)+posx+35;
x2 = (int)(i*fx)+posx+35;
y1 = posy+hoch-(int)(zt1*fy)-10;
y2 = posy+hoch-(int)(zt2*fy)-10;
g.drawLine(x1, y1, x2, y2);
// "nicht gesehen" markieren
if (leer == true) {
g.setColor(Color.black);
g.drawOval(x2-2, y2-2, 5, 5);
g.setColor(Color.white);
g.fillOval(x2-1, y2-1, 3, 3);
g.setColor(gr);
}
// "doppelt gesehen" markieren
if (res_g[i] >= 1) {
g.setColor(Color.blue);
g.fillOval(x2-2, y2-2, 5, 5);
g.setColor(gr);
}
}
// Lienien und Beschriftung des Diagramms
fo = new Font("TimesRoman", Font.PLAIN, 11);
g.setFont(fo);
FontMetrics fm = getFontMetrics(fo);
g.setColor(Color.black);
String st = Integer.toString(tmax);
g.drawString(st, posx+5, posy+14);
st = Integer.toString(tmax/2);
g.drawString(st, posx+5, posy+hoch/2+4);
st = " 0";
g.drawString(st, posx+5, posy+hoch-6);
st = "in ms";
g.drawString(st, posx+5, posy+hoch-20);
st = Integer.toString(i_in+1);
g.drawString(st, posx+lang-fm.stringWidth(st)-12, posy+hoch-12);
st = "1";
g.drawString(st, posx+38, posy+hoch-12);
g.setColor(Color.lightGray);
g.drawLine(posx+35, posy+10, posx+55, posy+10);
g.drawLine(posx+35, posy+hoch/2, posx+55, posy+hoch/2);
g.drawLine(posx+35, posy+hoch-10, posx+35, posy+hoch-25);
g.drawLine(posx+27, posy+hoch-10, posx+lang-5, posy+hoch-10);
g.drawLine(posx+lang-10, posy+hoch-10, posx+lang-10, posy+hoch-25);
}
// die "Zahlen" anzeigen und genaues Layout festlegen (per Hand)
void daten() {
// Lage und Größe festlegen, Rechteck zeichnen
int x = inx+dim.width/2+ind;
int y = iny+dim.height/4;
int w = dimS.width-2*inx-ind-dim.width/2;
int h = dim.height/4;
g.setColor(Color.white);
g.fillRect(x, y, w, h);
g.setColor(Color.black);
g.drawRect(x, y, w, h);
// Bezeichnungen der Daten anzeigen
String s1 = "Anzahl Blinker:";
String s2 = "Dauer des Versuchs:";
String s3 = "nicht gesehen:";
String s4 = "zuviel gesehen:";
String s5 = "mittlere Reaktionszeit:";
Font fo = new Font("TimesRoman", Font.PLAIN, 13);
g.setFont(fo);
int a = (h-100)/2;
if (a <= 0) a=0;
g.drawString(s1, x+8, y+a+14);
g.drawString(s2, x+8, y+a+34);
g.drawString(s3, x+8, y+a+54);
g.drawString(s4, x+8, y+a+74);
g.drawString(s5, x+8, y+a+94);
// die Daten selbst anzeigen
s1 = Integer.toString(f.i+1);
// Uhrzeit-Format realisieren
int sek = (f.gezeit/1000)%60;
int min = (f.gezeit/1000)/60;
if (min == 0)
s2 = (Integer.toString(sek)+" s");
if (min > 0)
s2 = (Integer.toString(min)+" m "+Integer.toString(sek)+" s");
// die übrigen Daten anzeigen
s3 = Integer.toString(nicht);
s4 = Integer.toString(dopp);
s5 = (Integer.toString(rzeit)+" ms");
g.setColor(new Color(0,160,0));
fo = new Font("Helvetica", Font.BOLD, 13);
g.setFont(fo);
g.drawString(s1, x+135, y+a+14);
g.drawString(s2, x+135, y+a+34);
g.drawString(s3, x+135, y+a+54);
g.drawString(s4, x+135, y+a+74);
g.drawString(s5, x+135, y+a+94);
// Überschrift anzeigen
s1 = "Ergebnis in Zahlen:";
fo = new Font("Helvetica", Font.BOLD, 14);
g.setFont(fo);
g.setColor(Color.black);
g.drawString(s1, x, y-8);
}
// die übrige Beschriftung der Auswert-Seite und die Knöpfe
void schrift() {
String s1 = "Auswertung";
String s4 = "Das wurde gesehen:";
String s2 = " = gesehene Punkte ";
String s3 = " = nicht gesehene Punkte";
String s5 = " = nicht gesehene Punkte ";
String s6 = " = doppelt gesehene Punkte";
Font fo;
FontMetrics fm;
// Überschrift schreiben, variable Größe und Lage
fo = new Font("Helvetica", Font.PLAIN, dimS.width/21);
g.setFont(fo);
fm = getFontMetrics(fo);
int x1, la;
int w = (dimS.width-2*inx-ind-dim.width/2)-fm.stringWidth(s1);
if (w < -2*ind) w = -2*ind;
int x = inx+dim.width/2+ind+w/2;
g.setColor(Color.black);
g.drawString(s1, x, (int)(dimS.height*0.03)+fm.getAscent());
// die übrigen Überschriften schreiben
fo = new Font("Helvetica", Font.BOLD, 14);
g.setFont(fo);
g.setColor(Color.black);
g.drawString(s4, inx, iny-8);
// die übrigen Beschriftungen schreiben
fo = new Font("TimesRoman", Font.PLAIN, 11);
fm = getFontMetrics(fo);
int dur = f.dur/2;
if (dur > 15) dur=15;
if (dur < 4) dur = 4;
int y = iny+dim.height/2+fm.getAscent()+8;
int yd = y-(fm.getAscent()+dur)/2;
g.setFont(fo);
g.drawString(s2, inx+dur, y-2);
g.drawString(s3, inx+fm.stringWidth(s2)+dur*2, y-2);
g.drawString(s5, inx+5, dimS.height-8);
g.drawString(s6, inx+fm.stringWidth(s5)+10, dimS.height-8);
// die Symbole der Diagramme anbringen
g.setColor(c);
g.fillOval(inx, yd, dur, dur);
g.setColor(Color.gray);
g.drawOval(inx+fm.stringWidth(s2)+dur-1, yd-1, dur+1, dur+1);
g.setColor(Color.black);
g.drawOval(inx, dimS.height-13, 5, 5);
g.setColor(Color.blue);
g.fillOval(inx+fm.stringWidth(s5)+5, dimS.height-13, 5, 5);
// Lage und Größe der Knöpfe festlegen
but1.reshape(dimS.width-inx-125, iny+dim.height/8-13, 55, 26);
but2.reshape(dimS.width-inx-55, iny+dim.height/8-13, 55, 26);
but3.reshape(dim.width/2+inx+ind, iny+dim.height/8-13, 55, 26);
}
// Reaktionen der drei Knöpfe
public boolean action(Event evt, Object arg) {
// werden weitergeleitet und später wie die Key-Events behandelt
if (evt.target == but1)
f.keyDown(evt, f.keyStart);
if (evt.target == but2)
f.keyDown(evt, Event.F1);
// ruft das Korrelations-Fenster auf (auf Umwegen, über "f")
if (evt.target == but3) {
f.aus_but3 = "Korrelat.";
f.korrel();
}
return false;
}
// alle zeichnenden Methoden werden hier nochmals (und erstmals) aufgerufen
public void paint(Graphics g) {
ini();
retina();
graph();
daten();
schrift();
requestFocus();
}
}
// ist für die zusätzliche Korrelations-Auwertung und -Anzeige zuständig
class Korrel extends Panel {
Fenster f;
Dimension dim;
Graphics g;
Button but4;
int inx1, inx2, iny1, iny2; // Mindest-Einrückungen
// Referenzen zuweisen, Knopf einfügen
Korrel(Fenster f) {
super();
this.f = f;
setBackground(new Color(255,245,206));
but4 = new Button("zurück");
add(but4); // ruft indirekt auch paint() auf, daher darf paint(),
// (auch indirekt) nicht add() aufrufen
}
// die Haupt-Methode, erstellt die Korrelations-Anzeige
void korrel() {
// Größe und Position festlegen, Rechteck zeichnen
dim = size();
g = getGraphics();
inx1 = 200;
inx2 = (int)(dim.width*0.10);
iny1 = (int)(dim.width*0.10);
if (iny1 < 25) iny1 = 25;
iny2 = (int)(dim.width*0.10);
if (iny2 < 40) iny2 = 40;
int lang = Math.min(dim.width-inx1-inx2, dim.height-iny1-iny2);
int hoch = lang;
int posx = dim.width-lang-inx2;
int posy = iny1;
g.setColor(Color.white);
g.fillRect(posx ,posy , lang, hoch);
g.setColor(Color.black);
g.drawRect(posx, posy, lang, hoch);
but4.reshape(35, dim.height-60, 55, 26);
// Punkte eintragen und farblich kennzeichnen
double fx = 0;
if (f.p_max-f.p_min > 0) fx = (lang)/(double)(f.p_max-f.p_min);
double fy = 0;
if (f.aus.rzeit*2 > 0) fy = (hoch)/(double)(f.aus.rzeit*2);
int max = f.aus.rzeit*2;
int x, y;
int r_t;
for (int i=0; i<=f.i; i++) {
g.setColor(new Color(180,140,0));
if (i >=1) if (f.res_g[i-1] > 0) g.setColor(new Color(110,110,255));
r_t = f.res_t[i];
if (r_t >= max) r_t = max;
if (r_t > 0) {
x = posx+(int)((f.res_w[i]-f.p_min-f.dau)*fx)-3;
y = posy+hoch-(int)(r_t*fy)-3;
g.fillOval(x, y, 6, 6);
}
if (f.res_t[i] == 0) {
x = posx+(int)((f.res_w[i]-f.p_min-f.dau)*fx)-3;
y = posy+hoch-10;
g.drawOval(x, y, 6, 6);
}
}
// Beschriftung Titel, variable Größe und zentriert
Font fo = new Font("Helvetica", Font.BOLD, (posx-40)/17);
FontMetrics fm = getFontMetrics(fo);
g.setFont(fo);
g.setColor(Color.black);
String s[] = {
"K o r r e l a t i o n",
" ",
"zwischen Reaktions-Zeit",
"und Blink-Pause"
};
for (int i=0; i< s.length; i++) {
g.drawString(s[i], (posx-40-fm.stringWidth(s[i]))/2,
posy+(fm.getHeight()+6)*(i+1));
}
// Beschriftung Diagramm und Achs-Zahlen
fo = new Font("TimesRoman", Font.PLAIN, 11);
fm = getFontMetrics(fo);
String s1 = Integer.toString(f.p_min);
String s2 = Integer.toString((f.p_max+f.p_min)/2);
String s3 = Integer.toString(f.p_max);
String s4 = "Blink-Pause in ms";
g.setFont(fo);
g.setColor(Color.black);
g.drawString(s1, posx-fm.stringWidth(s1)/2, posy+hoch+24);
g.drawString(s2, posx+lang/2-fm.stringWidth(s2)/2, posy+hoch+24);
g.drawString(s3, posx+lang-fm.stringWidth(s3)/2, posy+hoch+24);
g.drawString(s4, posx+lang-fm.stringWidth(s4)+fm.stringWidth(s3)/2, posy+hoch+38);
s1 = Integer.toString(0);
s2 = Integer.toString(f.aus.rzeit);
s3 = Integer.toString(f.aus.rzeit*2);
s4 = "Reaktions-Zeit in ms";
g.drawString(s1, posx-14-fm.stringWidth(s1), posy+hoch+4);
g.drawString(s2, posx-14-fm.stringWidth(s2), posy+hoch/2+4);
g.drawString(s3, posx-14-fm.stringWidth(s3), posy+4);
g.drawString(s4, posx-14-fm.stringWidth(s3), posy-11);
// die kleinen Striche zeichnen
g.drawLine(posx, posy+hoch, posx, posy+hoch+10);
g.drawLine(posx+lang/2, posy+hoch, posx+lang/2, posy+hoch+10);
g.drawLine(posx+lang, posy+hoch, posx+lang, posy+hoch+10);
g.drawLine(posx-10, posy+hoch, posx, posy+hoch);
g.drawLine(posx-10, posy+hoch/2, posx, posy+hoch/2);
g.drawLine(posx-10, posy, posx, posy);
}
// der "zurück"-Knopf ruft wieder die Auswertung auf
public boolean action(Event evt, Object arg) {
if (evt.target == but4) f.wertung();
return true;
}
// wird das Fenster verändert, geschieht korrel() einfach noch mal
public void paint(Graphics g) {
korrel();
requestFocus();
}
}
// dies ist das kleine Muster-Rechteck im Farb-Fenster
// ich hab es nicht geschafft, die Anweisungen zum Zeichnen zu realisieren,
// ohne eine eigene Klasse für dieses Objekt anzulegen, jetzt kann man
// indirekt die draw..() und fill..()-Methoden hierfür aufrufen
class CanEi extends Canvas {
Graphics g;
Fenster f;
CanEi(Fenster f) {
this.f = f;
}
void ini() {
g = getGraphics();
}
void fillOval(Color c, int d) {
g.setColor(c);
g.fillOval((size().width-d)/2, (size().height-d)/2, d, d);
}
void fillRect(Color c) {
g.setColor(c);
g.fillRect(0,0,80,80);
}
public void paint(Graphics g) {
fillRect(f.bBuf);
fillOval(f.cBuf, f.dBuf);
}
}
// Wird nur Thread.sleep() aufgerufen, so wartet das Programm anstandslos sine Zeit,
// aber das Schlafen geschieht nicht in einem Thread (nebenläufig). Das heißt, dass
// während dieser Zeit das Applet keine anderen Aktivitäten ausführen kann, zum Beispiel
// Tastatur-Ereignisse oder anstehende paint-Befehle.
// Da aber in jeder Klasse nur eine run()-Methode frei ist, gibt es hier die Warte-Klasse,
// nur damit sleep() auch wirklich als Thread ausgeführt wird.
// Später kehrt die Steuerung je nach Ziel-Schlüssel wieder zurück, wo sie herkam.
class Warte extends Thread {
static Thread t;
static Fenster f;
static int ziel;
static int dauer;
// Parameter werden übergeben, mit run() kann man das nicht
public static void warte(Fenster f_in, int ziel_in, int dauer_in) {
f = f_in;
ziel = ziel_in;
dauer = dauer_in;
Warte w = new Warte();
t = new Thread(w);
t.start();
}
public void run() {
try {Thread.sleep(dauer);}
catch (Exception e) { }
if (ziel==1) f.weiter1();
if (ziel==3) f.weiter3();
}
}
/* Die Dialogfenster sind nicht von der Standard Klasse "Dialog", sondern eigenständige
Frames "DialogEi" und geben ihre Events wohldefiniert weiter. Ich hatte sie nachträglich
umgewandelt, damit auch die Version JAVA 1.1 damit etwas anfangen kann. */
class DialogEi extends Frame {
Fenster f;
DialogEi(Fenster f, String str) {
super(str);
this.f = f;
}
public boolean handleEvent(Event evt) {
f.handleEvent(evt);
return false;
}
}