【问题标题】:JavaFX, MouseEvent problemsJavaFX、MouseEvent 问题
【发布时间】:2018-11-05 02:03:15
【问题描述】:

我目前正在制作一个绘画应用程序,并创建了几个正在工作的工具,但是在尝试创建一个 “画直线”工具

所以我基本上从 A 点到 B 点画一条线,它可以工作,这条线就在那里,但是,当我切换我的其他工具(绘制圆形、矩形等)时,形状与直线同时绘制-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();
}

}

【问题讨论】:

  • 首先,请遵循java命名约定。您的 Button 被突出显示为一个类,因为它以大写字母开头,即使它是一个变量。
  • @Kartik 感谢它,但是,我通常遵循命名约定,我只是匆忙编写此代码并导致错误:)
  • 别担心,点赞

标签: java javafx mouseevent line draw


【解决方案1】:

您只检查lineButton 是否在MOUSE_CLICKED(顺便说一下,这是一个按下然后释放手势)处理程序中被选中。在这个处理程序中,您添加一个MOUSE_PRESSED 处理程序,在该处理程序中您添加一个MOUSE_DRAGGED 处理程序。您不检查是否在 MOUSE_PRESSEDMOUSE_DRAGGED 处理程序中选择了 lineButton

这一切的意思是,在MOUSE_CLICKED 处理程序内的if 条件评估为真后,您将拥有一个MOUSE_PRESSEDMOUSE_DRAGGED 处理程序,它们独立运行你的MOUSE_CLICKED 处理程序。现在,每当您按下 any 鼠标按钮时,它都会创建一个 Line 并将其添加到父级。然后新添加的MOUSE_DRAGGED 处理程序将更改Line

在某种程度上,您很幸运,您使用的是onXXX 属性而不是addEventHandler。设置后,这些属性将替换旧的 EventHandler。如果这没有发生(例如 addEventHandler),您将有很多(每次多一个)EventHandlers 绘图 Lines。

您只需要注册所有适当的EventHandlers 一次并在其中执行逻辑。

这是一个小例子:

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;
  }

}

【讨论】:

  • 非常感谢,一直在查看您的代码,我对事件处理程序更有信心,它还为我提供了解决方案,非常感谢您花时间帮助我,再次感谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-11
  • 1970-01-01
  • 2013-04-14
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 2014-10-12
相关资源
最近更新 更多