JavaFX鼠标事件延迟/滞后

4
我创建了一个矩形对象的网格并将它们添加到一个Pane中。每个矩形都附有一个鼠标事件监听器,该监听器由MouseEvent.Entered触发。当用户将鼠标移动到矩形上时,处理程序会简单地更改矩形的颜色。问题在于,触发器似乎有相当大的延迟才能执行。有什么办法可以加速它,使其与鼠标实时同步?
我在这里上传了一段录像:https://screencast-o-matic.com/watch/cFQI0lqdHe
public class WarehouseMap extends Pane {

    private int xSpaces = 200;
    private int ySpaces = 100;
    private ArrayList<Rectangle> gridReferences = new ArrayList<Rectangle> ();

    public WarehouseMap() {
        setWidth(2000);
        setHeight(1000);
        initGrid();
    }

    public void initGrid() {
        double rectWidth = getWidth() / xSpaces;
        double rectHeight = getHeight() / ySpaces;

        for(int x=0; x<xSpaces; x++) {
            for(int y=0; y<ySpaces; y++) { 
                Rectangle gr = new Rectangle(x*rectWidth, y*rectHeight, rectWidth, rectHeight);
                gr.setStroke(Color.GRAY);
                gr.setFill(Color.TRANSPARENT);
                gr.setStrokeWidth(1);
                gr.addEventHandler(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent> () {
                    @Override
                    public void handle(MouseEvent event) {
                        gr.setFill(Color.DARKGRAY);
                    }

                });

                gr.addEventHandler(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent> () {
                    @Override
                    public void handle(MouseEvent event) {
                        gr.setFill(Color.TRANSPARENT);
                    }

                });

                gridReferences.add(gr);
                this.getChildren().add(gr);
            }
        }
    }
}
1个回答

3
您可以使用 Canvas 来创建更快的视图:
public class WarehouseCanvasMap extends Pane {
    private int xSpaces = 200;
    private int ySpaces = 100;
    private int cellSize = 10;
    private int lineSize = 1;
    private Canvas canvas;

    public WarehouseCanvasMap() {
        setWidth(xSpaces * cellSize);
        setHeight(ySpaces * cellSize);
        initGrid();
    }

    public void initGrid() {
        canvas = new Canvas();
        canvas.setWidth(getWidth());
        canvas.setHeight(getHeight());
        getChildren().add(canvas);
        GraphicsContext graphic = canvas.getGraphicsContext2D();

        graphic.setStroke(Color.GRAY);
        graphic.setFill(Color.DARKGRAY);
        graphic.setLineWidth(lineSize);

        canvas.setOnMouseMoved(event -> {
            graphic.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());

            graphic.fillRect(event.getX() - event.getX() % cellSize, event.getY() - event.getY() % cellSize, cellSize, cellSize);

            for (int x = 0; x <= xSpaces; x++) {
                graphic.strokeLine(x * cellSize, 0, x * cellSize, canvas.getHeight());
            }
            for (int y = 0; y <= xSpaces; y++) {
                graphic.strokeLine(0, y * cellSize, canvas.getWidth(), y * cellSize);
            }
        });
    }
}

这个解决方案看起来像这样: enter image description here 并且它比原来的速度更快: enter image description here

1
这是一个很棒的答案! - Sam Orozco
谢谢,绝对更快了。JavaFX版本的Swing的paint方法。完美回答了问题。FYI:我重新评估了需求分析,并大大降低了矩形数量,我的原始解决方案已经足够响应我的需求,并且可以轻松访问Rectangle对象,似乎事件监听器越多性能越差。这是我的实现方式:https://screencast-o-matic.com/watch/cFQbeOqMc6 - Ashley Swatton
1
看起来很棒,速度也很快。祝你的项目好运。 - gearquicker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接