JavaFX Как я могу изменять и перемещать круги во время выполнения? - PullRequest
1 голос
/ 29 марта 2020

Я новичок в JavaFX и пытаюсь реализовать эффект TranslateTransition.

Моя цель - создать группу окружностей на сцене, а затем перемещать их во время выполнения, когда другие классы передают им новую информацию о координатах.

Моя проблема состоит из двух частей: 1. если Я исключительно создаю анимацию внутри start (Stage stage), весь эффект будет происходить вместе. Допустим, я создал 30 кругов в al oop, и для каждого l oop я хочу переместить один круг. Реальность такова, что все 30 кругов движутся вместе. 2. Если я попытаюсь запустить свой код в другом классе, например Test. java. Я создаю новый класс Animation и вызываю его main для запуска нового приложения JavaFX. Тогда у меня нет возможности попросить мои круги перейти к указанному c местоположению во время выполнения.

Я знаю, что это может показаться странным, потому что я делаю хакфон и никогда раньше не делал ничего подобного JavaFX. Я подозреваю, что моя проблема связана с параллелизмом или многопоточностью. Спасибо за чтение, любая помощь будет принята с благодарностью!

package sample;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.util.Random;

public class Animation extends Application {
    private Group groupOfPeople;
    private Scene scene;
    private Stage window;
    private PathCircle[][] pathCircles;
    private final int x_length = 100; //align with Person.java
    private final int y_length = 100;
    public Controller control;

    public static void main(String args[]){
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        Random num = new Random();
        initConstants(stage);
        for (int i=0; i<30; i++) { //TODO:can randomly generate people and move, but only
            //TODO: works within the start function
            addPeople(i, 0, num.nextInt(550), num.nextInt(550));
            pathCircles[i][0].move(num.nextInt(550),num.nextInt(550));
        }

        window.show();
    }


    //requires the index in field[][] in Person.java, and the initial position
    public void addPeople(int xIndex, int yIndex, double xPos, double yPos) {
        pathCircles[xIndex][yIndex] = new PathCircle(xPos, yPos);
        groupOfPeople.getChildren().add(pathCircles[xIndex][yIndex].getCircle());
    }

    public void playMove(int xPosOfPerson, int yPosOfPerson, double xPos, double yPos) {
        pathCircles[xPosOfPerson][yPosOfPerson].move(xPos, yPos);
    }

    private void initConstants(Stage stage) {
        window = stage;
        groupOfPeople = new Group();
        window.setTitle("Corona Model");
        pathCircles = new PathCircle[x_length][y_length];
        scene = new Scene(groupOfPeople, 600, 600);
        window.setResizable(false);
        window.setScene(scene);
    }
}
package sample;
import javafx.animation.TranslateTransition;
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;
import javafx.util.Duration;

public class PathCircle {
    private Circle circle;
    private TranslateTransition movingPath;

    PathCircle(double xPos, double yPos) {
        circle = new Circle(xPos, yPos, 5.0f, Color.GOLD);
        circle.setStrokeWidth(20);
        //TODO: initial color not decided
        movingPath = new TranslateTransition(Duration.millis(2000), circle);
        movingPath.setCycleCount(1);
        movingPath.setAutoReverse(false);
    }

    public double getCenterX() {
        return circle.getCenterX();
    }

    public double getCenterY() {
        return circle.getCenterY();
    }

    public void setCircleColor(Color color) {
        circle.setFill(color);
    }

    public void move(double xDest, double yDest) {
        movingPath.setByX(xDest - getCenterX());
        movingPath.setByY(yDest - getCenterY());
        movingPath.play();
    }

    public Circle getCircle() {
        return circle;
    }

package sample;

public class Test {
    public static void main(String[] args) throws Exception {
        Animation anime = new Animation();

        anime.main(args);
        //TODO:if I want to move a circle, I can't:
        anime.playMove(1,0,50,50);


    }
}

1 Ответ

0 голосов
/ 30 марта 2020

Это не работает

public static void main(String[] args) throws Exception {
    Animation anime = new Animation();
    anime.main(args);
    anime.playMove(1,0,50,50);
}

, потому что вызов запуска создаст другой экземпляр Animation. Думайте о методе start как о JavaFx главном. Если вам нужен класс, который изменяет gui (перемещает круги), вызовите его из start, как показано в следующем mre :

import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.TilePane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Animation extends Application {

    private Group groupOfPeople;
    private Scene scene;
    private Stage window;
    private PathCircle[][] pathCircles;
    private final int x_length = 10, y_length = 10, size = 600;

    public static void main(String args[]){
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        Random num = new Random();
        initConstants(stage);
        for (int i=0; i<pathCircles.length; i++) {
            for (int j=0; j<pathCircles[0].length; j++) {
                addPeople(i, j, num.nextInt(size - 50), num.nextInt(size - 50));
            }
        }

        window.show();

        Stage secondStage = new SecondStage(pathCircles);
        secondStage.show();
    }

    public void addPeople(int xIndex, int yIndex, double xPos, double yPos) {
        pathCircles[xIndex][yIndex] = new PathCircle(xPos, yPos);
        groupOfPeople.getChildren().add(pathCircles[xIndex][yIndex].getCircle());
    }

    private void initConstants(Stage stage) {
        window = stage;
        groupOfPeople = new Group();
        window.setTitle("Corona Model");
        pathCircles = new PathCircle[x_length][y_length];
        scene = new Scene(groupOfPeople, size, size);
        window.setResizable(false);
        window.setScene(scene);
    }
}

class PathCircle {
    private final Circle circle;
    private final TranslateTransition movingPath;

    PathCircle(double xPos, double yPos) {
        circle = new Circle(xPos, yPos, 5.0f, Color.GOLD);
        circle.setStrokeWidth(20);
        movingPath = new TranslateTransition(Duration.millis(2000), circle);
        movingPath.setCycleCount(1);
        movingPath.setAutoReverse(false);
    }

    public double getCenterX() {
        return circle.getCenterX();
    }

    public double getCenterY() {
        return circle.getCenterY();
    }

    public void setCircleColor(Color color) {
        circle.setFill(color);
    }

    public void move(double xDest, double yDest) {
        movingPath.setByX(xDest - getCenterX());
        movingPath.setByY(yDest - getCenterY());
        movingPath.play();
    }

    public Circle getCircle() {
        return circle;
    }
}

class SecondStage extends Stage{

    private final PathCircle[][] pathCircles;

    public SecondStage(PathCircle[][] pathCircles) {

        this.pathCircles = pathCircles;

        ComboBox<Integer>xPos = new ComboBox<>();
        xPos.getItems().addAll(IntStream.range(0, pathCircles.length).boxed().collect(Collectors.toList()));
        xPos.getSelectionModel().selectFirst();
        ComboBox<Integer>yPos = new ComboBox<>();
        yPos.getItems().addAll(IntStream.range(0, pathCircles[0].length).boxed().collect(Collectors.toList()));
        yPos.getSelectionModel().selectFirst();
        Button moveBtn = new Button("Move");
        moveBtn.setOnAction(e->  playMove(xPos.getValue(),yPos.getValue(),50,50));
        Pane root = new TilePane( new Text("Select Circle X , Y : "), xPos, yPos, moveBtn);

        Scene scene = new Scene(root);
        sizeToScene();
        setScene(scene);
    }

    public void playMove(int xPosOfPerson, int yPosOfPerson, double xPos, double yPos) {
        pathCircles[xPosOfPerson][yPosOfPerson].move(xPos, yPos);
    }
}

Для лучшего проектирования и разделения view и logi c, используйте PathCircle[][] как общую модель между Animation и SecondStage. SecondStage измените модель и Animation прослушайте изменения модели:

public class Animation extends Application implements Listener {

    private Group groupOfPeople;
    private PathCircle[][] pathCircles;
    private final int x_length = 10, y_length = 10, size = 600;

    public static void main(String args[]){
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {

        Stage window = stage;
        groupOfPeople = new Group();
        window.setTitle("Corona Model");
        pathCircles = new PathCircle[x_length][y_length];
        Scene scene = new Scene(groupOfPeople, size, size);
        window.setResizable(false);
        window.setScene(scene);

        Random num = new Random();
        for (int i=0; i<pathCircles.length; i++) {
            for (int j=0; j<pathCircles[0].length; j++) {
                addPeople(i, j, num.nextInt(size - 50), num.nextInt(size - 50));
            }
        }

        window.show();

        Stage secondStage = new SecondStage(pathCircles);
        secondStage.show();
    }

    public void addPeople(int xIndex, int yIndex, double xPos, double yPos) {
        pathCircles[xIndex][yIndex] = new PathCircle(xPos, yPos, this);
        groupOfPeople.getChildren().add(pathCircles[xIndex][yIndex].getCircle());
    }

    @Override
    public void circleMoveByChanged(PathCircle pathCircle) {
        move(pathCircle.getCircle(), pathCircle.getMoveByX(), pathCircle.getMoveByY());
    }

    public void move(Circle circle, double xDest, double yDest) {
        TranslateTransition movingPath = new TranslateTransition(Duration.millis(2000), circle);
        movingPath.setCycleCount(1);
        movingPath.setAutoReverse(false);
        movingPath.setByX(xDest - circle.getCenterX());
        movingPath.setByY(yDest - circle.getCenterY());
        movingPath.play();
    }
}

interface Listener{
    void circleMoveByChanged(PathCircle pathCircle);
}

class PathCircle {

    private final Circle circle;

    private double moveByX, moveByY;
    private final Listener listener;

    PathCircle(double xPos, double yPos, Listener listener) {
        this.listener = listener;
        circle = new Circle(xPos, yPos, 5.0f, Color.GOLD);
        circle.setStrokeWidth(20);
    }

    public double getCenterX() {
        return circle.getCenterX();
    }

    public double getCenterY() {
        return circle.getCenterY();
    }

    public Circle getCircle() {
        return circle;
    }

    public double getMoveByX() {
        return moveByX;
    }

    public double getMoveByY() {
        return moveByY;
    }

    public void setMoveBy(double moveByX, double moveByY) {
        this.moveByX = moveByX;
        this.moveByY = moveByY;
        listener.circleMoveByChanged(this);
    }
}

class SecondStage extends Stage{

    private final PathCircle[][] pathCircles;

    public SecondStage(PathCircle[][] pathCircles) {

        this.pathCircles = pathCircles;

        ComboBox<Integer>xPos = new ComboBox<>();
        xPos.getItems().addAll(IntStream.range(0, pathCircles.length).boxed().collect(Collectors.toList()));
        xPos.getSelectionModel().selectFirst();
        ComboBox<Integer>yPos = new ComboBox<>();
        yPos.getItems().addAll(IntStream.range(0, pathCircles[0].length).boxed().collect(Collectors.toList()));
        yPos.getSelectionModel().selectFirst();
        Button moveBtn = new Button("Move");
        moveBtn.setOnAction(e->  playMove(xPos.getValue(),yPos.getValue(),50,50));
        Pane root = new TilePane( new Text("Select Circle X , Y : "), xPos, yPos, moveBtn);

        Scene scene = new Scene(root);
        sizeToScene();
        setScene(scene);
    }

    public void playMove(int xPosOfPerson, int yPosOfPerson, double xPos, double yPos) {
        pathCircles[xPosOfPerson][yPosOfPerson].setMoveBy(xPos, yPos);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...