创建不规则形状的 JavaFX 组件
Creating irregular shaped JavaFX component
我正在尝试为 JavaFX 制作一个不规则形状的组件,但遇到了非常奇怪的行为。
package pkg;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
import javafx.event.EventHandler;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
public class App extends Application {
private static Scene scene;
@Override
public void start(Stage stage) throws IOException {
Pane pane = new Pane();
for (int x = 50; x < 150; x += 50) {
for (int y = 50; y < 150; y += 50) {
pane.getChildren().add(new Triangle(x, y));
}
}
scene = new Scene(pane, 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
private static class Triangle extends Region {
Polygon p;
public Triangle(int x, int y) {
super();
p = new Polygon(x - 25, y + 25, x, y - 25, x + 25, y + 25);
setOnMouseEntered(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
p.setFill(Color.RED);
System.out.println("x: " + x + " y: " + y);
}
});
setOnMouseExited(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
p.setFill(Color.BLACK);
}
});
setShape(p);
getChildren().add(p);
}
}
}
依赖关系:
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>15.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>13</version>
</dependency>
</dependencies>
当这是 运行 时,它会创建 4 个三角形,每个三角形都有鼠标悬停行为。
但是,当您将鼠标悬停在每个三角形上时,它们都表现得好像右下角的三角形被触发了。
这不直观。我不太清楚那是什么。
这里发生了什么,我如何让这些组件独立反应?
默认情况下,区域的边界将从 [0,0]
开始并扩展以填充所有子项所需的 space。因此,您创建的最后一个三角形实际上具有覆盖所有其他三角形的边界,并且由于它位于堆栈的最顶部(因为您最后添加它),它接收所有鼠标事件。
如果你将每个三角形推到后面(这不是一个特别好的解决方案),你会看到你想要的:
for (int x = 50; x < 150; x += 50) {
for (int y = 50; y < 150; y += 50) {
Triangle t = new Triangle(x, y);
pane.getChildren().add(t);
t.toBack();
}
}
另一个解决方案是添加
setPickOnBounds(false) ;
到 Triangle
构造函数。这只会在鼠标悬停在 Triangle
.
的非透明部分上时触发鼠标事件
也许您应该创建仅占用 space 他们真正需要的区域。您可能还需要 setPickOnBounds(false)
调用,因此三角形仅响应鼠标悬停在三角形部分(而不是包含它的完整矩形区域)上:
private static class Triangle extends Region {
Polygon p;
public Triangle() {
super();
p = new Polygon(0, 50, 25, 0, 50, 50);
setOnMouseEntered(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
p.setFill(Color.RED);
}
});
setOnMouseExited(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
p.setFill(Color.BLACK);
}
});
setShape(p);
getChildren().add(p);
setPickOnBounds(false);
}
}
然后您可以按照通常的方式将三角形放置在它们的包含窗格中:
Pane pane = new Pane();
for (int x = 25; x < 125; x += 50) {
for (int y = 25; y < 125; y += 50) {
Triangle t = new Triangle();
pane.getChildren().add(t);
t.setLayoutX(x);
t.setLayoutY(y);
}
}
他们还将使用布局窗格:
GridPane pane = new GridPane();
for (int x = 0; x < 2; x++) {
for (int y = 0; y < 2; y++) {
Triangle t = new Triangle();
pane.add(t, x, y);
}
}
我正在尝试为 JavaFX 制作一个不规则形状的组件,但遇到了非常奇怪的行为。
package pkg;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
import javafx.event.EventHandler;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
public class App extends Application {
private static Scene scene;
@Override
public void start(Stage stage) throws IOException {
Pane pane = new Pane();
for (int x = 50; x < 150; x += 50) {
for (int y = 50; y < 150; y += 50) {
pane.getChildren().add(new Triangle(x, y));
}
}
scene = new Scene(pane, 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
private static class Triangle extends Region {
Polygon p;
public Triangle(int x, int y) {
super();
p = new Polygon(x - 25, y + 25, x, y - 25, x + 25, y + 25);
setOnMouseEntered(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
p.setFill(Color.RED);
System.out.println("x: " + x + " y: " + y);
}
});
setOnMouseExited(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
p.setFill(Color.BLACK);
}
});
setShape(p);
getChildren().add(p);
}
}
}
依赖关系:
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>15.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>13</version>
</dependency>
</dependencies>
当这是 运行 时,它会创建 4 个三角形,每个三角形都有鼠标悬停行为。
但是,当您将鼠标悬停在每个三角形上时,它们都表现得好像右下角的三角形被触发了。
这不直观。我不太清楚那是什么。
这里发生了什么,我如何让这些组件独立反应?
默认情况下,区域的边界将从 [0,0]
开始并扩展以填充所有子项所需的 space。因此,您创建的最后一个三角形实际上具有覆盖所有其他三角形的边界,并且由于它位于堆栈的最顶部(因为您最后添加它),它接收所有鼠标事件。
如果你将每个三角形推到后面(这不是一个特别好的解决方案),你会看到你想要的:
for (int x = 50; x < 150; x += 50) {
for (int y = 50; y < 150; y += 50) {
Triangle t = new Triangle(x, y);
pane.getChildren().add(t);
t.toBack();
}
}
另一个解决方案是添加
setPickOnBounds(false) ;
到 Triangle
构造函数。这只会在鼠标悬停在 Triangle
.
也许您应该创建仅占用 space 他们真正需要的区域。您可能还需要 setPickOnBounds(false)
调用,因此三角形仅响应鼠标悬停在三角形部分(而不是包含它的完整矩形区域)上:
private static class Triangle extends Region {
Polygon p;
public Triangle() {
super();
p = new Polygon(0, 50, 25, 0, 50, 50);
setOnMouseEntered(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
p.setFill(Color.RED);
}
});
setOnMouseExited(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
p.setFill(Color.BLACK);
}
});
setShape(p);
getChildren().add(p);
setPickOnBounds(false);
}
}
然后您可以按照通常的方式将三角形放置在它们的包含窗格中:
Pane pane = new Pane();
for (int x = 25; x < 125; x += 50) {
for (int y = 25; y < 125; y += 50) {
Triangle t = new Triangle();
pane.getChildren().add(t);
t.setLayoutX(x);
t.setLayoutY(y);
}
}
他们还将使用布局窗格:
GridPane pane = new GridPane();
for (int x = 0; x < 2; x++) {
for (int y = 0; y < 2; y++) {
Triangle t = new Triangle();
pane.add(t, x, y);
}
}