Frage von Bohne999, 42

Wie bennutze ich in Java korrekt wait(), notify() und synchronized..?

Hey, ich möchte in meinem Programm ein Menü erstellen. Wenn man auf einen Play Button klickt sollen die Buttons aus dem Bild fliegen(Das funktioniert), nur jetzt möchte ich das nachdem die Buttons aus dem Bild sind das Spiel hinzufügen. So wie ich es unten gemacht habe bekomme ich immer eine IllegalMonitorStateException :( Kann mir jemand helfen wie ich das machen kann?

 play.setOnMouseClicked(event -> {
        moveOnClick(credits, play, close);


        synchronized (th) {
            try {
                th.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }


        screen.getChildren().remove(background);
        screen.getChildren().addAll(new Ground(), game.getCardPane());


    });


}


private void moveOnClick(CustomButton... buttons){


     th = new Thread(new Runnable() {
        @Override
        public void run() {


            synchronized (th) {
                Timeline time1 = createTimeLine(Duration.millis(350), buttons[0].layoutXProperty(), buttons[0].layoutYProperty(), 1500, buttons[0].getLayoutY());


                Timeline time2 = createTimeLine(Duration.millis(350), buttons[1].layoutXProperty(), buttons[1].layoutYProperty(), 0 - buttons[1].getWidth(), buttons[1].getLayoutY());
                Timeline time3 = createTimeLine(Duration.millis(350), buttons[2].layoutXProperty(), buttons[2].layoutYProperty(), 0 - buttons[2].getWidth(), buttons[2].getLayoutY());

                try {
                    time1.wait();
                    time2.wait();

                    time3.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                th.notify();

            }
        }
    });

    th.start();



}



private Timeline createTimeLine(Duration dur, WritableValue xProp, WritableValue yProp, double toX, double toY){

    Timeline time = new Timeline();

    KeyValue xValue = new KeyValue(xProp, toX);

    KeyValue keyValue = new KeyValue(yProp, toY);

    KeyFrame frame = new KeyFrame(dur, xValue, keyValue);

    time.getKeyFrames().add(frame);

    time.play();

    time.setOnFinished(event -> {
        time.notify();
    });


    return time;

}
Expertenantwort
von KnusperPudding, Community-Experte für Java, 16

Grundsätzlich hat androhecker recht: Zur Modifikation von JavaFX Elementen muss die Änderung auf dem Application-Thread statt finden, was du via Platform.runPlater() bewerkstelligst.

Allerdings ist mir noch nicht so ganz klar, was du mit deine Threads bewerkstelligen willst. Denn eigentlich sollte die Timeline dafür ausreichen.

Ich würde dich an der Stelle einfach nur gerne darum bitten, ein ausführbares Beispiel bereit zu stellen. 

Ich weiß wie grausam die Codefunktion bei GF ist. Daher rate ich dir eher dazu, das Beispiel via pastie.org oder pastebin.com hoch zu laden und dann den Link dazu hier zu posten.

Meiner Meinung nach benötigst du nämlich hier keinen Thread für deine Anforderung, allerdings möchte ich jetzt nicht selbst den Code ergänzen den du teilweise bereit gestellt hast.

Das ist nicht böse gemeint, ich helfe gerne, aber Code erraten ist nun mal nicht so meins. - Freue mich auf deine Ergänzung.

Antwort
von androhecker, 34

Du musst JavaFX Elemente im JavaFX Thread verändern, das geht mit Platform.runLater(Runnable run);

Antwort
von Luksior, 8

Mach im ersten synchronized(th) mal das (th) weg und bei th.notify(); das th.

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten