当前位置: 首页 > 知识库问答 >
问题:

在窗格中显示形状的阵列列表(JavaFX)

逄宁
2023-03-14

我正在编写一个代码,它是一个让用户根据他们单击的位置在屏幕上创建圆圈的程序。我尝试的是在第一个事件处理程序中放置createnew cle方法,但它所做的只是给我带来问题。到目前为止,我正在尝试以不同的方式处理问题。我现在使用ArrayList将所有形状组合在一起并将它们显示在窗格上。但是当我运行代码时,圆圈不会显示。

这是我的代码:

import javafx.application.Application; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.Pane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Circle; 
import javafx.scene.shape.Line; 
import javafx.stage.Stage;
    
import java.util.ArrayList;


public class Main extends Application {

    private Pane root;
    private Circle circle;
    private Line line;
    private boolean isClicked = false;
    private ArrayList<Circle> circleList;


    @Override
    public void start(Stage primaryStage) {
        root = new Pane();

        circle = new Circle();
        line = new Line();

         circleList = new ArrayList<Circle>();

        root.getChildren().addAll(line);

        //root.getChildren().addAll(circle); //when this is uncommented the program runs just fine but there is only one circle there at a time

        root.getChildren().addAll(circleList); //I feel like the problem could be here?


        root.setOnMousePressed(new mouseClick());
        root.setOnMouseMoved(new moveMouse());

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

        primaryStage.setTitle("blank");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private double getRadius(double pointOnRadiusX, double pointOnRadiusY, double circleCenterX, double circleCenterY) {
        return Math.sqrt(Math.pow(Math.abs(pointOnRadiusX) - Math.abs(circleCenterX), 2) + Math.pow(Math.abs(pointOnRadiusY) - Math.abs(circleCenterY), 2));
    }

    private class mouseClick implements EventHandler<MouseEvent> {


        @Override
        public void handle(MouseEvent e) {



            if (!isClicked) {
                if(e.getEventType() == MouseEvent.MOUSE_PRESSED){


                    circle.setRadius(0);
                    circle.setCenterX(e.getSceneX());
                    circle.setCenterY(e.getSceneY());
                    circle.setStroke(Color.RED);
                    circle.setFill(Color.TRANSPARENT);

                    line.setStartX(e.getSceneX());
                    line.setStartY(e.getSceneY());
                    line.setStroke(Color.RED);
                    isClicked = true;

                    circleList.add(circle);

                }

            }

            else {

                circle.setRadius(getRadius(e.getSceneX(),e.getSceneY(),circle.getCenterX(), circle.getCenterY()));

                circle.setStroke(Color.GREEN);
                line.setStroke(Color.TRANSPARENT);

                isClicked = false;
            }

        }
    }

    private class moveMouse implements EventHandler <MouseEvent>{
        @Override
        public void handle(MouseEvent e) {
            {
                if (isClicked) {

                    circle.setRadius(getRadius(e.getSceneX(),e.getSceneY(),circle.getCenterX(), circle.getCenterY()));

                    line.setEndX(e.getSceneX());
                    line.setEndY(e.getSceneY());


                }
            }
        }
    }


    public static void main(String[] args) {

        Application.launch(args);
    } }

共有1个答案

林项明
2023-03-14

执行此代码时:

root.getChildren().addAll(circleList);

圆圈列表为空。鉴于您稍后将添加到<code>圆圈列表</code>中,我假设您认为<code>addAll</code>方法以某种方式将两个列表“链接”在一起。事实并非如此。该方法所做的只是从一个列表中复制所有元素并将它们附加到另一个列表。请注意,“复制”并不是指每个元素都是重复的;添加到一个列表中的元素与给定列表中的实例相同。但名单本身仍然是分开的。

您还必须确保不要将同一个<code>圆</code>实例多次添加到<code>根</code>中。节点最多只能在场景图中出现一次。当添加新圆的过程开始时,您应该创建一个新的对象。如果您计划显示多行,则<code>行</code>也是如此。

这是一个工作示例(没有您的Line):

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class App extends Application {

  private Pane root;
  private Circle circle;

  @Override
  public void start(Stage primaryStage) {
    root = new Pane();
    root.setOnMousePressed(this::handleMousePressed);
    root.setOnMouseMoved(this::handleMouseMoved);
    primaryStage.setScene(new Scene(root, 1000.0, 650.0));
    primaryStage.show();
  }

  private void handleMousePressed(MouseEvent e) {
    if (e.getButton() == MouseButton.PRIMARY && e.getClickCount() == 1) {
      if (circle == null) {
        // start drawing a new circle
        circle = new Circle(e.getX(), e.getY(), 0.0, Color.TRANSPARENT);
        circle.setStroke(Color.RED);
        circle.setStrokeWidth(2.0);
        root.getChildren().add(circle);
      } else {
        // "lock" the circle in place
        circle.setStroke(Color.GREEN);
        circle = null;
      }
    }
  }

  private void handleMouseMoved(MouseEvent e) {
    // if 'circle' is null then there's no circle being drawn
    if (circle != null) {
      double x1 = circle.getCenterX();
      double y1 = circle.getCenterY();
      double x2 = e.getX();
      double y2 = e.getY();
      double r = Math.sqrt(Math.pow(x2 - x1, 2.0) + Math.pow(y2 - y1, 2.0));
      circle.setRadius(r);
    }
  }
}

注意,我使用了私有方法和方法引用来实现鼠标处理程序。这样更简洁,但行为上和你的内部类是一样的。

还要注意,在计算半径时,我没有使用< code>Math.abs。使用< code>abs实际上是错误的,会给你错误的结果(< code>|x2| - |x1|!= x2 - x1)。例如,如果您有< code>-3 - 2,会怎么样?这给出了< code>|-3| - |2| = 1,它与< code>-3 - 2 = -5不同。

 类似资料:
  • 好的,所以我尝试在gridpane中垂直列中的任何节点上鼠标时高亮显示该列中的所有节点。现在,我正在获取节点的columnIndex,我的鼠标已结束,然后创建一个共享该列索引的所有节点的数组。将该数组返回到main方法,然后将数组中节点的背景色更改为一种颜色。 这是鼠标覆盖功能: 这是我的Node[]生成器:

  • 问题内容: 我有K个特征向量,它们全部共享维n,但具有可变维m(nxm)。他们都一起生活在一个清单中。 我正在寻找的是一种聪明的方法,以零填充这些np.arrays的行,以便它们都共享相同的维m。我曾尝试使用np.pad解决它,但我还无法提出一个漂亮的解决方案。朝正确方向的任何帮助或推动将不胜感激! 结果应该使数组看起来像这样: 问题答案: 您可以使用它,它也可以使用指定填充宽度的元组填充数组。为

  • 希望有人能帮我做这件事,我对Java很在行。我的问题是,当我打印数组时,会得到一些字符,我想打印数组中的点数。(请忽略不相关的代码,我甚至还没有完成)

  • 是否有一种内置的方法来使用proptypes来确保传递给组件的对象数组实际上是特定形状的对象数组? 也许是这样的? 我是不是漏了什么特别明显的东西?看来这会很受欢迎。

  • 我最近在一次采访中被问到这个问题,我不知道如何实施它。我希望有人能为我指出如何解决这个问题的正确方向。 问题陈述:给定一个二维整数数组,找出可以容纳的总水量。这些数字表示地图中的高程(即山的高度)。水从最高的山流到山谷(从最高的高度到最低的高度)。 示例1:这是一个5 x 3的矩阵。10是最高峰。您可以假设水向下流动,并开始在坐标处的瓷砖2处收集。这块瓷砖将收集7单位的水。在坐标(2,0)或(3,

  • 问题内容: 我想知道从ArrayList转换为Array是否安全/建议?我有一个文本文件,每行一个字符串: 我想将它们读入数组列表,然后将其转换为数组。建议这样做/合法吗? 谢谢 问题答案: 是的,将转换为是安全的。一个好主意取决于您的预期用途。您需要提供的操作吗?如果是这样,请将其保留为。否则转换掉! 输出