如何使用区域选择构建地图?

时间:2016-02-06 17:01:30

标签: java javafx

我尝试构建由区域(状态)组成的地图,当鼠标进入某个区域时,我需要处理它。有许多png图像分别代表每个区域。我混合了我的图像,得到了我想要的东西,但是我无法处理某个区域
例如:
它是第一个区域img
enter image description here


这是第二个区域img enter image description here


结果我得到了: enter image description here

代码:

@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"。
请给我研究提示。提前谢谢!

3 个答案:

答案 0 :(得分:3)

您可以使用ImageViewsetPickOnBounds

示例代码:

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)

图像数据可用于确定鼠标光标下像素的颜色。如果像素不是完全透明的,那么光标就在该区域上。

要检索此信息,您需要为鼠标移动事件使用侦听器。为简单起见,您可以使用附加了侦听器的属性来触发区域进入/离开事件:

以下示例假设您保留对用于名为image1image2的区域的图像的引用:

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来绘制图像。