JavaFX, MouseEvent проблемы - PullRequest
       43

JavaFX, MouseEvent проблемы

0 голосов
/ 05 ноября 2018

В настоящее время я делаю приложение для рисования и создал несколько работающих инструментов, но я столкнулся с проблемой при попытке создать Инструмент «Рисование прямой линии»

Таким образом, я в основном рисую линию от точки A до B, и она работает, линия есть, однако, когда я переключаю другие мои инструменты (рисовать круг, прямоугольник и т. Д.), Фигуры рисуются одновременно с прямой -линии, несмотря на то, что кнопка "Draw Line" отключена.

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

Кто-нибудь знает, какую ошибку я совершил и какие возможные исправления и / или альтернативные решения?

(есть обработчик событий, так что я могу выбрать нарисованные фигуры, изменить их позже, если необходимо, этот код является урезанной версией моего приложения для рисования)

public class DrawLine extends Application {


@Override
public void start(Stage primaryStage) {

    ToggleButton lineButton  =   new    ToggleButton    ("Draw Line");
    ToggleButton Button      =   new    ToggleButton    ("Button with no function");

    BorderPane pane = new BorderPane();
    ToolBar toolbar = new ToolBar();
    Scene scene = new Scene(pane, 1200, 800);
    pane.setLeft(toolbar);
    toolbar.getItems().addAll(lineButton, Button);


    // Draw Line
    scene.addEventHandler(MouseEvent.MOUSE_CLICKED, me -> { 
        if(lineButton.isSelected() & me.getButton().equals(MouseButton.PRIMARY) ) { 
            scene.setOnMousePressed(event -> {
                Line line = new Line();

                line.setStartX(event.getX());
                line.setStartY(event.getY());

                    scene.setOnMouseDragged(e->{

                        line.setEndX(e.getX());
                        line.setEndY(e.getY());
                        });

                    pane.getChildren().add(line);

                });
        }
    });


    primaryStage.setTitle("Paint App"); 
    primaryStage.setScene(scene);       
    primaryStage.show();                 
}

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

}

1 Ответ

0 голосов
/ 05 ноября 2018

Вы только проверяете, выбран ли lineButton в обработчике MOUSE_CLICKED (кстати, жестом пресс-релиза). Внутри этого обработчика вы добавляете обработчик MOUSE_PRESSED и внутри этого обработчика добавляете обработчик MOUSE_DRAGGED. Вы не проверяете, выбран ли lineButton внутри обработчиков MOUSE_PRESSED или MOUSE_DRAGGED.

Это означает, что после того, как условие if в обработчике MOUSE_CLICKED оценивается как true, у вас будет обработчик MOUSE_PRESSED и MOUSE_DRAGGED, который работает независимо от вашего MOUSE_CLICKED обработчик. Теперь, когда вы нажимаете любую кнопку мыши, он создает Line и добавляет его к родителю. Затем добавленный обработчик MOUSE_DRAGGED изменит Line.

Вам повезло, что вы используете свойства onXXX вместо addEventHandler. Свойства заменяют старые EventHandler, если установлены. Если этого не произойдет (например, с addEventHandler), у вас будет много (по одному каждый раз) EventHandler с рисования Line с.

Вам просто нужно зарегистрировать все соответствующие EventHandler s один раз и выполнить логику внутри них.

Вот небольшой пример:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.ToolBar;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

public class Main extends Application {

  private ToggleGroup toggleGroup;
  private ToggleButton lineBtn;

  private Group group;
  private Line currentLine;

  @Override
  public void start(Stage primaryStage) {
    toggleGroup = new ToggleGroup();
    lineBtn = new ToggleButton("Line");

    ToggleButton noneBtn = new ToggleButton("None");
    toggleGroup.getToggles().addAll(lineBtn, noneBtn);
    toggleGroup.selectToggle(noneBtn);

    group = new Group();

    BorderPane root = new BorderPane(new Pane(group), new ToolBar(lineBtn, noneBtn), null, null, null);
    root.getCenter().setOnMousePressed(this::handleMousePressed);
    root.getCenter().setOnMouseDragged(this::handleMouseDragged);
    root.getCenter().setOnMouseReleased(this::handleMouseReleased);

    primaryStage.setScene(new Scene(root, 800, 600));
    primaryStage.setTitle("Draw Shape Example");
    primaryStage.show();
  }

  private void handleMousePressed(MouseEvent event) {
    if (lineBtn.equals(toggleGroup.getSelectedToggle())
        && event.getButton() == MouseButton.PRIMARY) {
      currentLine = new Line(event.getX(), event.getY(), event.getX(), event.getY());
      group.getChildren().add(currentLine);
    }
  }

  private void handleMouseDragged(MouseEvent event) {
    if (currentLine != null) {
      currentLine.setEndX(event.getX());
      currentLine.setEndY(event.getY());
    }
  }

  private void handleMouseReleased(MouseEvent event) {
    if (currentLine != null 
        && currentLine.getStartX() == currentLine.getEndX()
        && currentLine.getStartY() == currentLine.getEndY()) {
      // The line has no length, remove it
      group.getChildren().remove(currentLine);
    }
    currentLine = null;
  }

}
...