JavaFX,MouseEvent 问题
JavaFX, MouseEvent problems
我目前正在制作一个绘画应用程序并创建了几个可用的工具,但是我在尝试创建一个
"Draw straight line" 工具
所以我基本上画了一条从 A 点到 B 点的线,它起作用了,线就在那里,但是,当我切换我的其他工具(画圆、矩形等)时,形状是同时绘制的尽管 "Draw Line" 按钮被关闭,但直线仍然存在。
下面的代码将允许您绘制直线,您可以尝试打开和关闭不同的按钮,当您将光标拖过窗格时,直线仍会被绘制。
有谁知道我犯了什么样的错误,以及任何可能的修复方法and/or 替代解决方案?
(事件处理程序在那里,以便我可以 select 绘制的形状稍后根据需要更改它们,此代码是我的绘画应用程序的精简版)
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();
}
}
您只检查 lineButton
是否在 MOUSE_CLICKED
(顺便说一下,这是一个按下然后释放的手势)处理程序中被选中。在此处理程序中,您添加了一个 MOUSE_PRESSED
处理程序,并且 在该处理程序中 您添加了一个 MOUSE_DRAGGED
处理程序。您不检查是否在 MOUSE_PRESSED
或 MOUSE_DRAGGED
处理程序中选择了 lineButton
。
这一切意味着,在 MOUSE_CLICKED
处理程序中的 if
条件计算结果为真后,您将拥有一个 MOUSE_PRESSED
和 MOUSE_DRAGGED
处理程序独立 操作您的 MOUSE_CLICKED
处理程序。现在,只要您按下 any 鼠标按钮,它就会创建一个 Line
并将其添加到父级。然后新添加的 MOUSE_DRAGGED
处理程序将更改 Line
.
在某种程度上,您很幸运,您使用的是 onXXX
属性而不是 addEventHandler
。这些属性在设置时会替换旧的 EventHandler
。如果那没有发生(比如 addEventHandler
),你会有很多(每次多一个)EventHandler
s 图 Line
s.
您只需要注册所有合适的EventHandler
一次并在其中执行逻辑。
这是一个小例子:
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;
}
}
我目前正在制作一个绘画应用程序并创建了几个可用的工具,但是我在尝试创建一个 "Draw straight line" 工具
所以我基本上画了一条从 A 点到 B 点的线,它起作用了,线就在那里,但是,当我切换我的其他工具(画圆、矩形等)时,形状是同时绘制的尽管 "Draw Line" 按钮被关闭,但直线仍然存在。
下面的代码将允许您绘制直线,您可以尝试打开和关闭不同的按钮,当您将光标拖过窗格时,直线仍会被绘制。
有谁知道我犯了什么样的错误,以及任何可能的修复方法and/or 替代解决方案?
(事件处理程序在那里,以便我可以 select 绘制的形状稍后根据需要更改它们,此代码是我的绘画应用程序的精简版)
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();
}
}
您只检查 lineButton
是否在 MOUSE_CLICKED
(顺便说一下,这是一个按下然后释放的手势)处理程序中被选中。在此处理程序中,您添加了一个 MOUSE_PRESSED
处理程序,并且 在该处理程序中 您添加了一个 MOUSE_DRAGGED
处理程序。您不检查是否在 MOUSE_PRESSED
或 MOUSE_DRAGGED
处理程序中选择了 lineButton
。
这一切意味着,在 MOUSE_CLICKED
处理程序中的 if
条件计算结果为真后,您将拥有一个 MOUSE_PRESSED
和 MOUSE_DRAGGED
处理程序独立 操作您的 MOUSE_CLICKED
处理程序。现在,只要您按下 any 鼠标按钮,它就会创建一个 Line
并将其添加到父级。然后新添加的 MOUSE_DRAGGED
处理程序将更改 Line
.
在某种程度上,您很幸运,您使用的是 onXXX
属性而不是 addEventHandler
。这些属性在设置时会替换旧的 EventHandler
。如果那没有发生(比如 addEventHandler
),你会有很多(每次多一个)EventHandler
s 图 Line
s.
您只需要注册所有合适的EventHandler
一次并在其中执行逻辑。
这是一个小例子:
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;
}
}