我已经为 java fx 创建了一个程序来输入数组中的点。这些点将用在最大点之间绘制的线来显示。此外,如果您单击鼠标左键,它会添加一个点并重新计算最大点。如果右键单击,则会从显示中删除该点。我遇到的问题是我正在读取带有点的文件,但显示屏上没有显示任何内容。我什至尝试手动添加点,但显示屏上仍然没有显示任何内容。我错过了什么?
我已尽我所能来理解为什么没有显示任何点并且不知所措。我知道这很简单,但我无法弄清楚。 应从文本文件添加的点是 这是最初运行时的样子 这就是它实际的样子 我已经更正了鼠标事件,因此如果我单击左上角,它将添加点
Point.java
package application;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public final class Point implements Comparable<Point> {
private final double x;
private final double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public boolean isBelowAndLeftOf(Point other) {
return this.x <= other.getX() && this.y <= other.getY();
}
@Override
public int compareTo(Point other) {
return Double.compare(this.x, other.getX());
}
}
MaximalPointsPane.java
package application;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.scene.input.MouseButton;
import java.util.Collections;
import java.util.ArrayList;
public class MaximalPointsPane extends Pane {
private final ArrayList<Point> points;
private final ArrayList<Point> maximalPoints;
public MaximalPointsPane(ArrayList<Point> points) {
this.points = points;
this.maximalPoints = new ArrayList<>();
findMaximalPoints();
drawMaximalLines();
this.setOnMouseClicked(this::handleMouseClick);
}
private void findMaximalPoints() {
maximalPoints.clear();
for (Point p1 : points) {
boolean isMaximal = true;
for (Point p2 : points) {
if (p1 != p2 && p2.isBelowAndLeftOf(p1)) {
isMaximal = false;
break;
}
}
if (isMaximal) {
maximalPoints.add(p1);
}
}
}
private void drawMaximalLines() {
getChildren().clear();
for (int i = 0; i < maximalPoints.size() - 1; i++) {
Point p1 = maximalPoints.get(i);
Point p2 = maximalPoints.get(i + 1);
Line line = new Line(p1.getX(), p1.getY(), p2.getX(), p2.getY());
getChildren().add(line);
}
}
private void handleMouseClick(MouseEvent event) {
if (event.isPrimaryButtonDown()) {
// Left click
double x = event.getX();
double y = event.getY();
points.add(new Point(x, y));
findMaximalPoints();
drawMaximalLines();
} else if (event.isSecondaryButtonDown()) {
// Right click
double x = event.getX();
double y = event.getY();
Point pointToRemove = null;
for (Point p : points) {
if (Math.abs(p.getX() - x) < 5 && Math.abs(p.getY() - y) < 5) {
pointToRemove = p;
break;
}
}
if (pointToRemove != null) {
points.remove(pointToRemove);
findMaximalPoints();
drawMaximalLines();
}
}
}
}
Main.java
package application;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
ArrayList<Point> points = new ArrayList<>();
try {
File file = new File("points.txt");
Scanner scanner = new Scanner(file);
while (scanner.hasNext()) {
double x = scanner.nextDouble();
double y = scanner.nextDouble();
points.add(new Point(x, y));
}
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
MaximalPointsPane pane = new MaximalPointsPane(points);
Scene scene = new Scene(pane, 500, 500);
stage.setTitle("Maximal Points");
stage.setScene(scene);
stage.show();
}
}
方法
isPrimaryButtonDown()
(还有isSecondaryButtonDown()
)是这里使用的错误方法。请参阅文档。
基本上,按下并释放鼠标按钮时会发生鼠标单击。由于鼠标单击事件发生在释放之后,因此此时不会按下鼠标按钮。
而是使用
if (event.getButton() == MouseButton.PRIMARY)
等:
private void handleMouseClick(MouseEvent event) {
if (event.getButton() == MouseButton.PRIMARY) {
// Left click
double x = event.getX();
double y = event.getY();
points.add(new Point(x, y));
findMaximalPoints();
drawMaximalLines();
} else if (event.getButton() == MouseButton.SECONDARY) {
// Right click
double x = event.getX();
double y = event.getY();
Point pointToRemove = null;
for (Point p : points) {
if (Math.abs(p.getX() - x) < 5 && Math.abs(p.getY() - y) < 5) {
pointToRemove = p;
break;
}
}
if (pointToRemove != null) {
points.remove(pointToRemove);
findMaximalPoints();
drawMaximalLines();
}
}
}
或者,等效地,使用 switch 语句:
private void handleMouseClick(MouseEvent event) {
switch (event.getButton()) {
case PRIMARY -> {
// Left click
double x = event.getX();
double y = event.getY();
points.add(new Point(x, y));
findMaximalPoints();
drawMaximalLines();
}
case SECONDARY -> {
// Right click
double x = event.getX();
double y = event.getY();
Point pointToRemove = null;
for (Point p : points) {
if (Math.abs(p.getX() - x) < 5 && Math.abs(p.getY() - y) < 5) {
pointToRemove = p;
break;
}
}
if (pointToRemove != null) {
points.remove(pointToRemove);
findMaximalPoints();
drawMaximalLines();
}
}
}
}
我不相信你计算“最大点”的逻辑。由于您没有提供“最大点”的定义或测试文件,因此无法说明为什么您没有从文件中看到任何点。上述更改在单击窗格后在某些情况下确实会显示一些点和线。