为了账号安全,请及时绑定邮箱和手机立即绑定

JavaFX 未渲染数组中较早的项目,无法找到问题,相信线程可能是问题所在

JavaFX 未渲染数组中较早的项目,无法找到问题,相信线程可能是问题所在

FFIVE 2023-07-13 14:30:49
我编写了一个画线算法,在计算每个点时可以正确运行,但是当它被渲染时,程序会跳过近 20 个点,无法找到问题。我试图弄乱算法,特别是 for 循环,它将点添加到计算线的位置列表中,因为我在其他版本的代码中遇到了问题。我只是一辈子都找不到代码的问题,我对 Java 还很陌生,你可能会从下面混乱的代码中看出这一点。它说不要发布整个文件,但我无法确定哪里出了问题。我对下面混乱的代码感到非常抱歉,我只是不知道出了什么问题。package sample;import com.sun.jdi.ArrayReference;import javafx.application.Application;import javafx.application.Platform;import javafx.scene.Group;import javafx.scene.canvas.Canvas;import javafx.scene.canvas.GraphicsContext;import javafx.scene.paint.Color;import javafx.scene.Scene;import javafx.stage.Stage;import java.util.ArrayList;class PositionCounter {    public int position;    public void setPosition(int newPos){        position = newPos;    }}public class Main extends Application {//    public void drawRectangle(int x1, int y1, int x2, int y2, Stage primStage, GraphicsContext gc){//        drawLine(x1, y2, x2, y2 , primStage, gc);//        drawLine(x1, y1, x2, y2, primStage, gc);//        drawLine(x1, y1, x1 , y2, primStage, gc);//        drawLine(x2, y1, x2 , y2, primStage, gc);//        drawLine(x1, y1, x2, y1 , primStage, gc);////    }//    public void fillPosition(ArrayList<Integer[]> points, GraphicsContext gc, int positionInArray ){        gc.fillRect(points.get(positionInArray)[0], points.get(positionInArray)[1], squareWidth / 2, squareWidth / 2);        //System.out.println("(" + points.get(positionInArray)[0] + ", " + points.get(positionInArray)[1]);    }    public void drawLine(int x1, int y1, int x2, int y2, Stage primStage, GraphicsContext gc){        ArrayList<Integer[]> points = calculateLine(x1, y1, x2, y2, gc);        PositionCounter position = new PositionCounter();        Thread thread = new Thread(new Runnable() {            @Override            public void run() {                    Runnable updater = new Runnable() {                        @Override                        public void run() {                            fillPosition(points, gc, position.position);                        }                    };问题是计算线函数返回正确的点,只是没有正确渲染它们。
查看完整描述

1 回答

?
慕森卡

TA贡献1806条经验 获得超8个赞

我建议您使用Timeline而不是Thread. 它可以使用 a 来完成Thread,但Timeline专为此类情况而设计。

画线方法:

public void drawLine(int x1, int y1, int x2, int y2, Stage primStage, GraphicsContext gc)

{


    ArrayList<Integer[]> points = calculateLine(x1, y1, x2, y2, gc);

    PositionCounter position = new PositionCounter();


    int dy = Math.abs(y2 - y1);

    int dx = Math.abs(x2 - x1);

    int m = (dy >= dx) ? dy : dx;


    AtomicInteger counter = new AtomicInteger();

    Timeline animationTimeline = new Timeline(new KeyFrame(Duration.millis(20), (ActionEvent t) -> {

        position.setPosition(counter.getAndIncrement());

        fillPosition(points, gc, position.position);

    }));

    animationTimeline.setCycleCount(points.size());

    animationTimeline.play();


}

完整代码:


import com.sun.jdi.ArrayReference;

import javafx.application.Application;

import javafx.application.Platform;

import javafx.scene.Group;

import javafx.scene.canvas.Canvas;

import javafx.scene.canvas.GraphicsContext;

import javafx.scene.paint.Color;

import javafx.scene.Scene;

import javafx.stage.Stage;


import java.util.ArrayList;

import java.util.concurrent.atomic.AtomicInteger;

import javafx.animation.KeyFrame;

import javafx.animation.Timeline;

import javafx.event.ActionEvent;

import javafx.event.EventHandler;

import javafx.util.Duration;


class PositionCounter

{


    public int position;


    public void setPosition(int newPos)

    {

        position = newPos;

    }

}


public class JavaFXTestingGround extends Application

{


//    public void drawRectangle(int x1, int y1, int x2, int y2, Stage primStage, GraphicsContext gc){

//        drawLine(x1, y2, x2, y2 , primStage, gc);

//        drawLine(x1, y1, x2, y2, primStage, gc);

//        drawLine(x1, y1, x1 , y2, primStage, gc);

//        drawLine(x2, y1, x2 , y2, primStage, gc);

//        drawLine(x1, y1, x2, y1 , primStage, gc);

//

//    }

//

    public void fillPosition(ArrayList<Integer[]> points, GraphicsContext gc, int positionInArray)

    {

        gc.fillRect(points.get(positionInArray)[0], points.get(positionInArray)[1], squareWidth / 2, squareWidth / 2);

        //System.out.println("(" + points.get(positionInArray)[0] + ", " + points.get(positionInArray)[1]);

    }


    public void drawLine(int x1, int y1, int x2, int y2, Stage primStage, GraphicsContext gc)

    {


        ArrayList<Integer[]> points = calculateLine(x1, y1, x2, y2, gc);

        PositionCounter position = new PositionCounter();


        int dy = Math.abs(y2 - y1);

        int dx = Math.abs(x2 - x1);

        int m = (dy >= dx) ? dy : dx;


        AtomicInteger counter = new AtomicInteger();

        Timeline animationTimeline = new Timeline(new KeyFrame(Duration.millis(20), (ActionEvent t) -> {

            position.setPosition(counter.getAndIncrement());

            fillPosition(points, gc, position.position);

        }));

        animationTimeline.setCycleCount(points.size());

        animationTimeline.play();


    }


    @Override

    public void start(Stage primaryStage) throws Exception

    {


        //STUFF

        Group root = new Group();

        Scene scene = new Scene(root, 400, 400);

        scene.setFill(Color.GOLD);


        Canvas canvas = new Canvas(400, 400);

        GraphicsContext gc = canvas.getGraphicsContext2D();


        root.getChildren().add(canvas);

        //////////


        gc.fillRect(0, 200, 400, 1);

        gc.fillRect(0, 100, 400, 1);

        gc.fillRect(0, 300, 400, 1);

        gc.fillRect(200, 0, 1, 400);

        gc.fillRect(100, 0, 1, 400);

        gc.fillRect(300, 0, 1, 400);


        // drawRectangle(50, 50, 350, 250, primaryStage, gc);

        //drawLine(50, 250, 350, 250 , primaryStage, gc);

        //drawLine(50, 50, 350, 250, primaryStage, gc);

        //drawLine(50, 50, 50 , 250, primaryStage, gc);

        //drawLine(350, 50, 350 , 250, primaryStage, gc);

        drawLine(50, 50, 350, 50, primaryStage, gc);


        //////////

        primaryStage.setScene(scene);

        primaryStage.show();

        /////////

    }


    int squareWidth = 2;


    public ArrayList<Integer[]> calculateLine(int x1, int y1, int x2, int y2, GraphicsContext gc)

    {


        ArrayList<Integer[]> points = new ArrayList<Integer[]>();


        int dy = Math.abs(y2 - y1);

        int dx = Math.abs(x2 - x1);


        int sx = (x1 < x2) ? 1 : -1;

        int sy = (y1 < y2) ? 1 : -1;


        int err = dx - dy;

        int x = x1;

        int y = y1;

        int e2 = 0;


        Integer[] pos = new Integer[2];

        pos[0] = x;

        pos[1] = y;

        points.add(pos);


        int m = (dy >= dx) ? dy : dx;


        for (int i = 0; i <= m; i++) {


            e2 = 2 * err;

            if (e2 > -dy) {

                err = err - dy;

                x = x + sx;

                Integer[] position = new Integer[2];

                position[0] = x;

                position[1] = y;

                points.add(position);

            }


            if (e2 < dx) {

                err = err + dx;

                y = y + sy;

                Integer[] position = new Integer[2];

                position[0] = x;

                position[1] = y;

                points.add(position);

            }


        }


        return points;

    }


    public static void main(String[] args)

    {

        launch(args);

    }

}



查看完整回答
反对 回复 2023-07-13
  • 1 回答
  • 0 关注
  • 94 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信