Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Fehler in ImageMap-Programm

0 views
Skip to first unread message

Jan Fader

unread,
Dec 9, 2003, 10:28:50 AM12/9/03
to
Hallo Leute,
ich finde in folgendem Quellcode den Fehler einfach nicht.
Es dreht sich um einen Gebäudeplan, bei dem sich beim Klick auf einzelne
Gebäude ein Popup-Menu mit den jeweiligen Stockwerken und Räume öffnen
soll (habe das im Quellcode nur exemplarisch für ein Gebäude gemacht)
Bei der Auswahl eines Raumes soll dann ein Bild des entsprechendes
Raumes angezeigt werden und beim Verlassen des Bildes soll wieder das
Applet neugezeichnet werden.

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;

public class ImageMap extends JApplet implements MouseListener
{

Image background;
Image image;

boolean mouseover=false;

Vector areas = new Vector();
Vector images = new Vector();
JPopupMenu pm1 = new JPopupMenu();
Polygon poly = new Polygon();

menuitem m1 = new menuitem("Lab1");
menuitem m2 = new menuitem("Schwarzes Brett");
menuitem m3 = new menuitem("Lab2");

Jmenu eg = new Jmenu("EG");
Jmenu og1 = new Jmenu("OG 1");
Jmenu og2 = new Jmenu("OG 2");

int current = -1;

public void init()
{
addMouseListener(this);

eg.add(m2);
og1.add(m3);
og2.add(m1);

m1.addMouseListener(new MouseAdapter()
{ public void Mouse(MouseEvent e)
{
mouseover=true;
repaint();
}
});

pm1.add(eg);
pm1.addSeparator();
pm1.add(og1);
pm1.addSeparator();
pm1.add(og2);

pm1.setBackground(Color.blue);

background = getImage(getDocumentBase(),"plan.jpg");
prepareImage(background, this);
setBackground (Color.red);
boolean ok = true;
String imageStr = "front.jpg";
if (imageStr != null)
{
image = getImage(getDocumentBase(), imageStr);
images.addElement(image);
prepareImage (image, this);
}
else
{ok = false;}
}

public void mouseReleased(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseClicked(MouseEvent e)
{

poly.addPoint(91,369);
poly.addPoint(95,397);
poly.addPoint(189,481);
poly.addPoint(218,455);
poly.addPoint(237,470);
poly.addPoint(271,444);
poly.addPoint(270,414);
poly.addPoint(289,414);
poly.addPoint(289,349);
poly.addPoint(165,260);

Point p1 = new Point(e.getX() , e.getY());
if (poly.contains(p1))
{
pm1.show(e.getComponent(),e.getX() ,e.getY());
}

}

public void mouseEntered(MouseEvent e){}
public void mousePressed(MouseEvent e){}
public void mouseMoved(MouseEvent e){}
public void mouseDragged(MouseEvent e){}

public void paint(Graphics g)
{
g.drawImage (background, 0, 0, this);
while (mouseover)
{
g.drawImage (image ,50 ,50 ,this);
}


}

class Jmenu extends JMenu
{
Jmenu()
{
setBackground(Color.LIGHT_GRAY);
}
Jmenu(String s)
{
setText(s);
}
}

class menuitem extends JMenuItem
{
menuitem()
{
setBackground(Color.LIGHT_GRAY);
}
menuitem(String s)
{
setText(s);
}

}

}


Hoffe ihr könnt mir helfen. Vielen Dank im Voraus.

Stefan Matthias Aust

unread,
Dec 10, 2003, 4:09:05 AM12/10/03
to
Jan Fader wrote:

> Image background;
> Image image;
>
> boolean mouseover=false;

Wird nicht benutzt bzw. falsch gesetzt und nie zurückgesetzt.

> Vector areas = new Vector();
> Vector images = new Vector();

List statt Vector wäre moderner

> JPopupMenu pm1 = new JPopupMenu();
> Polygon poly = new Polygon();

Nicht merken sondern jedes Mal bauen! Siehe unten...

> menuitem m1 = new menuitem("Lab1");
> menuitem m2 = new menuitem("Schwarzes Brett");
> menuitem m3 = new menuitem("Lab2");

Gaaanz schlechter Klassenname.

> Jmenu eg = new Jmenu("EG");
> Jmenu og1 = new Jmenu("OG 1");
> Jmenu og2 = new Jmenu("OG 2");

Noch schlechterer Klassenname.

> int current = -1;

Was soll diese Zeile? Variable ist unbenutzt.

> public void init()
> {

Wo ist "super.init()" ?

> addMouseListener(this);
>
> eg.add(m2);
> og1.add(m3);
> og2.add(m1);
>
> m1.addMouseListener(new MouseAdapter()
> { public void Mouse(MouseEvent e)
> {
> mouseover=true;
> repaint();
> }
> });

Was ist denn "Mouse" für eine Methode? Und warum versuchst du einen
MouseListener an das Menü für "Lab1" zu hängen?

> pm1.add(eg);
> pm1.addSeparator();
> pm1.add(og1);
> pm1.addSeparator();
> pm1.add(og2);
>
> pm1.setBackground(Color.blue);

Hm... häßliche Farbgebung...

> background = getImage(getDocumentBase(),"plan.jpg");
> prepareImage(background, this);
> setBackground (Color.red);
> boolean ok = true;

Was interessiert dieses lokale "ok"-Flag? Wird nie benutzt...

> String imageStr = "front.jpg";
> if (imageStr != null)

Diese zwei Zeilen sind auch sehr merkwürdig. Ich tippe mal, das liegt
am Zusammenstrechen. Ansonsten aber ist das extrem fragwürdig.

> {
> image = getImage(getDocumentBase(), imageStr);
> images.addElement(image);

Einfach nur "add" - ist moderner

> prepareImage (image, this);

Warum eigentlich immer prepareImage - ich bin mir sicher, das
funktioniert auch ohne. Warum brauchst du eigentlich einen Vector für
nur ein Bild? Auch ein Ergebnis des Zusammenstreichens?

> }
> else
> {ok = false;}
> }

Die Formatierung ist grausam.

> public void mouseReleased(MouseEvent e){}
> public void mouseExited(MouseEvent e){}
> public void mouseClicked(MouseEvent e)
> {
>
> poly.addPoint(91,369);
> poly.addPoint(95,397);
> poly.addPoint(189,481);
> poly.addPoint(218,455);
> poly.addPoint(237,470);
> poly.addPoint(271,444);
> poly.addPoint(270,414);
> poly.addPoint(289,414);
> poly.addPoint(289,349);
> poly.addPoint(165,260);

Du kannst doch nicht in einem Listener jedes Mal immer wieder neue
Koordinatenpaare zu dem Polygon hinzufügen!? Entweder nimmst du auch
jedes Mal ein neues Polygon (siehe obne) oder aber lass die Finger
davon! Die adds sind übrigens die langsamste Methode, wie man das
Polygon erzeugen kann...

> Point p1 = new Point(e.getX() , e.getY());

Abgesehen davon, dass p1 ein ganz schlechter Variablenname ist, das "new
Point" ist nun völlig überflüssig, denn entweder kannst du
"e.getPoint()" benutzen oder einfach "e.getX(), ..." direkt in contains.

> if (poly.contains(p1))
> {
> pm1.show(e.getComponent(),e.getX() ,e.getY());
> }

Hiergegen ist nichts zu sagen. Das funktioniert.

> }
>
> public void mouseEntered(MouseEvent e){}
> public void mousePressed(MouseEvent e){}
> public void mouseMoved(MouseEvent e){}
> public void mouseDragged(MouseEvent e){}
>
> public void paint(Graphics g)
> {
> g.drawImage (background, 0, 0, this);
> while (mouseover)
> {
> g.drawImage (image ,50 ,50 ,this);
> }

ARG!?! Eine Endlosschleife in einer paint-Methode?! Das ist schlecht,
ganz schlecht, fatal, falsch, unmöglich, tötlich, Sünde. Sei froh, dass
deine Methode zum setzen von "mouseover = true" nicht funktioniert.
Zudem, es würde eine NullPointerException geben, denn "image" wird
niemals initialisiert.

> Hoffe ihr könnt mir helfen. Vielen Dank im Voraus.

Ich kann dir sagen, dass dein Programm nicht macht was es soll. Hilft
das? Da ich das Hintergrundbild nicht habe, habe ich mal

g.setColor(Color.white);
g.drawPolygon(polygon);

in der paint()-Methode ergänzt um zu sehen, wo überhaupt man klicken
darf. Mit genügend Klicken kommt dann auch ein Menü. Da dort kein
korrekter Listener daranhängt, passiert aber nichts weiter.

Du solltest übrigens nicht auch mouseClicked achten, sondern auf
mousePressed UND mouseReleased und dann auf isPopupTrigger() prüfen.
Dann kommt das Kontextmenü auch wie gewohnt bei jedem Klick.

Aber folge auf keinem Fall deinem Plan mit der while-Schleife. Das wird
niemals funktionieren. Du kannst nicht einfach die paint-Methode
anhalten. Das würde das gesamte Applet stoppen.


bye
--
Stefan Matthias Aust // "Ist es normal, nur weil alle es tun?" -F4

Jan Fader

unread,
Dec 10, 2003, 8:24:46 AM12/10/03
to
Stefan Matthias Aust schrieb:

> Jan Fader wrote:
>
>> Image background;
>> Image image;
>>
>> boolean mouseover=false;
>
>
> Wird nicht benutzt bzw. falsch gesetzt und nie zurückgesetzt.
>
>> Vector areas = new Vector();
>> Vector images = new Vector();
>
>
> List statt Vector wäre moderner
geht aber noch und ist somit das wichtigste

>
>> JPopupMenu pm1 = new JPopupMenu();
>> Polygon poly = new Polygon();
>
>
> Nicht merken sondern jedes Mal bauen! Siehe unten...
>
>> menuitem m1 = new menuitem("Lab1");
>> menuitem m2 = new menuitem("Schwarzes Brett");
>> menuitem m3 = new menuitem("Lab2");
> Gaaanz schlechter Klassenname.
geändert *G*

>
>> Jmenu eg = new Jmenu("EG");
>> Jmenu og1 = new Jmenu("OG 1");
>> Jmenu og2 = new Jmenu("OG 2");
> Noch schlechterer Klassenname.
ebenfalls geändert

>
>> int current = -1;
> Was soll diese Zeile? Variable ist unbenutzt.
Gestrichen. war noch aus vorheriger idee da.

>
>> public void init()
>> {
>
>
> Wo ist "super.init()" ?
ergänzt

>
>> addMouseListener(this);
>> eg.add(m2);
>> og1.add(m3);
>> og2.add(m1);
>> m1.addMouseListener(new MouseAdapter()
>> { public void Mouse(MouseEvent e)
>> {
>> mouseover=true;
>> repaint();
>> }
>> });
>
>
> Was ist denn "Mouse" für eine Methode? Und warum versuchst du einen
> MouseListener an das Menü für "Lab1" zu hängen?

Mouse ist natürlich keine Methode, da fehlt was.
Ich hab versucht den MouseListener an das MenuItem von Lab1 zu hängen,
damit er bei einem klick auf Lab1 das Bild des Labors anzeigt.


>
>> pm1.add(eg);
>> pm1.addSeparator();
>> pm1.add(og1);
>> pm1.addSeparator();
>> pm1.add(og2);
>> pm1.setBackground(Color.blue);
>
>
> Hm... häßliche Farbgebung...

extra dir zu liebe geändert ;)


>
>> background = getImage(getDocumentBase(),"plan.jpg");
>> prepareImage(background, this);
>> setBackground (Color.red);
>> boolean ok = true;
>
>
> Was interessiert dieses lokale "ok"-Flag? Wird nie benutzt...

auch noch aus vorheriger Idee vorhanden


>
>> String imageStr = "front.jpg";
>> if (imageStr != null)
>
>
> Diese zwei Zeilen sind auch sehr merkwürdig. Ich tippe mal, das liegt
> am Zusammenstrechen. Ansonsten aber ist das extrem fragwürdig.

Treffer. Gestrichen


>
>> {
>> image = getImage(getDocumentBase(), imageStr);
>> images.addElement(image);
>
>
> Einfach nur "add" - ist moderner

Recht hast, geändert


>
>> prepareImage (image, this);
>
>
> Warum eigentlich immer prepareImage - ich bin mir sicher, das
> funktioniert auch ohne. Warum brauchst du eigentlich einen Vector für
> nur ein Bild? Auch ein Ergebnis des Zusammenstreichens?

Stimmt geht auch ohne, prepareImage.
das mit dem Vector ist auch geändert.


>
>> }
>> else
>> {ok = false;}
>> }
>
>
> Die Formatierung ist grausam.

wieso die formatierung stammt so von meinem c++ dozenten.
ist bei einzelnenen anweisungen so ok, auch gestrichen.
wenn das so weiter geht, bin ich ja nur noch am streichen *G*


>
>> public void mouseReleased(MouseEvent e){}
>> public void mouseExited(MouseEvent e){}
>> public void mouseClicked(MouseEvent e)
>> {
>> poly.addPoint(91,369);
>> poly.addPoint(95,397);
>> poly.addPoint(189,481);
>> poly.addPoint(218,455);
>> poly.addPoint(237,470);
>> poly.addPoint(271,444);
>> poly.addPoint(270,414);
>> poly.addPoint(289,414);
>> poly.addPoint(289,349);
>> poly.addPoint(165,260);
>
>
> Du kannst doch nicht in einem Listener jedes Mal immer wieder neue
> Koordinatenpaare zu dem Polygon hinzufügen!? Entweder nimmst du auch
> jedes Mal ein neues Polygon (siehe obne) oder aber lass die Finger
> davon! Die adds sind übrigens die langsamste Methode, wie man das
> Polygon erzeugen kann...

also ich hab das polygon umbenannt, da der variablename doof gewählt
war. und das hinzufügen der punkte erfolgt jetzt in der init-methode.
ob langsam oder nicht ist egal.


>
>> Point p1 = new Point(e.getX() , e.getY());
>
>
> Abgesehen davon, dass p1 ein ganz schlechter Variablenname ist, das "new
> Point" ist nun völlig überflüssig, denn entweder kannst du
> "e.getPoint()" benutzen oder einfach "e.getX(), ..." direkt in contains.

stimmt. verbessert


>
>> if (poly.contains(p1))
>> {
>> pm1.show(e.getComponent(),e.getX() ,e.getY());
>> }
>
>
> Hiergegen ist nichts zu sagen. Das funktioniert.

Stimmt. Juchu endlich mal was das geht *freu*


>
>> }
>> public void mouseEntered(MouseEvent e){}
>> public void mousePressed(MouseEvent e){}
>> public void mouseMoved(MouseEvent e){}
>> public void mouseDragged(MouseEvent e){}
>>
>> public void paint(Graphics g)
>> {
>> g.drawImage (background, 0, 0, this);
>> while (mouseover)
>> {
>> g.drawImage (image ,50 ,50 ,this);
>> }
>
>
> ARG!?! Eine Endlosschleife in einer paint-Methode?! Das ist schlecht,
> ganz schlecht, fatal, falsch, unmöglich, tötlich, Sünde. Sei froh, dass
> deine Methode zum setzen von "mouseover = true" nicht funktioniert.
> Zudem, es würde eine NullPointerException geben, denn "image" wird
> niemals initialisiert.

Ok, aber es wäre eine möglichkeit gewesen.
und image wird initalisiert


>
>> Hoffe ihr könnt mir helfen. Vielen Dank im Voraus.
>
>
> Ich kann dir sagen, dass dein Programm nicht macht was es soll. Hilft
> das?

Hätte ich nie bemerkt, wenn du es nicht gesagt hättest *fg*


>Da ich das Hintergrundbild nicht habe, habe ich mal
>
> g.setColor(Color.white);
> g.drawPolygon(polygon);
>
> in der paint()-Methode ergänzt um zu sehen, wo überhaupt man klicken
> darf. Mit genügend Klicken kommt dann auch ein Menü. Da dort kein
> korrekter Listener daranhängt, passiert aber nichts weiter.

Wieso genügend, einmal klicken reicht.


>
> Du solltest übrigens nicht auch mouseClicked achten, sondern auf
> mousePressed UND mouseReleased und dann auf isPopupTrigger() prüfen.
> Dann kommt das Kontextmenü auch wie gewohnt bei jedem Klick.

also auf mousePressed und mouseReleased achte ich jetzt, aber
isPopupTrigger ist nicht sinn der sache, da das Popup bei einem
Linksklick erscheinen soll.


>
> Aber folge auf keinem Fall deinem Plan mit der while-Schleife. Das wird
> niemals funktionieren. Du kannst nicht einfach die paint-Methode
> anhalten. Das würde das gesamte Applet stoppen.

Bessere Vorschläge??
>
>
> bye
CU. Achja hier nochmal der verbesserte, gekürzte Quellcode.

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;

public class ImageMap extends JApplet implements MouseListener
{

Image background;
Image image;

Vector areas = new Vector();


Vector images = new Vector();

JPopupMenu pm1 = new JPopupMenu();

Polygon gebäude2 = new Polygon();

JMenuItem m1 = new JMenuItem("Lab1");
JMenuItem m2 = new JMenuItem("Schwarzes Brett");
JMenuItem m3 = new JMenuItem("Lab2");

JMenu eg = new JMenu("EG");
JMenu og1 = new JMenu("OG 1");
JMenu og2 = new JMenu("OG 2");


public void init()
{
super.init();

gebäude2.addPoint(91,369);
gebäude2.addPoint(95,397);
gebäude2.addPoint(189,481);
gebäude2.addPoint(218,455);
gebäude2.addPoint(237,470);
gebäude2.addPoint(271,444);
gebäude2.addPoint(270,414);
gebäude2.addPoint(289,414);
gebäude2.addPoint(289,349);
gebäude2.addPoint(165,260);

addMouseListener(this);

eg.add(m2);
og1.add(m3);
og2.add(m1);

pm1.add(eg);
pm1.add(og1);
pm1.add(og2);


background = getImage(getDocumentBase(),"plan.jpg");

setBackground (Color.red);
image = getImage(getDocumentBase(), "front.jpg");
}

public void mouseReleased(MouseEvent e)
{
if (gebäude2.contains(e.getX(), e.getY()))
{
pm1.show(e.getComponent(),e.getX() ,e.getY());


}
}
public void mouseExited(MouseEvent e){}
public void mouseClicked(MouseEvent e){}

public void mouseEntered(MouseEvent e){}
public void mousePressed(MouseEvent e)
{

if (gebäude2.contains(e.getX(), e.getY()))
{
pm1.show(e.getComponent(),e.getX() ,e.getY());

Stefan Matthias Aust

unread,
Dec 10, 2003, 8:59:09 AM12/10/03
to
Jan Fader wrote:

>> Hm... häßliche Farbgebung...
>
> extra dir zu liebe geändert ;)

So liebe ich das...

>> Die Formatierung ist grausam.
>
> wieso die formatierung stammt so von meinem c++ dozenten.

Dann bestelle einen schönen Gruß, aber wer in Rom ist, sollte es wie die
Römer treiben, will sagen, bei jeder Sprache sollten man sich den
sprachspezifischen Konventionen beugen und Sun hat mit den Empfehlungen
bzgl. der Formatierung und Benennung von Programmen der Community einen
guten Dienst geleistet und man sollte sich zugunsten allgemeiner
Lesbarkeit an diese Konventionen halten.

> ist bei einzelnenen anweisungen so ok, auch gestrichen.
> wenn das so weiter geht, bin ich ja nur noch am streichen *G*

Du beginnst zu erkennen, was einen guten Programmierer ausmacht :)

> also ich hab das polygon umbenannt, da der variablename doof gewählt
> war. und das hinzufügen der punkte erfolgt jetzt in der init-methode.
> ob langsam oder nicht ist egal.

An der neuen Stelle schon, in einem Event Listener weniger.

>> in der paint()-Methode ergänzt um zu sehen, wo überhaupt man klicken
>> darf. Mit genügend Klicken kommt dann auch ein Menü. Da dort kein
>> korrekter Listener daranhängt, passiert aber nichts weiter.
>
> Wieso genügend, einmal klicken reicht.

Bei mir gings nur bei jedem zweiten Klick, aber ich habe nicht weiter
darüber nachgedacht, warum das wohl so ist, weil mouseClicked eh nicht
der richtige Event IMHO ist.

> also auf mousePressed und mouseReleased achte ich jetzt, aber
> isPopupTrigger ist nicht sinn der sache, da das Popup bei einem
> Linksklick erscheinen soll.

Na gut, dann eben ein eigenes ungewöhnliches feel...

>> Aber folge auf keinem Fall deinem Plan mit der while-Schleife. Das
>> wird niemals funktionieren. Du kannst nicht einfach die paint-Methode
>> anhalten. Das würde das gesamte Applet stoppen.
>
> Bessere Vorschläge??

Möge ein anderer Vortreten und übernehmen... die Lösung scheint mir
sehr einfach.

0 new messages