我尝试构建由区域(状态)组成的地图,当鼠标进入某个区域时,我需要处理它。有许多png图像分别代表每个区域。我混合了我的图像,得到了我想要的东西,但是我无法处理某个区域。
例如:
它是第一个区域img
代码:
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("view/MapView.fxml"));
Pane root = loader.load();
primaryStage.setTitle("Map");
primaryStage.setScene(new Scene(root, 700, 700));
primaryStage.show();
//First region
File file = new File("src/res/img/region1.png");
Canvas canvas = new Canvas(700, 700);
canvas.addEventHandler(MouseEvent.MOUSE_ENTERED_TARGET, event -> System.out.println("Region 1"));
GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
graphicsContext.drawImage(new Image(file.toURI().toString()), 0, 0);
root.getChildren().add(canvas);
//Second region
file = new File("src/res/img/region2.png");
canvas = new Canvas(700, 700);
canvas.addEventHandler(MouseEvent.MOUSE_ENTERED_TARGET, event -> System.out.println("Region 2"));
graphicsContext = canvas.getGraphicsContext2D();
graphicsContext.drawImage(new Image(file.toURI().toString()), 0, 0);
root.getChildren().add(canvas);
}
在控制台中,我总是得到#34;区域2"。
请给我研究提示。提前谢谢!
答案 0 :(得分:3)
您可以使用ImageView和setPickOnBounds。
示例代码:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class LayersWithMouseEvents extends Application {
@Override
public void start(Stage primaryStage) {
// root
StackPane root = new StackPane();
// create layers
Pane region1Layer = new Pane();
Pane region2Layer = new Pane();
// add layers
root.getChildren().addAll(region1Layer, region2Layer);
// load images
ImageView region1ImageView = new ImageView( new Image( getClass().getResource("region1.png").toExternalForm()));
ImageView region2ImageView = new ImageView( new Image( getClass().getResource("region2.png").toExternalForm()));
// add images
region1Layer.getChildren().add(region1ImageView);
region2Layer.getChildren().add(region2ImageView);
// mouse handler
region1Layer.setOnMousePressed(e -> System.out.println("Region 1: " + e));
region2Layer.setOnMousePressed(e -> System.out.println("Region 2: " + e));
// this is the magic that allows you to click on the separate layers, but ONLY(!) as long as the layer is transparent
region1Layer.setPickOnBounds(false);
region2Layer.setPickOnBounds(false);
primaryStage.setScene(new Scene(root, 800, 600));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
将来请创建MCVE,重点是完整。没有人愿意浪费时间让你的不完整的例子发挥作用。
答案 1 :(得分:2)
我认为在这里使用画布不是正确的方法。如果要将区域定义为多边形并将它们添加到场景图中,则可以将侦听器附加到每个多边形,然后如果鼠标位于某个区域上,则会做出相应的反应。也许这对于图像视图也是可能的,但我从未尝试过图像的透明区域也是鼠标透明的,在这种情况下似乎是必要的。对于我的程序,我使用了多边形,它很好用。
答案 2 :(得分:2)
图像数据可用于确定鼠标光标下像素的颜色。如果像素不是完全透明的,那么光标就在该区域上。
要检索此信息,您需要为鼠标移动事件使用侦听器。为简单起见,您可以使用附加了侦听器的属性来触发区域进入/离开事件:
以下示例假设您保留对用于名为image1
和image2
的区域的图像的引用:
PixelReader reader1 = image1.getPixelReader();
PixelReader reader2 = image2.getPixelReader();
SimpleIntegerProperty region = new SimpleIntegerProperty(-1);
region.addListener((observable, oldValue, newValue) -> {
if (newValue.intValue() < 0) {
System.out.println("region left");
} else {
System.out.println("Region " + (newValue.intValue() + 1));
}
});
canvas.setOnMouseMoved(event -> {
int x = (int) event.getX();
int y = (int) event.getY();
if (x < image1.getWidth() && y < image1.getHeight() && reader1.getColor(x, y).getOpacity() != 0) {
region.set(0);
} else if (x < image2.getWidth() && y < image2.getHeight() && reader2.getColor(x, y).getOpacity() != 0) {
region.set(1);
} else {
region.set(-1);
}
});
此外,无需创建多个Canvas
来绘制图像。