JavaFX при нажатии кнопки нарисовать прямоугольник с размерами в textField и определить, пересекаются ли они - PullRequest
0 голосов
/ 09 мая 2019

Я пытаюсь написать программу JavaFX, которая получает размеры от пользователя, используя поля TextField, создает два прямоугольника, рисует их и отправляет сообщение, если они пересекаются. У меня проблемы с получением прямоугольников, и я не знаю, почему это происходит. Я также не уверен, как я могу сказать, пересекаются ли они или нет, когда смотрят на значения. Буду признателен за любую помощь, которую вы можете предоставить. Я разместил свой код ниже.

Мой код:

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.*;
import javafx.scene.layout.StackPane;
import javafx.geometry.Insets;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.scene.control.*;
import javafx.scene.shape.Rectangle;
public class Rectangles extends Application
{
    Canvas canvas;
    Label intersectLabel;
    TextField x1Text;
    TextField x2Text;
    TextField y1Text;
    TextField y2Text;
    TextField width1Text;
    TextField width2Text;
    TextField height1Text;
    TextField height2Text;

    @Override
    public void start(Stage stage) throws Exception
    {
        // Create a VBox to stack panes vertically
        VBox panesStack = new VBox(20);
        // Create padding of 10 pixels
        Insets padding = new Insets(10);

        // Create labels and text fields for rectangle 1 info
        Label x1Label = new Label("X:");
        // Create labels and field for r1.
        TextField x1Text = new TextField();
        Label y1Label = new Label("Y:");
        TextField y1Text = new TextField();
        Label width1Label = new Label("Width:");
        TextField width1Text = new TextField();
        Label height1Label = new Label("Height:");
        TextField height1Text = new TextField();

        // Create grid pane for rectangle 1 info, set spacing
        GridPane grid1 = new GridPane();
        grid1.setPadding(padding);
        grid1.setHgap(10);
        grid1.setVgap(5);

        // Add rectangle 1 labels and text fields to grid pane
        // First add the top label to span two columns
        grid1.add(new Label("Enter Rectangle 1 info:"),0,0,2,1);
        grid1.add(x1Label,0,1);
        // Add rest of labels and text fields to grid pane
        grid1.add(x1Text,1,1);
        grid1.add(y1Label,0,2);
        grid1.add(y1Text,1,2);
        grid1.add(width1Label,0,3);
        grid1.add(width1Text,1,3);
        grid1.add(height1Label,0,4);
        grid1.add(height1Text,1,4);

        // Create labels and text fields for rectangle 2 info
        Label x2Label = new Label("X:");
        TextField x2Text = new TextField();
        Label y2Label = new Label("Y:");
        TextField y2Text = new TextField();
        Label width2Label = new Label("Width:");
        TextField width2Text = new TextField();
        Label height2Label = new Label("Height:");
        TextField height2Text = new TextField();

        // Create grid pane for rectangle 2 info, set spacing
        GridPane grid2 = new GridPane();
        grid2.setPadding(padding);
        grid2.setHgap(10);
        grid2.setVgap(5);

        // Add rectangle 2 labels and text fields to grid pane
        // First add the top label to span two columns
        grid2.add(new Label("Enter Rectangle 2 info:"),0,0,2,1);
        // Add field and labels
        grid2.add(x2Label,0,1);
        grid2.add(x2Text,1,1);
        grid2.add(y2Label,0,2);
        grid2.add(y2Text,1,2);
        grid2.add(width2Label,0,3);
        grid2.add(width2Text,1,3);
        grid2.add(height2Label,0,4);
        grid2.add(height2Text,1,4);

        // Add the two rectangle info grid panes to an HBox
        // (so they appear horizontally)
        // then add the HBox to the overarching vertical box (panesStack)
        HBox rectGrids = new HBox(30);
        rectGrids.getChildren().add(grid1);
        rectGrids.getChildren().add(grid2);
        panesStack.getChildren().add(rectGrids);

        // Create update button
        // Add event handler to button
        // Add it to overarching vertical box (panesStack)
        Button update = new Button("Update");
        update.setOnAction(this::updateGUI);
        panesStack.getChildren().add(new StackPane(update));

        // Create a canvas for drawing the rectangles
        canvas = new Canvas(600, 500);      
        // Get the canvas' graphics context to draw
        GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
        // Initially make the canvas blank white
        graphicsContext.setFill(Color.WHITE);
        graphicsContext.fillRect(0,0, canvas.getWidth(), canvas.getHeight());

        // Add the canvas to the overarching vertical box (panesStack)
        panesStack.getChildren().add(canvas);

        // Create a label for the intersection message
        intersectLabel = new Label("waiting for rectangle info");
        intersectLabel.setPadding(new Insets(0,0,20,0));
        panesStack.getChildren().add(new StackPane(intersectLabel));

        // Create a scene containing the overarching vertical box
        Scene scene = new Scene(panesStack);             
        stage.setTitle("Rectangles Lab"); // Set window's title
        stage.setScene(scene);            // Set window's scene
        stage.show();
    }
    public void updateGUI(ActionEvent e) {
        Rectangle r1 = new Rectangle();
        r1.setHeight(Double.valueOf(height1Text.getText()));
        r1.setWidth(Double.valueOf(width1Text.getText()));
        r1.setX(Double.valueOf(x1Text.getText()));
        r1.setY(Double.valueOf(y1Text.getText()));

        Rectangle r2 = new Rectangle();
        r2.setHeight(Double.valueOf(height2Text.getText()));
        r2.setWidth(Double.valueOf(width2Text.getText()));
        r2.setX(Double.valueOf(x2Text.getText()));
        r2.setY(Double.valueOf(y2Text.getText()));

        GraphicsContext graphics = canvas.getGraphicsContext2D();
        graphics.fillRect(r1.getX(), r1.getY(), r1.getWidth(), r1.getHeight());
        graphics.setStroke(Color.BLUE);

        graphics.fillRect(r2.getX(), r2.getY(), r2.getWidth(), r2.getHeight());
        graphics.setStroke(Color.RED);

    }
}

Ответы [ 2 ]

2 голосов
/ 09 мая 2019

Вы не упоминали, что получаете NullPointerException при запуске этого кода, всегда включайте такую ​​информацию и трассировку стека.

Причина, по которой вы получаете NPE, заключается в том, что Rectanglesполя класса height1Text и т. д. никогда не устанавливаются.Вместо этого вы объявляете локальные переменные в своем коде с тем же именем, вместо того, чтобы назначать поля класса.

Когда вы исправляете это, NPE исчезает.

Во-вторых, прямоугольникам нужно fillcolor, так как вы используете fillRect, поэтому обязательно установите его.Цвет stroke вам не поможет, если вы не используете drawRect.Кроме того, сначала установите нужный цвет (с помощью setFill), затем вызовите fillRect, а не наоборот.

2 голосов
/ 09 мая 2019

Прежде всего, исправьте ваш NPE , который является результатом затенения .

Теперь посмотрите внутрь updateGUI.Вы звоните graphics.fillRect, но звоните graphics.setStroke.Обводка и заливка - это разные атрибуты. Если вы хотите заполнить, вызовите setFill с нужным Paint, а если вы хотите произвести обводку, вызовите setStroke.Кроме того, вам нужно установить обводку / заливку до того, как вы выполните операцию рисования, а не после.

Что касается проверки пересечения, посмотрите на Shape#intersect илина Node.intersects.Первый возвращает форму, которая является результатом пересечения и работает для всех фигур.Второй возвращает логическое значение в зависимости от прямоугольных границ узла, поэтому он подходит только для прямоугольников.

Кроме того, не забывайте очищать холст, если это необходимо, перед каждым рисованием.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...