Hilfe bei BlueJ-Projekt

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Hilfe bei BlueJ-Projekt

    Hi, ich bin absulut verzweifelt. Wir sollen in der Schule ein kleines Spiel Programieren und da ich mit Computersprachen und Programierung generell nicht so gut zurecht komme, ist das für mich richtig schwer. Zudem habe ich auf Grund eines längeren Klinikaufenthaltes viele Informatikstunden verpasst, was aber nicht berücksichtigt wird...
    Ich habe mich schon einigermaßen durchgebissen, nur habe ich noch folgende Probleme:
    Ich schaffe es einfach nicht, einen Punkt zu animieren, der durch Zufall an einem Punkt am Rand (Spielfeld 600x600) zur Mitte hin läuft. it er in der Mitte angekommen, soll dieser verschwinden, klickt man ihn vorher an, so verschwindet er auch. Das er verschwindet, wenn er in der Mitte ist und das verschwinden beim klicken krieg ich noch hin. Aber das er zufällig am Rand auftaucht und sich mit Zufälliger geschwindigkeit in die Mitte bewegt ist ein Problem für mich...
    Zwar hat uns unser Lehrer einiges vorgegeben, wie zum Beispiel die ganzen Animationsmanager oder die Klasse, die das Spiel startet. Doch leider haben wir diese nie richtig besprochen und ich bin in meiner Klasse nicht die einzige, die Schwierigkeiten nun hat =(
    Klar, ich könnt auch einfach meinen Lehrer fragen, aber da wir mit 36 Schülern eine verdammt große Klasse sind ist es ein richtiger Kampf um den Leher, so das man kaum eine chanche hat richtige hilfe von ihm zu bekommen...

    Lange rede kurzer Sinn. Meine Bitte:
    Hat jemand eine idee, wie man einen Punkt animiert, der zufällig am rand erscheint und mit zufälliger geschwindigkeit zur Mitte wandert?


    (und keine Sorge, mein lehrer hat uns erlaubt für Sachen wo wir absulut nicht weiterkommen fremdhilfe anzunehmen...)

    ich danke schon mal im vorraus und hoffe auf Hilfe (und das ich das Thema auch im richtigen bereich gelegt habe xD )
    lg Lailan
  • Nun ja, ich kenne ja jetzt dein bestehendes Programm nicht. Ich will aber anhand der Informationen so viele Hinweise wie möglich geben.

    Für Zufälliges ist die Klasse java.util.Random gut. Ein Objekt dieser Klasse erzeugst du am einfachsten an einem statischen Klassen-Attribut. Dann kannst du dir von dort Zufallszahlen holen. (Wichtig: Das Random-Objekt nicht ständig neu erzeugen)
    Beispiel:

    Quellcode

    1. public class MainClass
    2. {
    3. public final static Random RANDOM_GENERATOR = new Random();
    4. public void myMethod()
    5. {
    6. System.out.println(RANDOM_GENERATOR.nextInt());
    7. System.out.println(RANDOM_GENERATOR.nextInt());
    8. System.out.println(RANDOM_GENERATOR.nextInt());
    9. }
    10. }
    Alles anzeigen


    Wenn du eine bestimmte Zahl aus einem bestimmten Zahlenbereich haben willst, dann die der Modulo-Operator % wichtig. Das ist vereinfacht gesagt der Rest bei einer Division (de.wikipedia.org/wiki/Modulo).
    Beispiel:

    Quellcode

    1. public class MainClass
    2. {
    3. public final static Random RANDOM_GENERATOR = new Random();
    4. public void myMethod()
    5. {
    6. System.out.println(RANDOM_GENERATOR.nextInt()%600); // zwischen inclusive 0 und inclusive 599
    7. System.out.println((RANDOM_GENERATOR.nextInt()%600)+1); // zwischen inclusive 1 und inclusive 600
    8. }
    9. }


    Hilft dir das erstmal weiter?

    Ansonsten sind konkrete Probleme leichter zu beantworten.
  • Noch was, was mir grade noch einfällt.
    Das schöne an Java ist, das man eigentlich nur wissen muss wie die Methoden einer Klasse heißen (bzw wie sie aufgerufen werden) und WAS sie machen. Also was rein kommt und was raus kommt. WIE sie das machen, kann einem bei einer bereits existierenden Klasse herzlich egal sein. Ich nehme an, das ist der Grund warum ihr die Animations-Klasse nicht näher besprochen habt.
    Ohne die Klasse, bzw. ihre Methoden, jetzt wirklich zu kennen, vermute ich jetzt einfach mal das die Klasse Animation eine Methode hat die "public void setzePosition(int x, inty)" oder so ähnlich heißt. Dann sollte dein erstes Ziel erstmal sein, den Kreis von einem bestimmten Punkt am Rand (möglichst einen den du einfach eingeben kannst) in die Mitte laufen zu lassen. Dazu kann die Methode setzePosition in Kombination mit einer Schleife durchaus hilfreich sein.
    Wenn das klappt, wäre der nächste Schritt den Startpunkt zufällig zu wählen. Dazu hat Hafner ja schon was geschrieben.

    Ansonnsten kann man dir sicher besser helfen wenn du dein Problem etwas konkretisierst.

    Zudem kann ich mir nicht vorstellen, dass dein Lehrer etwas dagegen hat, wenn du dich auch ausserhalb des Unterrichts schlau machst. Es ist ja nicht so das wir dir hier einfach eine Komplettlösung hin legen. Das können wir auch garnicht so einfach, dazu kennen wir das Projekt bei weitem nicht gut genug. Vielmehr versuchen wir dir die Sachen so zu erklären, das du hinterher selbst auf die Lösung kommst.
  • Zuerstmal, danke für die Antworten^^

    Und zu der Schleife: Was genau meinst du damit? Bedeutet das, ich soll einen Punkt animieren, der durch abziehen von x und y bis zur Mitte wandernt und dann durch eine Schleifen-Funktion immer wieder nue animiert wird und zur Mitte geht? Für den Anfang ist das denk ich das beste, ich werde es auf jeden fall vorest versuchen, aber gibt es eigentlich eine Funktion, bei der ich (ich kenne sowas nur aus nem Flash-Video-Maker) einen Anfangspunkt und einen Endpunkt makieren kann und dann wandert der Punkt automatisch zum ziel? Weil weitläufig gesehen soll der Punkt ja von verscheidenen Seiten auf die Mitte zu gehen. Das hieße auch, dass ich immer andere x und y werte abziehen muss, bis der Punkt die Mitter erreicht habe. Müsste ich also für jeden möglichen Punkt einzelnd ausrechnen, wie er zur Mitte gelangen würde? 8|


    Aber ich frage mich auch warum man drei mal:


    System.out.println(RANDOM_GENERATOR.nextInt());
    System.out.println(RANDOM_GENERATOR.nextInt());
    System.out.println(RANDOM_GENERATOR.nextInt());


    schreiben muss? Gibt es dafür nen besonderen Grund oder würde nicht einmal reichen?

    Mein(e) Problem(e) konkreter zu formulieren ist ein wenig schwer, da ich mich gänzlich überfordert fühle. Wir haben 13 Klassen, von denen vier mit Animation zu tun haben (AnimationsManager (ist abstract(was bedeutet es eigentlich wenn eine Klasse abstract ist?)), ListeAnimierterObjekte, AnimiertesObjekt und AnimationsJPanel) und noch viele weitere mit unendlich vielen Verknüpfungen. Mein Grund Problem ist, das ich teilweise nicht weiß wo ich ansetzten soll.

    Ich habe aber auch eine Klasse "Kugel" folglich müsste ich dort die Startwerte einsetzen können. Vorerst ohne Zufallszahl. Hier einen Ausschnitt aus der Klasse "Kugel"

    _________________________________________________________

    public class Kugel extends AnimiertesObjekt
    {
    public double x, y, r;
    public Color farbe;
    public int vx=5, vy=4;

    /**
    * Konstruktor mit Startwerten
    */
    public Kugel(double x, double y, double r, Color farbe)
    {
    this.x=x;
    this.y=y;
    this.r=r;
    this.farbe=farbe;
    }

    /**
    * Ball mit standard-Werten
    */
    public Kugel()
    {
    this(100,100,8,Color.BLUE);

    }


    _________________________________________________________

    Dazu habe ich 2 Fragen.

    1. Was hat die Funktion public Kugel( double x, [...] ) für eine Bedeutung und was bewirkt sie?

    2. Was genau ist der Unterschied zwischen public Kugel (double x, [...]) und public Kugel()?



    Oh, und momentan ist ein weiteres Problem, dass mir zwar gesagt wird, das mein Hintergrundbild erfolgreich geladen wird, aber wenn ich das Spiel starte wird es nicht animiert, also ich sehe nichts.
    Aber bei allem durchforsten der Animations Klassen habe ich keine Funktion gesehen, die meiner Meinung eine Animation des Bildes bewirken könnte. Wie würde diese aussehen, oder kann man das nicht einheitlich sagen? Bzw, wonach müsste ich eigentlich suchen, also, nach was für einer Art von Funktion?
    ...

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von Lailan ()

  • 1. Ganz tief durchatmen.
    2. RANDOM_GENERATOR.nextInt() hat dir in meinem Beispiel eine zufällige Zahl vom Typ int erzeugt (Was für Arten von zufälligen Zahlen man noch damit erstellen kann, kannst du hier nachlesen: java.sun.com/javase/6/docs/api/java/util/Random.html).
    3. System.out.println(...) ist nur eine einfache Ausgabe auf der Konsole. Damit kann man sich recht einfach ein paar Informationen anzeigen lassen. Das ist oftmals recht hilfreich. Allerdings weiß ich nicht ob man bei BlueJ die Konsole sieht. Wenn nein, ist das sehr schade.
    4. Ich habe die Zufallszahl nur deswegen drei mal mit System.out.println(...) ausgegeben um dir zu demonstrieren das die Zahlen jedes mal anders, also tatsächlich zufällig, sind.
    5. Ich setze mal voraus, dass du weißt, was ein Objekt und was eine Klasse ist. Mit einer abstrakten Klasse kannst du keine Objekte initialisieren. Gewöhnlicherweise erbt eine nicht-abstrakte Klasse von dieser abstrakten Klasse, die die in der abstrakten Klasse noch fehlenden Dinge zu Ende implementiert. Diese kannst du dann initialisieren. Beispiel:

    Quellcode

    1. public abstract class MyAbstractClass
    2. {
    3. public abstract void methodeDieNICHTInDerAbstrakenKlasseImplementiertIst();
    4. public void methodeDieInDerAbstrakenKlasseImplementiertIst()
    5. {
    6. // hier wird irgend etwas gemacht. Z.B. wird auch die methodeDieNICHTInDerAbstrakenKlasseImplementiertIst() aufgerufen.
    7. }
    8. }

    Quellcode

    1. MyAbstractClass myObject = new MyAbstractClass(); // geht nicht, da MyAbstractClass abstract ist.

    Quellcode

    1. public class MyClass extends MyAbstractClass // hier wird von der abstrakten Klasse geerbt
    2. {
    3. public void methodeDieNICHTInDerAbstrakenKlasseImplementiertIst()
    4. {
    5. // diese Methode MUSS nun implementiert werden, sonst kann man nicht compilieren.
    6. }
    7. public void andereMethode()
    8. {
    9. // irgend eine andere Methode
    10. }
    11. }
    Alles anzeigen

    Quellcode

    1. MyAbstractClass myObject = new MyClass(); // geht
    2. myObject.methodeDieInDerAbstrakenKlasseImplementiertIst(); // geht
    3. myObject.methodeDieNICHTInDerAbstrakenKlasseImplementiertIst(); // geht
    4. myObject.andereMethode(); // geht nicht, da der Typ von der Variable myObject MyAbstractClass ist. ( Hat nicht direkt etwas mit abstrakten Klassen zu tun sondern mit Vererbung im allgemeinen.)

    Quellcode

    1. MyClass myObject = new MyClass(); // geht
    2. myObject.methodeDieInDerAbstrakenKlasseImplementiertIst(); // geht
    3. myObject.methodeDieNICHTInDerAbstrakenKlasseImplementiertIst(); // geht
    4. myObject.andereMethode(); // geht

    Quellcode

    1. MyAbstractClass myObject = new MyClass(); // geht
    2. myObject.methodeDieInDerAbstrakenKlasseImplementiertIst(); // geht
    3. myObject.methodeDieNICHTInDerAbstrakenKlasseImplementiertIst(); // geht
    4. if (myObject instanceof MyClass)
    5. {
    6. ((MyClass)myObject).andereMethode(); // geht
    7. // So etwas nennt man im übrigen einen Cast, wenn man eine allgemeinere Klasse auf eine speziellere "herrunterbricht"
    8. // Das dient nur zum Verständnis und muss nicht unbedingt in deinem Programm Verwendung finden.
    9. }

    6. Zu deinem ersten und zweiten Punkt: Die Methode (In Java nennt man Funktionen Methoden) die du erwähnst ist ein sogenannter Konstruktor. Man erkennt ihn daran, dass er genauso heißt wie die Klasse und keinen Rückgabetyp hat. Ein Konstruktor wird zum erzeugen eines Objektes dieser Klasse verwendet. Das hatten wir oben schon einmal mit dem new-Operator. Beispiel:

    Quellcode

    1. Kugel myKugel = new Kugel(1.56, 12.1, 30.0, Color.RED);

    Nun hast du eine Kugel mit den Gewünschten Eigenschaften in der Variable myKugel gespeichert.
    Warum hat nun meine Klasse oben keinen Konstruktor und ich kann trotzdem new MyClass() aufrufen? Ganz einfach. Wenn der Konstruktor fehlt, ist das das selbe wie das:

    Quellcode

    1. public class MyClass extends MyAbstractClass // hier wird von der abstrakten Klasse geerbt
    2. {
    3. public MyClass()
    4. {
    5. }
    6. ...
    7. }

    Die Kugel-Klasse hat auch noch einen anderen Konstruktor: "public Kugel()". Dieser ermöglicht es weiterhin "new Kugel();" aufzurufen. Wenn du dir diesen Konstruktor genauer anschaust, dann stellst du fest, dass er den ersten Konstruktor mit festgelegten Werten aufruft: "this(100,100,8,Color.BLUE);".
  • Oh jeh, das gibt viel Tipp-Arbeit... Na dann wollen wir mal, ohne solche Fragen hätt ichs schließlich auch nicht verstanden damals...

    Lailan schrieb:

    ...
    Und zu der Schleife: Was genau meinst du damit? Bedeutet das, ich soll einen Punkt animieren, der durch abziehen von x und y bis zur Mitte wandernt und dann durch eine Schleifen-Funktion immer wieder nue animiert wird und zur Mitte geht? Für den Anfang ist das denk ich das beste, ich werde es auf jeden fall vorest versuchen, aber gibt es eigentlich eine Funktion, bei der ich (ich kenne sowas nur aus nem Flash-Video-Maker) einen Anfangspunkt und einen Endpunkt makieren kann und dann wandert der Punkt automatisch zum ziel? Weil weitläufig gesehen soll der Punkt ja von verscheidenen Seiten auf die Mitte zu gehen. Das hieße auch, dass ich immer andere x und y werte abziehen muss, bis der Punkt die Mitter erreicht habe. Müsste ich also für jeden möglichen Punkt einzelnd ausrechnen, wie er zur Mitte gelangen würde? 8|

    Wenn du bereits eine Funktion hast die den ball zur Mitte laufen lässt, kannst du dir das natürlich spaaren.
    Fals nicht, wäre es doch wahnsinnig aufwändig den Ball einen Pixel weiter zur mitte Wandern zu lassen und dann den Code nochmal wiederholen zu müssen. Da wäre eine Schleife ganz praktisch die den Code so lange wiederholt bis der Ball die Mitte erreicht hat.
    Wie der Ball zur Mitte kommt muss folglich in der Schleife stehen, und ich denke das dürfte der schwierigste teil sein. Sinnvoll wäre ein Code der den Ball immer zur Mitte lotst, egal wo der Ball ist.
    Muss der Ball denn auf einer graden Linie zur Mitte?
    Wenn nicht ist das mit den unterschiedlichen X und Y Werten doch kein Problem. Du änderst beide Werte nur so lange bis einer mit der Mitte auf einer Linie liegt, und danach nurnoch den anderen.
    Wenn es doch eine grade Linie sein soll, musst du dir überlegen wie du die Schritte so aufteilst, das der kleinere Wert sich über die ganze Strecke aufteilt.

    Lailan schrieb:


    Aber ich frage mich auch warum man drei mal:

    Quellcode

    1. System.out.println(RANDOM_GENERATOR.nextInt());
    2. System.out.println(RANDOM_GENERATOR.nextInt());
    3. System.out.println(RANDOM_GENERATOR.nextInt());

    schreiben muss? Gibt es dafür nen besonderen Grund oder würde nicht einmal reichen?

    Das war lediglich ein Beispiel das dir zeigen sollte wie man eine Zufallszahl aufruft, ohne für jede Zahl einen neuen Generator zu erzeugen. Dieses Beispiel liefert dir 3 Zufallszahlen, der Aufruf dafür ist RANDOM_GENERATOR.nextInt() und den Generator erzeugen kannst du mit public final static Random RANDOM_GENERATOR = new Random();.

    Lailan schrieb:


    Mein(e) Problem(e) konkreter zu formulieren ist ein wenig schwer, da ich mich gänzlich überfordert fühle. Wir haben 13 Klassen, von denen vier mit Animation zu tun haben (AnimationsManager (ist abstract(was bedeutet es eigentlich wenn eine Klasse abstract ist?)), ListeAnimierterObjekte, AnimiertesObjekt und AnimationsJPanel) und noch viele weitere mit unendlich vielen Verknüpfungen. Mein Grund Problem ist, das ich teilweise nicht weiß wo ich ansetzten soll.

    Wenn man so garnicht weiß wo man ansetzen soll, hilft es oft das Problem in kleine Häppchen zu zerlegen und sich erstmal an das kleinste dieser Häppchen zu wagen. Ist das immernoch zu kompliziert, teilt man das eben nochmal auf.
    Hat man ein Teil des Problems gelöst, zeigen sich oft für den Rest ganz neue Möglichkeiten. Außerdem steigert es das Ego und man wird sicherer.

    Was die Abstrakte Klasse an geht (Ich hoffe ich erzähl jetzt hier kein Dummfug, is nämlich n weilchen her das ich mich mit Vererbung beschäftigt habe. Wenn das jetzt Blödsin ist, bitte berichtigen!):
    Eine abstrakte Klasse ist eine Klasse bei der es keinen Sinn macht daraus ein Objekt zu machen. Diese Klasse fasst lediglich einige Grund-Funktionen und Eigenschaften zusammen, die später mittels Vererbung auf mehrere andere Klassen übertragen werden.

    Lailan schrieb:


    Ich habe aber auch eine Klasse "Kugel" folglich müsste ich dort die Startwerte einsetzen können. Vorerst ohne Zufallszahl. Hier einen Ausschnitt aus der Klasse "Kugel"

    ________________________________________________________

    Quellcode

    1. public class Kugel extends AnimiertesObjekt
    2. {
    3. public double x, y, r;
    4. public Color farbe;
    5. public int vx=5, vy=4;
    6. /**
    7. * Konstruktor mit Startwerten
    8. */
    9. public Kugel(double x, double y, double r, Color farbe)
    10. {
    11. this.x=x;
    12. this.y=y;
    13. this.r=r;
    14. this.farbe=farbe;
    15. }
    16. /**
    17. * Ball mit standard-Werten
    18. */
    19. public Kugel()
    20. {
    21. this(100,100,8,Color.BLUE);
    22. }
    Alles anzeigen

    _________________________________________________________

    Dazu habe ich 3 Fragen.

    1. Was hat die Funktion public Kugel( double x, [...] ) für eine Bedeutung und was bewirkt sie?

    Das ist der Konstruktor. Sobald du ein Objekt der Klasse Kugel erzeugst, wird der darin befindliche Code ausgeführt. Was in den Klammern steht sind die Parameter die der Funktion übergeben werden. Hier macht sie nichts anderes als die übergebenen Parameter in den Instanzvariablen zu speichern. Was hier ein bischen blöd gelöst ist, dass die Parameter und die Instanzvariablen den gleichen Namen haben. Das ist zwar durchaus so Standard, aber bis ich verstanden hatte was da passiert, fand ich das damals sehr verwirrend.

    Lailan schrieb:


    2. Was genau ist der Unterschied zwischen public Kugel (double x, [...]) und public Kugel()?

    Beides sind Konstruktoren für die Klasse Kugel, aber der erste erwartet Parameter, der zweite nicht. Der zweite Konstruktor geht von Standard-Werten aus, die bereits eingetragen sind. Wenn du einfach nur ein Kugel-Objekt erzeugen willst, dann kannst du den zweiten aufrufen, und das Objekt wird mit den angegebenen Parametern generiert. Willst du die Parameter selbst übergeben, musst du die erste aufrufen.
    Hier auch wieder ein bischen Blöd gelöst ist, das der zweite Konstruktor den ersten aufruft. Zum lernen find ich sowas immer etwas verwirrend, später spart man sich auf die Art ne menge Schreibarbeit.

    Lailan schrieb:


    Oh, und momentan ist ein weiteres Problem, dass mir zwar gesagt wird, das mein Hintergrundbild erfolgreich geladen wird, aber wenn ich das Spiel starte wird es nicht animiert, also ich sehe nichts.
    Aber bei allem durchforsten der Animations Klassen habe ich keine Funktion gesehen, die meiner Meinung eine Animation des Bildes bewirken könnte. Wie würde diese aussehen, oder kann man das nicht einheitlich sagen? Bzw, wonach müsste ich eigentlich suchen, also, nach was für einer Art von Funktion?
    ...

    Leider kann man das so pauschal nicht sagen, da die Klassen die ihr da verwendet ja nicht in der Öffentlichen Klassenbibliothek zu finden sind. Ich vermute mal das euer Lehrer die entweder selbst geschrieben hat, oder aus irgendeinem Lehrer-Vorbereitungs-Dingsbums hat. Da bleibt eigentlich nur suchen, und hoffen das der Quelltext gut kommentiert ist.
    Sollte letzteres der Fall sein, kann dir folgendes evtl beim Suchen etwas helfen. Ruf mal bei BlueJ eine Klasse auf und wähle dann oben Rechts in dem Dropdown-Menü statt Quelltext mal die Option Dokumentation. Wenn die Klasse vernünftig dokumentiert ist, dürfte das etwas übersichtlicher sein um nach brauchbaren Methoden zu suchen.

    HTH
    Look

    Edith sagt: Mist man sollte halt nicht, während man einen Post schreibt, noch was zu essen organisieren, dann braucht man einfach zu lange...
  • Wow, danke für das Fingerwundtippen um mir weiter zu helfen! :D

    Also, ich hab nun endlich einen sich bewegenden Ball. Ich denke, das er in die Mitte muss ist nicht wirklich wichtig, da dreh ich einfach was an den Spielregeln^^
    Und die Sache mit dem Hintergrundbild is im nachhinein gesehn eine winzige Lapalie gewesen x)
    Habe einfach vergessen, die "Let's go" animation animieren zu lassen, während doch gleichzeitig das Spiel erst läd und startet wenn diese auftaucht...
    Manchmal lohnt sich 5 mal gucken eben doch...!

    "abstract" ist also dafür da, das man einige Sachen nicht 100 mal schreiben muss und mehrere Klassen darauf zurückgreifen können?


    Meine nächste Hürde ist es nun, die Kugel bei Klick verschwinden zu lassen. Doch da schon haperts es mir an dem Klick...(alles gar nich so leicht wie man denkt =/ )
    Wie mache ich bemerkbar, dass ich auf eine bestimmte Stelle geklickt habe? Also, wie leite ich die true or false abfrage ein ob die Kugel dort ist? Gibt es dafür einen bestimmten befehl? Der meine Mausklicks bemerkbar macht? Denn zZ passiert nichts wenn ich auf das Feld klicke (verständlicher weise). Aber bei den "Start" und "Pause" Buttons wird eine Aktion angeleitet...(ebenfals vorgegeben)
    Ich habe also zum wiederholtem mal besagte, vorgegebenen Klassen durchgeforstet und bin dabei immer wieder auf "protected void" gestoßen. Zwar hege ich leichte Zweifel, dass das ist, was ich brauche um meine Klicks "bemerkbar" zu machen...(oder?)...aber dennoch würde mich interessieren, wofür "protected" steht.
  • protected ist wie public und private einfach nur eine Sichtbarkeitseinstufung der Attribute, Klassen oder Methoden:
    public ist überall zugreifbar.
    private nur in der Klasse selbst.
    protected in allen Unterklassen und allen Klassen die im selben Paket sind.

    void bedeutet einfach nur, dass die Methode nichts zurück gibt. Ansonsten steht hier der Rückgabetyp.

    Ich weiß nicht welche GUI ihr verwendet aber normalerweise ist es üblich den Objekten die z.B. auf einen Klick reagieren sollen einen sogenannten Listener zu geben. Zum Beispiel gibt es einen java.awt.event.MouseListener (AWT). Wenn deine Kugel Listener unterstützt, so kannst du dieser einen entsprechenden hinzufügen. Dazu musst du eine eigene Klasse schreiben, die den Listener implementiert (dort kommt auch rein, was passieren soll, wenn die Maus geklickt wird), dann ein Objekt dieser Klasse erzeugen (mit new) und den Listener der Kugel zuweisen.
    Ob die Kugel AWT-Listener unterstützt kann ich dir nicht sagen. Das musst du selber nachprüfen. Kann auch sein, dass du eigene Listener-Klassen hast, die nichts mit AWT zu tun haben. Oder es wird ein völlig anderes Konzept angewandt. Das kann ich aber nicht erraten.
    Wie es mit AWT geht wird z.B. hier erklärt: openbook.galileocomputing.de/j…81fbfb09c544667c272f00c0a

    AWT ist im übrigen eine Möglichkeit mit Java grafische Oberflächen zu bauen.

    "abstract" ist also dafür da, das man einige Sachen nicht 100 mal schreiben muss und mehrere Klassen darauf zurückgreifen können?

    Ja, könnte man so sehen. Es gibt aber auch noch einen anderen Vorteil. Stell dir vor du hast 20 verschiedene Produkte. Von allen diesen Produkten willst du den Preis haben. Dieser Preis wird aber für alle diese 20 Produkte unterschiedlich berechnet oder von sonstwo hergeholt. Dann machst du einfach eine abstrakte Klasse Produkt mit einer abstrakten Methode getPreis(). Die 20 Produkte sind dann alles eigene Klassen die von Produkt erben und diese Methode implementieren. Der Vorteil ist nun, dass ich in meinem Quellcode nicht ständig zwischen 20 Klassen unterscheiden muss nur um bei denen die getPreis()-Methode aufzurufen. Stattdessen weiß ich, egal welches von den 20 Dingern es ist, es ist auf jeden Fall ein Produkt und hat deswegen auch eine getPreis()-Methode. Also müßen meine Preismethoden nur mit der Klasse Produkt umgehen können und die andern 20 Klassen nicht kennen.
  • Hm, das mit dem ATW werd ich mir noch mal anschauen müssen, danke für den Link.

    *seuftz* ich versteh es nur nich...ich habe zwar einen sich bewegenen Ball, doch ist mir nu aufgefallen (hab nie mehr als wenige Sekunden geschaut), dass er irgentwie nicht richtig läuft. Um ehrlich zu sein hat mir mein vater auch noch "reingepfuscht" so das ich die Bewegung nur noch wage verstehe aber noch im stande bin zu folgen.
    Auf jeden fall ist mein Problem, das der Ball sich zwar bewegt, aber irgentwas stimmt anscheinend nicht mir meiner random funktion, denn die Ball geht immer erst schäk nach oben, und hängt dann in der Ecke (da er ja von den rändern apprallen soll).

    Meine Rechnung sieht so aus:


    [...]

    public int getRandom(int max)
    {
    return RANDOM_GENERATOR.nextInt(max*2+1)-max; // zwischen inclusive -max und inclusive + max
    }

    public void aktualisiereObjekt()
    {
    newRichtung = getRandom(3);
    int r = richtung;
    richtung += newRichtung;

    if (richtung == 8 ) richtung = 0;
    if (richtung == 9) richtung = 1;
    if (richtung == 8 ) richtung = 2;
    if (richtung == -1) richtung = 7;
    if (richtung == -2) richtung = 6;
    if (richtung == -3) richtung = 5;

    switch (richtung)
    {
    case 0: vx = 1; vy = 0;
    case 1: vx = 1; vy = 1;
    case 2: vx = 0; vy = 1;
    case 3: vx = -1; vy = 1;
    case 4: vx = -1; vy = 0;
    case 5: vx = -1; vy = -1;
    case 6: vx = 0; vy = -1;
    case 7: vx = 1; vy = -1;
    }

    if ( (x>=600-r) || (x<=r) ) vx = -vx;
    if ( (y>=600-r) || (y<=r) ) vy= - vy;

    System.out.println(r + ", " +newRichtung+", " + vx + ", " + vy);

    x+=vx;
    y+=vy;

    [...]


    Damit der Ball nicht immer wie ein Zitteraal hin und her wackelt hatte mein Vater vorgeschlagen die 8 richtungen in die der ball gehen kann jeweils einzelnd zu beschreiben (hat irgendwas von Modul gefaselt o.O).
    Aber was soll dieser Part:


    if (richtung == 8 ) richtung = 0;
    if (richtung == 9) richtung = 1;
    if (richtung == 8 ) richtung = 2;
    if (richtung == -1) richtung = 7;
    if (richtung == -2) richtung = 6;
    if (richtung == -3) richtung = 5;

    und sieht einer von euch den Fehler, warum der ball immer nu nach oben rechts wandert?
  • Das mit dem Finger wund tippen ist garnicht so wild, ich bin Bassist, ich hab Hornhaut ohne Ende auf den Fingerkuppen. Und nur wer viel Fragt wird letztlich auch was verstehen...
    Also, auf ein neues...

    Lailan schrieb:

    ...
    Also, ich hab nun endlich einen sich bewegenden Ball. Ich denke, das er in die Mitte muss ist nicht wirklich wichtig, da dreh ich einfach was an den Spielregeln^^

    Na, die feine Art ist das aber nicht!
    Wenn du den Ball bewegen kannst, dann garantiert auch zur Mitte hin. Denk mal ein bischen nach wie das gehen könnte. Bischen Mathematik könnte hier helfen, aber nur n bischen.

    Lailan schrieb:

    ...
    "abstract" ist also dafür da, das man einige Sachen nicht 100 mal schreiben muss und mehrere Klassen darauf zurückgreifen können?

    Hm, jain.
    Eine abstrakte Klasse ist eine besondere Art Oberklasse von der andere Klassen erben.
    Das was du da ansprichst geht mit jeder Form von Vererbung, dafür muss eine Klasse nicht abstrakt sein.
    Angenommen du hast eine Oberklasse Tier, und dann diverse Klassen die davon erben. Hund, Katze, Pferd, Vogel, ...
    Und die sollen zum Beispiel folgende Methoden haben: macheGeräusch, friss, schlaf, ...
    Schlafen kann jedes Tier, und das ist auch bei allen Tieren mehr oder weniger gleich, also reicht es wenn du diese Methode einmal programmierst, darum schreibst du das in deine Klasse Tier rein.
    Auch jedes Tier macht irgend ein Geräusch, darum kannst du auch das schonmal in der Klasse Tier vormerken. Da aber jedes Tier ein anderes Geräusch macht, kannst du die Methode nicht dierekt in Tier fertig schreiben. Aber ohne die Geräusch-Methode ist ein Tier kein Tier, also macht es wenig Sinn ein Objekt der Klasse Tier zu erzeugen. Darum macht man daraus eine abstrakte Klasse. Jetzt kann man die kleinen Unterklassen schreiben, wie Hund, Pferd, Katze, ... und in jeder Unterklasse die Methode macheGeräusch implementieren. Da diese Methode in Tier abstrakt war, und Hund, Katze, Vogel, ... von Tier erben, muss diese Methode auch eingebaut werden.
    Das ist die eine Seite, die Code-Dublizierung vermeidet, dadurch das z.B. schlafen vererbt wird.
    Gleichzeitig schaffst du dir damit aber auch einen neuen Datentyp. Jede Klasse ist immer auch gleichzeitig ein Datentyp (Color, String, ... Das sind eigentlich auch alles Klassen)
    Hierhast du dir neben den speziellen Datentypen Hund, Vogel, ... eben auch einen übergreifenden Datentyp namens Tier geschaffen. Auch das kann manchmal sehr praktisch sein.

    Ich weiß, das klingt bissel verwirrend, Vererbung ist auch kein einfaches Thema. Am besten versuchst du erstmal dich mit einigen grundlegenderen Sachen auseinander zu setzen, bevor du dich damit beschäftigst. Ich wage auch zu bezweifeln das du bei dem Projekt großartig Vererbung brauchst.

    Lailan schrieb:


    Meine nächste Hürde ist es nun, die Kugel bei Klick verschwinden zu lassen. Doch da schon haperts es mir an dem Klick...(alles gar nich so leicht wie man denkt =/ )
    Wie mache ich bemerkbar, dass ich auf eine bestimmte Stelle geklickt habe? Also, wie leite ich die true or false abfrage ein ob die Kugel dort ist? Gibt es dafür einen bestimmten befehl? Der meine Mausklicks bemerkbar macht? Denn zZ passiert nichts wenn ich auf das Feld klicke (verständlicher weise). Aber bei den "Start" und "Pause" Buttons wird eine Aktion angeleitet...(ebenfals vorgegeben)

    Genaues kann ich dir dazu auch nicht sagen, ich weiß nur das du einen ActionListener brauchen wirst. Wie du den jetzt aber auf deinen Kreis bekommst, weiß ich offen gesagt nicht, da ich bisher solche Listener immer nur auf Objekte angewendet habe die dafür vorbereitet waren. Buttons, Text-Felder, Tabellen, etc.

    Lailan schrieb:


    Ich habe also zum wiederholtem mal besagte, vorgegebenen Klassen durchgeforstet und bin dabei immer wieder auf "protected void" gestoßen. Zwar hege ich leichte Zweifel, dass das ist, was ich brauche um meine Klicks "bemerkbar" zu machen...(oder?)...aber dennoch würde mich interessieren, wofür "protected" steht.

    Hinter dem void stand doch garantiert noch mehr!?
    Jeh nach dem was da so stand, kann es durchaus sein das es trotzdem für dich interessant ist, und dir bei deinem Problem hilft.
    protected sagt, das diese Methode bei Vererbung nicht verändert werden darf/kann.
    Du kannst normaler weise durchaus hingehen und eine Klasse von einer anderen erben lassen, aber sagen die Unterklasse soll diese und jene Methode anders ausführen als die Oberklasse. Bei einer protected Methode geht das nicht.

    HTH
    Look

    Edit: Warum schreib ich hier überhaupt noch? Andere sind doch eh schneller... :wacko:
  • Quellcode

    1. if (richtung == 8 ) richtung = 0;
    2. if (richtung == 9) richtung = 1;
    3. if (richtung == 8 ) richtung = 2;
    4. if (richtung == -1) richtung = 7;
    5. if (richtung == -2) richtung = 6;
    6. if (richtung == -3) richtung = 5;

    Die dritte Zeile sieht falsch aus. Willst du nochmal auf == 8 prüfen? Schau dir zudem einfach mal an, was dir
    richtung = richtung % 8;
    zurück gibt.


    Quellcode

    1. switch (richtung)
    2. {
    3. case 0: vx = 1; vy = 0;
    4. case 1: vx = 1; vy = 1;
    5. case 2: vx = 0; vy = 1;
    6. case 3: vx = -1; vy = 1;
    7. case 4: vx = -1; vy = 0;
    8. case 5: vx = -1; vy = -1;
    9. case 6: vx = 0; vy = -1;
    10. case 7: vx = 1; vy = -1;
    11. }
    Alles anzeigen


    Der break Befehl ist bei einem Switch wichtig. Ansonsten springt er zum ersten passenden case und führt dann die nachfolgenden TROTZDEM aus. Was dazu führt, dass am Ende vx immer 1 und vy immer -1 ist. Mache lieber:

    Quellcode

    1. switch (richtung)
    2. {
    3. case 0: vx = 1; vy = 0; break;
    4. case 1: vx = 1; vy = 1; break;
    5. case 2: vx = 0; vy = 1; break;
    6. case 3: vx = -1; vy = 1; break;
    7. case 4: vx = -1; vy = 0; break;
    8. case 5: vx = -1; vy = -1; break;
    9. case 6: vx = 0; vy = -1; break;
    10. case 7: vx = 1; vy = -1;
    11. }
    Alles anzeigen
  • Oww, des mit dem Break war mir nicht klar...klingt aber logisch^^

    Das das nicht die Feine Art ist, einfach die Spielregeln zu ändern, ist mir schon klar, aber ich möchte erst mal es so hinkriegen. Die kleinen feinen Detais, die das Spiel dann perfekt machen, komm zum schluss, falls ich noch Zeit habe. Gibt schließlich noch so was wie abgabe Termine (der übrigens gefährlich nahe kommt <=/....)

    Ich habe mich nun ein wenig mit dem MouseListener beschäftigt und erlich gesagt, will der nich so ganz 8|
    >>implement MouseListener<< steht braf ganz oben und im weiteren Verlauf der Kugel Klasse auch noch



    public void mousePressed(MouseEvent e)
    {
    / System.out.println("Mouse pressed; # of clicks: " + e.getClickCount(), e);
    }

    public void mouseReleased(MouseEvent e)
    {
    System.out.println("Mouse released; # of clicks: " + e.getClickCount(), e);
    }

    public void mouseEntered(MouseEvent e)
    {
    System.out.println("Mouse entered", e);
    }

    public void mouseExited(MouseEvent e)
    {
    System.out.println("Mouse exited", e);
    }

    public void mouseClicked(MouseEvent e)
    {
    System.out.println("Mouse clicked (# of clicks: " + e.getClickCount() + ")", e);

    }


    Das sind Methoden, die ich im Internet gefunden habe und ohne die der MouseListener streikt.
    (addMouseListener(this) und alle notwendigen Bibliotheken, so wie extends Jpanel habe ich auch.)

    Problem:
    So wie ich es nu ja stehn hab soll er mir eiiiiinfach nur ausdrucken, was in der Klammer ind den Anführungszeichen steht, oder?
    macht er aber nicht!
    Beim Compelieren ist alles perfekt und sonst kommen auch keine fehlermeldungen.

    Habe ich was vergessen? Oder mal wieder übersehen?


    Oder liegt es daran, das ich bereits einen MouseListener in der Klasse "Maus" habe und dieser den Listener in der Klasse "Kugel" irgentwie aufhebt oder einschrenkt (kann ich mir aber eigentlich nur schwer vorstellen...)
  • Du hast das Konzept des Listeners nicht verstanden. :D

    Also. Das erste was du tun musst ist zu überprüfen ob du der Kugel überhaupt einen Listener zuweisen kannst. Es bringt nichts die Kugel selbst zu einem Listener zu machen. Die Methoden werden nie ausgeführt. Von wem auch.
    Vielleicht musst du auch keinen Listener übergeben, sondern hast einfach eine Hook-Methode die du überschreiben musst. Es gibt viele Möglichkeiten.
    Ich kenne die Klassen nicht, die du verwendest. Deswegen kann ich dir natürlich auch nicht sagen was du tun musst.

    Überprüfe doch einfach mal, welche Methoden du an der Kugel und an deren Oberklassen (wie AnimiertesObjekt) hast. Vielleicht ist dort ja etwas passendes dabei.

    Wenn du selbst nichts findest, dann poste doch hier mal die Methoden und die Klassenhierarchie der Kugel.
  • Warum ist es so wichtig eine Klasse zu kennen? Also genau zu wissen, was in dieser steht?
    Naja, da ist die Kugel:

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


    /**
    * Write a description of class RuhenderBall here.
    *
    * @author (your name)
    * @version (a version number or a date)
    */
    public class Kugel extends AnimiertesObjekt implements MouseListener
    {
    public double x, y, r;
    public Color farbe;
    public int vx, vy;
    public int richtung = 2, timerRichtung;
    public int newRichtung;
    public final static Random RANDOM_GENERATOR = new Random();

    /**
    * Konstruktor mit Startwerten
    */
    public Kugel(double x, double y, double r, Color farbe)
    {
    this.x=x;
    this.y=y;
    this.r=r;
    this.farbe=farbe;
    addMouseListener(this);
    }

    /**
    * Ball mit standard-Werten
    */
    public Kugel()
    {
    this(100,100,37,Color.BLUE);

    }

    /**
    * Das Objekt kann seinen Zustand selbständig aktualisieren
    * aktualisiereObjekt() wird in der Animationsschleife jeweils einmal aufgerufen
    */


    public int getRandom(int max)
    {
    return RANDOM_GENERATOR.nextInt(max*2+1)-max; // zwischen inclusive -max und inclusive + max
    }

    public void aktualisiereObjekt()
    {
    if (--timerRichtung <= 0)
    {

    newRichtung = getRandom(3);
    int r = richtung;
    richtung += newRichtung;

    if (richtung == 8) richtung = 0;
    if (richtung == 9) richtung = 1;
    if (richtung == 10) richtung = 2;
    if (richtung == -1) richtung = 7;
    if (richtung == -2) richtung = 6;
    if (richtung == -3) richtung = 5;

    switch (richtung)
    {
    case 0: vx = 1; vy = 0; break;
    case 1: vx = 1; vy = 1; break;
    case 2: vx = 0; vy = 1; break;
    case 3: vx = -1; vy = 1; break;
    case 4: vx = -1; vy = 0; break;
    case 5: vx = -1; vy = -1; break;
    case 6: vx = 1; vy = -1; break;
    case 7: vx = 1; vy = -1; break;
    }


    System.out.println(r + ", " +newRichtung+", " + vx + ", " + vy);

    timerRichtung=40+RANDOM_GENERATOR.nextInt(20);

    // System.out.println(Maus.istLinksGeklickt());
    // System.out.println(Maus.istDrinnen());

    }
    x+=vx;
    y+=vy;

    if (x>=600-r) x=600-r;
    if (x<r) x=r;
    if (y>=600-r) y=600-r;
    if (y<r) y=r;

    }


    /**
    * Das Objekt zeichnet sich auf die Zeichenoberfläche
    *
    * @param g Die Zeichenoberfläche (gleich als Graphics2D)
    */
    public void zeichneObjekt(Graphics2D g)
    {
    Bilder.zeichneBildMittig("Kugel2", (int) x, (int) y, g);
    }



    public void mousePressed(MouseEvent e)
    {
    System.out.println("Mouse pressed; # of clicks: " + e.getClickCount());
    }

    public void mouseReleased(MouseEvent e)
    {
    System.out.println("Mouse released; # of clicks: " + e.getClickCount());
    }

    public void mouseEntered(MouseEvent e)
    {
    System.out.println("Mouse entered");
    }

    public void mouseExited(MouseEvent e)
    {
    System.out.println("Mouse exited");
    }

    public void mouseClicked(MouseEvent e)
    {
    System.out.println("Mouse clicked (# of clicks: " + e.getClickCount() + ")");

    }
    }

    Könnt man damit eher was anfangen? x)


    Warum aber funktioniert nichts? Also warum macht der Listener nicht?
    Und was ist ein Hook? xD
    (hast du da ne gute I-net seite zum erklären parat?)

    Und wonach muss ich in den Oberklassen suchen? Ich finde da schon einiges was sich MouseListener nennt, aber des ist leicht verwirrend...=S
  • Der Inhalt der Methoden ist erst einmal nicht so wichtig. Stattdessen ist aber wichtig welche Methoden es überhaupt gibt.

    Das "implements MouseListener" und die zugehörigen Methoden kannst du aus der Kugel-Klasse entfernen. Das stimmt so nicht.

    Dann liste mir mal die public und protected Methoden von AnimiertesObjekt auf. Ich brauche nicht das was in den Methoden steht, sondern nur ihre Rückgabe und Übergabewerte um mir ein Bild zu machen. Es ist selbstverständlich wichtig zu wissen was die Klasse kann, mit der man arbeitet. Wenn AnimiertesObjekt eine Oberklasse hat, dann liste mir bitte auch diese Methoden auf. (Außer private-Methoden. Auf die kann man eh nicht zugreifen.)


    Das Konzept der Listener:
    Ich versuche mal zu erklären wie das funktioniert. Zum AWT gehöhren Klassen mit denen man eine GUI rendern kann. Als Beispiel greife ich einfach mal eine Klasse heraus die zu AWT gehört. Das Panel. Das Panel ist einfach nur eine Fläche in einem Fenster. Das Panel erbt von Container, der wiederum von Component erbt. Die Klasse Component hat eine Methode "public void addMouseListener(MouseListener l)" und da das Panel (gemäß der Vererbung) auch eine Component ist, hat auch das Panel diese Methode. Der MouseListener ist nun ein Interface, das nur Methoden und deren Rück- und Übergabeparameter definiert, aber nicht sagt, was die Methoden tun sollen. Deswegen kann man auch kein Objekt von MouseListener erstellen (new MouseListener() geht nicht). Man kann aber eine eigene Klasse schreiben, die den MouseListener implementiert. Damit ist eben diese Klasse (ich nenne sie mal MyMouseListener) ein MouseListener. Da man dort auch gesagt hat, was die einzelnen Methode tun sollen, kann man auch ein Objekt von MyMouseListener anlegen (new MyMouseListener() geht). Jetzt kommt es! Nun kann man das Objekt von MyMouseListener dem Panel mit der addMouseListener-Methode übergeben, da ja auch MyMouseListener ein MouseListener ist! Das coole ist, dass das Panel deine MyMouseListener-Klasse nicht kennt, aber trotzdem die Methoden deiner Klasse ausführen kann, da es ja das Interface MouseListener kennt! Und wann wird das Panel die Methoden ausführen? Genau! wenn etwas mit der Maus auf dem Panel gemacht wird.
    So wird es bei AWT gemacht. Ob das was du benutzt ein ähnliches Prinzip hat, kann ich nicht sagen da ich nicht weiß, welche Methoden du überhaupt an deiner Kugel und ihren Oberklassen hast. Deswegen möchte ich sie von dir wissen. Die Kugel würde im Übrigen die Rolle des Panels einnehmen und nicht die der Klasse MyMouseListener. Deswegen meinte ich, dass du das nicht ganz verstanden hast, als ich deinen Ansatz sah.

    Das Konzept der Hook-Methode:
    Eine Hook-Methode ist eine Methode von einer Oberklasse die zwar aufgerufen wird, aber nichts tut. Die Implementierung ist leer. Warum braucht man dann so eine Methode? Ganz einfach, man kann diese Methode in der Unterklasse überschreiben und dort seinen Wunschquellcode einfügen. Wenn z.B. die Klasse AnimiertesObjekt eine Methode hat die z.B. "ichWerdeAusgefuehrtBeiEinemMausKlick()" heißt, dann könntest du diese in der Kugel-Klasse überschreiben. Wenn du dann ein Objekt der Kugel-Klasse hast und von irgendwo diese Methode aufgerufen wird, dann wird dein Quellcode ausgeführt.
    Auch hierfür ist es wichtig die Methoden aller Oberklassen zu kennen. Nicht unbedingt deren Inhalt, aber man sollte wissen welche es gibt. Aber das ist dir jetzt sicherlich auch klar.

    Eine Anmerkung am Rande. Alle Klassen die zur Java-Programmiersprache gehören sind mit samt ihren Methoden kurz und bündig dokumentiert. Das sind wirklich wertvolle und wichtige Informationen!
    Hier sind sie alle aufgeführt:
    java.sun.com/javase/6/docs/api/
    Wenn du also wissen willst, was eine Standard-Java-Klasse kann, dann ist das der richtige Ort um nach zuschlagen. Wenn "AnimiertesObjekt" eine Standard-Klasse währe, hätte ich das auch dort gemacht. :)
  • Und wie ich schonmal sagte: Wenn du in BlueJ eine Klasse auf rufst, kannst du oben rechts in dem Dropdown-Menü von "Quelltext" auf "Dokumentation" umstellen, das erleichtert die Übersicht über die vorhandenen Methoden ungemein.

    Ach, und wo wir schon bei Übersicht sind, benutz doch bitte das nächste mal wenn du hier Quellcode postest den entsprechenden Syntax-Highliter (findest du unten bei den Smileys), das erleichtert uns das lesen.
  • Quellcode

    1. import java.awt.*;
    2. import javax.swing.*;
    3. import java.util.*;
    4. import java.awt.event.*;
    5. public class Kugel extends AnimiertesObjekt implements MouseListener
    6. {
    7. public Kugel(double x, double y, double r, Color farbe)
    8. {
    9. }
    10. public Kugel()
    11. {
    12. }
    13. public int getRandom(int max)
    14. {
    15. }
    16. public void aktualisiereObjekt()
    17. {
    18. }
    19. public void zeichneObjekt(Graphics2D g)
    20. {
    21. }
    22. }
    Alles anzeigen


    Animiertes Objekt:

    Quellcode

    1. import java.awt.*;
    2. import javax.swing.*;
    3. public class AnimiertesObjekt extends JPanel
    4. {
    5. public void setzeBesitzer(ListeAnimierterObjekte besitzer)
    6. {
    7. }
    8. public void entferneAusListe()
    9. {
    10. }
    11. public void aktualisiereObjekt()
    12. {
    13. }
    14. public void zeichneObjekt(Graphics2D g)
    15. {
    16. }
    17. }
    Alles anzeigen


    und JPanel ist doch eins, des Java in ner Bibliotehk hat, oder?
    Also, wo genau müsste ich nun den MouseListener einfügen? oder kann ich sogar vieleicht einfach auf dem MouseListener in Klasse "Maus"?
    Klasse "Maus":

    Quellcode

    1. import java.awt.event.*;
    2. public class Maus implements MouseListener, MouseMotionListener
    3. {
    4. public static Maus gibInstanz() { return dasSingleton; }
    5. // hier werden die Ereignisse gemerkt:
    6. private int mausX, mausY;
    7. private boolean istMausLinksGedrückt=false;
    8. private boolean istMausRechtsGedrückt=false;
    9. private boolean istMausRechtsGeklickt=false;
    10. private int mausRechtsKlickX, mausRechtsKlickY;
    11. private boolean istMausLinksGeklickt=false;
    12. private int mausLinksKlickX, mausLinksKlickY;
    13. private boolean mausDrinnen=false; // geschätzt ...
    14. // die öffentlichen Zugriffsmethoden:
    15. public static int x() { return dasSingleton.mausX; }
    16. public static int y() { return dasSingleton.mausY; }
    17. public static boolean istLinksGedrückt() { return dasSingleton.istMausLinksGedrückt; }
    18. public static boolean istRechtsGedrückt() { return dasSingleton.istMausRechtsGedrückt; }
    19. public static boolean istRechtsGeklickt()
    20. {
    21. }
    22. public static boolean istLinksGeklickt()
    23. {
    24. }
    25. public static int linksKlickX() { return dasSingleton.mausLinksKlickX; }
    26. public static int linksKlickY() { return dasSingleton.mausLinksKlickY; }
    27. public static int rechtsKlickX() { return dasSingleton.mausRechtsKlickX; }
    28. public static int rechtsKlickY() { return dasSingleton.mausRechtsKlickY; }
    29. public static boolean istDrinnen() { return dasSingleton.mausDrinnen; }
    30. public void mouseClicked(MouseEvent e)
    31. {
    32. }
    33. public void mouseEntered(MouseEvent e) { mausDrinnen=true; }
    34. public void mouseExited(MouseEvent e) { mausDrinnen=false; }
    35. public void mousePressed(MouseEvent e)
    36. {
    37. }
    38. public void mouseReleased(MouseEvent e)
    39. {
    40. }
    41. public void mouseDragged(MouseEvent e)
    42. {
    43. }
    44. public void mouseMoved(MouseEvent e)
    45. {
    46. }
    47. }
    Alles anzeigen
  • Ah! Da haben wir ja schon die Lösung all unserer Probleme.

    JPanel ist eine Klasse die zu Swing gehört. Swing kann wie AWT eine GUI rendern. Swing setzt zudem auch noch auf AWT auf (wie du gleich sehen wirst) und gehört (wie du richtig erkannt hast) zu den Java-Standard-Klassen. Demnach ist es auch dokumentiert:
    java.sun.com/javase/6/docs/api/javax/swing/JPanel.html
    Wenn wir uns den Link einem genauer anschauen dann sehen wir diese Vererbungsstruktur:
    java.lang.Object
    extended by java.awt.Component
    extended by java.awt.Container
    extended by javax.swing.JComponent
    extended by javax.swing.JPanel

    Kommt die java.awt.Component irgendwie bekannt vor? Genau! Da hatten wir die addMouseListener()-Methode.
    Eine Klasse Maus hast du ja nun auch schon (auch wenn die beim Aufruf der mouseClicked()-Methode oder mouseReleased()-Methode noch nichts tut). War die Klasse vorgegeben oder hast du die selbst implementiert?

    Die Maus-Klasse ist etwas komisch. So wie das da steht kann es nicht funktionieren. Das statische Attribut dasSingleton wird weder deklariert noch initialisiert. Zudem halte ich das Singelton-Muster an dieser Stelle für unpassend. Die Bezeichnung Maus ist auch verwirrend. Es handelt sich nicht wirklich um eine Klasse die die Maus repräsentiert. Sondern es ist wirklich ein Listener, also ein Lauscher, der auf die Ereignisse reagieren soll, die von der Maus ausgelöst werden.

    Was musst du nun tun? Du muss irgendwie ein Objekt der Klasse Maus bekommen und dem Kugel-Objekt mit der addMouseListener()-Methode übergeben. Je nach Geschmack solltest du die mouseClicked()-Methode oder mouseReleased()-Methode implementieren. Wann die genau aufgerufen werden kannst du sogar in Deutsch nachlesen:
    dpunkt.de/java/Referenz/Das_Paket_java.awt.event/32.html

    An dieser Stelle hast du auch noch etwas was du vielleicht noch nicht kanntest. Das Schlüsselwort static. static Methoden oder Attribute sind der Klasse zugeordnet und nicht einem Objekt der Klasse. Was soll das bedeuten?
    Beispiel:

    Quellcode

    1. public class MyClass1
    2. {
    3. public void myMethod() { }
    4. }

    Quellcode

    1. public class MyClass2
    2. {
    3. public static void myMethod() { }
    4. }

    Quellcode

    1. MyClass1.myMethod(); // geht nicht, die Methode kann nur auf einem Objekt und nicht auf einer Klasse aufgerufen werden.
    2. MyClass1 classObject1 = new MyClass1();
    3. classObject1.myMethod(); // geht
    4. MyClass2.myMethod(); // geht, da die Methode statisch ist
    5. MyClass2 classObject2 = new MyClass2();
    6. classObject2.myMethod(); // geht, solle aber eine Warnung ausgeben, die besagt, dass man statische Methoden gefälligst auf der Klasse und nicht auf dem Objekt aufrufen soll.