我在JavaFX中使用GluonHQ Maps 1.0.3,并且在地图上绘制节点时遇到问题。
我有一个类GridMapController
,其中有一个名为MapView
的gridMap
。
我还有一个类GridPaintLayer
扩展了MapLayer
并完成了所有绘画的工作。使用方法GridPaintLayer
将GridMapController
添加到gridMap
的gridMap.addLayer(gridPaintLayer)
中。此类(GridPaintLayer
)具有方法addNode(NodeInputModel)
,我将传递一个要绘制的节点(包含经纬度值)传递给该方法。可以右键单击提到的gridMap
(MapView
),然后打开一个弹出菜单,我可以在其中选择“创建节点”。这将调用在createNodeItemClicked()
中实现的方法GridPaintLayer
(请参见下文)。当我单击“创建节点”菜单项时,一切正常,并且一个点出现在地图上。
在程序的另一部分,我有一个可观察的对象,每当添加一个节点时,该对象就会通知其观察者。通知消息在GridMapController
中处理,然后从addNode()
调用GridPaintLayer
方法。但是现在,当我希望GridPaintLayer's
baseMap
计算场景上的点位置时,方法baseMap.getMapPoint(double lat, double lon)
返回null
,因为baseMap的场景是null
。因此无法绘制节点。
发生这种情况,即当我想在应用程序的另一部分创建节点时。观察者正确地通知了GridMapController
(等等),但是问题如上所述出现。
下面的方法都在GridPaintLayer
类中实现。
public void addNode(NodeInputModel nodeInputModel) {
Circle circle = new Circle(7, Color.RED);
circle.setCursor(Cursor.HAND);
circle.setVisible(true);
paintedNodes.put(nodeInputModel, circle);
Point2D mapPoint = baseMap.getMapPoint(nodeInputModel.getLat(), nodeInputModel.getLon());
if(mapPoint != null) {
circle.setTranslateX(mapPoint.getX());
circle.setTranslateY(mapPoint.getY());
} else {
System.out.println("Could not calculate node position, baseMap scene = null: " + (baseMap.getScene() == null));
}
AtomicReference<Double> orgSceneX = new AtomicReference<>(0d);
AtomicReference<Double> orgSceneY = new AtomicReference<>(0d);
circle.setOnMousePressed(mousePressedEvent -> {...});
circle.setonMouseClicked(mouseEvent -> {...});
this.getChildren().add(circle);
this.markDirty();
}
public void createNodeItemClicked(MouseEvent mouseEvent) {
// Convert mouseEvent position to geo position
MapPoint mapPoint = baseMap.getMapPosition(mouseEvent.getX(), mouseEvent.getY());
LatLon latLon = new LatLon(mapPoint.getLatitude(), mapPoint.getLongitude());
Point geoPosition = Utils.latlonToPoint(latLon);
// Create NodeInputModel
NodeInputModel nodeInputModel = new NodeInputModel();
nodeInputModel.setGeoPosition(geoPosition);
// TODO: set the other parameters
// Add node to Map
addNode(nodeInputModel);
// Send update message to GridModel
UpdateMessage updateMessage =
new UpdateMessage(null, Arrays.asList(nodeInputModel), UpdateMessage.UpdateType.ADD);
gridMapController.sendUpdateMessage(updateMessage);
}
我尝试了几种方法来“重新激活”场景,但是没有任何效果。有没有办法做到这一点?
我希望我已经清楚地解释了一切。如果没有,请随时询问。
编辑:
我正在使用多个FXML文件。根FXML(MainView.fxml):
<VBox xmlns="http://javafx.com/javafx/8.0.172-ea"
xmlns:fx="http://javafx.com/fxml/1"
fx:id="main"
fx:controller="edu.ie3.controller.main.MainController">
<fx:include fx:id="io" source="IoView.fxml"/>
<fx:include fx:id="tool" source="ToolView.fxml"/>
<HBox prefHeight="${main.height}">
<!-- vertical button bar for grid info -->
<ButtonBar fx:id="leftButtonBar" rotate="-90">
<buttons>
<Button fx:id="gridInfoButton" text="Grid Info"/>
</buttons>
</ButtonBar>
<SplitPane fx:id="splitPane" prefWidth="${main.width}">
<fx:include fx:id="gridTab" source="GridTabView.fxml"/>
</SplitPane>
</HBox>
<fx:define>
<fx:include fx:id="gridInfo" source="GridInfoView.fxml"/>
<fx:include fx:id="gridMap" source="GridMapView.fxml"/>
<fx:include fx:id="gridSchema" source="GridSchemaView.fxml"/>
</fx:define>
</VBox>
包含GridMapView的Splitpane:
<TabPane
xmlns="http://javafx.com/javafx/8.0.172-ea"
xmlns:fx="http://javafx.com/fxml/1"
tabClosingPolicy="UNAVAILABLE"
fx:id="gridTabPane"
fx:controller="edu.ie3.controller.gridTab.GridTabController">
<Tab fx:id="gridMapTab" text="Map View">
<fx:include fx:id="gridMapLayer" source="GridMapView.fxml"/>
</Tab>
<Tab fx:id="gridSchemaTab" text="Schema View">
<fx:include fx:id="gridSchema" source="GridSchemaView.fxml"/>
</Tab>
</TabPane>
GridMapView.fxml如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<?import com.gluonhq.maps.MapView?>
<MapView xmlns="http://javafx.com/javafx/8.0.172-ea"
xmlns:fx="http://javafx.com/fxml/1"
fx:id="gridMap"
fx:controller="edu.ie3.controller.gridTab.gridMap.GridMapController">
</MapView>
我已经尝试注释掉某些语句,以避免包括GridMapView在内的双重内容,但是没有任何效果。
最佳答案
我解决了
问题是我在MainController中一次包含了GridMapController,在GridTabController中一次包含了GridMapController。我从MainController中删除了fx:include
,现在GridMapController仅初始化一次。
不过,非常感谢您,何塞·佩雷达(JoséPereda),您以正确的方式带给了我。