通过 JavaFx 的 GridPane 移动多个圆圈很困难

问题描述 投票:0回答:1

我目前在使用 GridPane 时面临挑战。我的目标是在 GridPane 的单元格中移动指定数量的生成圆圈。我有 5 个 GridPane,每个 GridPane 都包含 10 个垂直单元格,我的目标是每次移动圆圈一个单元格,从 0 开始,一直移动到每个 GridPane 中的最后一个单元格,此时圆圈应该消失。

我已经成功移动了一个圆圈,但在处理多个圆圈并按顺序排列它们的移动时遇到了困难。此外,我正在寻求有关单独调整圆圈速度的指导。我想加入一个速度因素,所以如果有一个缓慢移动的圆圈,就会导致线路整体移动的延迟。

以下是相关代码片段:

package phase1;

import javafx.animation.*;
import Classes.Person;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

public class Phase1 extends Application {
    ArrayList<Circle> PEOPLE;
    private List<Circle> objects;
    private Timer timer;
    private boolean isRowEmpty(GridPane gridPane, int rowIndex) {
        for (javafx.scene.Node node : gridPane.getChildren()) {
            Integer nodeRowIndex = GridPane.getRowIndex(node);
            if (nodeRowIndex != null && nodeRowIndex.intValue() == rowIndex) {
                return false;
            }
        }
        return true;
    }

    
    @Override
    public void start(Stage stage) throws InterruptedException, IOException {

        // Create the root container (AnchorPane)
        Parent fxmlRoot = new FXMLLoader().load(getClass().getResource("/PHASE.fxml"));
        // Create the controller and move the circles
        Phase1Controller controller = new Phase1Controller();


        Group root = new Group(); //Creating a Group
        root.getChildren().add(fxmlRoot);
        GridPane graid1 = (GridPane) fxmlRoot.lookup("#Grid2");
        objects = new ArrayList<>();
        //PEOPLE = Phase1Controller.show_circles(fxmlRoot, 10);
        ArrayList<Person> people = Main1.generatePeople(5);
        Circle c1 = people.get(0).circle;
        Circle c2 = new Circle(22.5,Color.RED);

        timer = new Timer();
        graid1.add(c1,0,0);
        int RowIndex = 0;

        AtomicInteger rowIndex = new AtomicInteger(0);
        AtomicBoolean ss = new AtomicBoolean(true);
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                Platform.runLater(() -> {
                    int currentRowIndex = rowIndex.getAndIncrement();
                    if (currentRowIndex >0){
                        //graid1.getChildren().set(currentRowIndex-1,c2);

                        }

                        // Add the node to the new row
                    graid1.getChildren().remove(c1);

                    // Add the node to the new row
                    graid1.add(c1, 0, currentRowIndex);
                    int pp = graid1.getRowConstraints().size();
                    System.out.println(pp);
                    if(pp == currentRowIndex){ graid1.getChildren().remove(c1); timer.cancel();}

                });


            }
        }, 0, 1000);// Run every 1 second




            // Create a scene and set it to the stage
            Scene scene = new Scene(root);
        stage.setTitle("Team 1");
        stage.setResizable(true); // Display the Resizable
        stage.setScene(scene);
        stage.show();

        }

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


    }

这是 GUI 中的 gif,仅展示了一个运动中的圆圈:enter image description here

java javafx gridpane
1个回答
0
投票

您问的问题不止一个。将您的帖子保持为每个帖子一个问题。这里有一些东西也许可以帮助你移动你的圈子。

我会使用

Timeline
而不是
Timer

Timeline
示例

import java.util.ArrayList;
import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.event.ActionEvent;
import javafx.scene.control.Button;

public class Mavenproject3 extends Application {
    final int ROW_COUNT = 8;
    final int COLUMN_COUNT = 1;

    
    @Override
    public void start(Stage stage){
        
        GridPane gridPane = new GridPane();
        gridPane.setGridLinesVisible(true);
        RowConstraints rowConstraints = new RowConstraints(100, 100, 100);
        ColumnConstraints columnConstraints = new ColumnConstraints(100, 100, 100);
        for(int i = 0; i < ROW_COUNT; i++)
        {
            gridPane.getRowConstraints().add(rowConstraints);
        }
        
        for(int i = 0; i < COLUMN_COUNT; i++)
        {
            gridPane.getColumnConstraints().add(columnConstraints);
        }
        
        Circle c1 = new Circle(22.5,Color.BLUE);
        Circle c2 = new Circle(22.5,Color.RED);
        Circle c3 = new Circle(22.5,Color.YELLOW);
        Circle c4 = new Circle(22.5,Color.GREEN);
        Map<Circle, Integer> circleMap = new LinkedHashMap();        
        circleMap.put(c1, -1);
        circleMap.put(c2, -1);
        circleMap.put(c3, -1);
        circleMap.put(c4, -1);
        List<Circle> keys = new ArrayList(circleMap.keySet());
        
        AtomicInteger addCircleCounter = new AtomicInteger();
        AtomicInteger cycleCounter = new AtomicInteger();
        
        Timeline oneSecondsWonder = new Timeline(new KeyFrame(Duration.seconds(1), (ActionEvent event) -> {
            //Moving circles
            if(cycleCounter.get() > 0 && cycleCounter.get() < circleMap.size() + ROW_COUNT)
            {
                for(Circle key : keys)
                {
                    if(circleMap.get(key) > -1)
                    {
                        //System.out.println("Moving Circle " + key.getFill()+ " to " + circleMap.get(key));
                        if(circleMap.get(key) >= ROW_COUNT - 1 )
                        {
                            gridPane.getChildren().remove(key);
                        }
                        else
                        {
                            circleMap.merge(key, 1, Integer::sum);
                            gridPane.getChildren().remove(key);                        
                            gridPane.add(key, 0, circleMap.get(key));
                        }
                    }
                }
            }
            
            //Add Circle to GridPane
            if(addCircleCounter.get()< circleMap.size())
            {
                //System.out.println("Add Circle " + keys.get(addCircleCounter.get()).getFill()+ " to GridPane!");
                gridPane.add(keys.get( addCircleCounter.get()), 0, 0);   
                circleMap.merge(keys.get( addCircleCounter.get()), 1, Integer::sum);
            }  
           
            cycleCounter.getAndIncrement();
            addCircleCounter.getAndIncrement();
        }));
        oneSecondsWonder.setCycleCount(Timeline.INDEFINITE);
        oneSecondsWonder.play();
        
        Button btnDecreaseSpeed = new Button("<");
        btnDecreaseSpeed.setOnAction((ActionEvent event) -> {
            double rate = oneSecondsWonder.getRate();
            if (rate > 1) {
                oneSecondsWonder.setRate(oneSecondsWonder.getRate() - 1);
                System.out.println("Speed: " + oneSecondsWonder.getRate());
            }
        });
        
        Button btnIncreaseSpeed = new Button(">");
        btnIncreaseSpeed.setOnAction((ActionEvent event) -> {
            double rate = oneSecondsWonder.getCurrentRate();
            if (rate < 10) {
                oneSecondsWonder.setRate(oneSecondsWonder.getRate() + 1);
                System.out.println("Speed: " + oneSecondsWonder.getRate());
            }
        });        
        
        VBox root = new VBox(gridPane, new HBox(btnDecreaseSpeed, btnIncreaseSpeed));
        Scene scene = new Scene(root);
        stage.setTitle("Team 1");
        stage.setResizable(true); // Display the Resizable
        stage.setScene(scene);
        stage.show();
    }

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

编辑 添加了增加和减少速度的按钮。输出未更新!

输出

© www.soinside.com 2019 - 2024. All rights reserved.