javafx:将参数传递给 fxml 文件中的事件处理函数
javafx : pass parameter to the eventhandler function in fxml file
有没有办法从包含 parameter
的 fxml file
调用 event handler
方法?请找到文件:
我的 Fxml 看起来像:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.cognizant.iotworkbench.View.AddImageController">
<children>
<Label layoutX="270.0" layoutY="14.0" text="Add Sensor" />
<BorderPane layoutY="-1.0" prefHeight="400.0" prefWidth="602.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<left>
<HBox fx:id="source" prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<ImageView fx:id="sourceimg" fitHeight="114.0" fitWidth="142.0" onDragDetected="#setUpGestureSource" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="file:Images/Project.png" />
</image>
</ImageView>
</children>
</HBox>
</left>
<right>
<HBox fx:id="target" onDragDropped="#setUpGestureTarget" onDragOver="#setUpGestureTarget" prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
</right>
</BorderPane>
</children>
</AnchorPane>
我的控制器class看起来像
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
/**
* FXML Controller class
*
*/
public class AddImage implements Initializable,ControlledScreen {
ScreensController myController;
/**
* Initializes the controller class.
*/
@FXML
final HBox target=new HBox();
@FXML
final HBox source=new HBox();
@FXML
final ImageView sourceimg=new ImageView();
@FXML
public void setUpGestureSource()
{
System.out.println("source");
source.setOnDragDetected(new EventHandler <MouseEvent>() {
@Override
public void handle(MouseEvent event) {
/* drag was detected, start drag-and-drop gesture*/
System.out.println("onDragDetected");
/* allow MOVE transfer mode */
Dragboard db = source.startDragAndDrop(TransferMode.COPY);
/* put a string on dragboard */
ClipboardContent content = new ClipboardContent();
Image sourceImage = sourceimg.getImage();
content.putImage(sourceImage);
db.setContent(content);
event.consume();
}
});
}
@FXML
public void setUpGestureTarget(){
System.out.println("target");
target.setOnDragOver(new EventHandler <DragEvent>() {
@Override
public void handle(DragEvent event) {
Dragboard db = event.getDragboard();
if(db.hasImage()){
event.acceptTransferModes(TransferMode.COPY);
}
event.consume();
}
});
target.setOnDragDropped(new EventHandler <DragEvent>() {
@Override
public void handle(DragEvent event) {
Dragboard db = event.getDragboard();
if(db.hasImage()){
insertImage(db.getImage(), target);
event.setDropCompleted(true);
}else{
event.setDropCompleted(false);
}
event.consume();
}
});
}
void insertImage(Image i, HBox hb){
ImageView iv = new ImageView();
iv.setImage(i);
setUpGestureSource();
hb.getChildren().add(iv);
}
@Override
public void setScreenParent(ScreensController screenParent) {
myController=screenParent;
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
拖放事件没有被触发。我不知道代码有什么问题。请帮助
所有用 @FXML
注释的方法 可能有也可能没有 有参数。如果需要参数,可以直接将specific Event
作为参数传递给方法。
让我们举个例子,假设您在 fxml 中为 HBox 添加了一个 onDragOver
事件。
<HBox fx:id="targetBox" onDragOver="#setupGestureTarget">
...
</HBox>
那么你可能有一个方法可以在控制器内部完成所需的工作class。
@FXML
public void setupGestureTarget(DragEvent event) {
Dragboard db = event.getDragboard();
if(db.hasImage()){
event.acceptTransferModes(TransferMode.COPY);
}
event.consume();
}
如果您需要调用该方法的源节点,您可以通过事件的 getSource()
访问它,然后将其类型转换为 Node
.
public void setupGestureTarget(DragEvent event) {
...
((Node)event.getSource()).setId("myHbox");
System.out.println(targetBox.getId()); // Prints - myHbox
}
注意: 要使用特定于 HBox
的方法,您可以将其类型转换为 HBox
而不是 Node
。
编辑 - 根据用户评论和更新
您的方法存在多个问题。让我来解决它们。
1.Values 到用 @FXML
注释的字段是在加载 FXML 时注入的,不应携带 new
关键字。
@FXML
final HBox target=new HBox();
应替换为
@FXML
final HBox target;
2.As 我已经说过你的方法可以有一个定义事件的参数。所以方法 setUpGestureSource()
和 setUpGestureTarget()
可以定义为:
@FXML
public void setUpGestureSource(DragEvent event) {
...
}
@FXML
public void setUpGestureTarget(DragEvent event) {
...
}
3.The方法setUpGestureSource
在ImageView
上出现drag-event
时调用,所以你不需要添加另一个 EventHandler
给它。
@FXML
public void setUpGestureSource(MouseEvent event) {
/* drag was detected, start drag-and-drop gesture*/
System.out.println("onDragDetected");
* allow MOVE transfer mode */
Dragboard db = source.startDragAndDrop(TransferMode.COPY);
/* put a string on dragboard */
ClipboardContent content = new ClipboardContent();
Image sourceImage = sourceimg.getImage();
content.putImage(sourceImage);
db.setContent(content);
event.consume();
}
同理,把另一种方法也改一下
有没有办法从包含 parameter
的 fxml file
调用 event handler
方法?请找到文件:
我的 Fxml 看起来像:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.cognizant.iotworkbench.View.AddImageController">
<children>
<Label layoutX="270.0" layoutY="14.0" text="Add Sensor" />
<BorderPane layoutY="-1.0" prefHeight="400.0" prefWidth="602.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<left>
<HBox fx:id="source" prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<ImageView fx:id="sourceimg" fitHeight="114.0" fitWidth="142.0" onDragDetected="#setUpGestureSource" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="file:Images/Project.png" />
</image>
</ImageView>
</children>
</HBox>
</left>
<right>
<HBox fx:id="target" onDragDropped="#setUpGestureTarget" onDragOver="#setUpGestureTarget" prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
</right>
</BorderPane>
</children>
</AnchorPane>
我的控制器class看起来像
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
/**
* FXML Controller class
*
*/
public class AddImage implements Initializable,ControlledScreen {
ScreensController myController;
/**
* Initializes the controller class.
*/
@FXML
final HBox target=new HBox();
@FXML
final HBox source=new HBox();
@FXML
final ImageView sourceimg=new ImageView();
@FXML
public void setUpGestureSource()
{
System.out.println("source");
source.setOnDragDetected(new EventHandler <MouseEvent>() {
@Override
public void handle(MouseEvent event) {
/* drag was detected, start drag-and-drop gesture*/
System.out.println("onDragDetected");
/* allow MOVE transfer mode */
Dragboard db = source.startDragAndDrop(TransferMode.COPY);
/* put a string on dragboard */
ClipboardContent content = new ClipboardContent();
Image sourceImage = sourceimg.getImage();
content.putImage(sourceImage);
db.setContent(content);
event.consume();
}
});
}
@FXML
public void setUpGestureTarget(){
System.out.println("target");
target.setOnDragOver(new EventHandler <DragEvent>() {
@Override
public void handle(DragEvent event) {
Dragboard db = event.getDragboard();
if(db.hasImage()){
event.acceptTransferModes(TransferMode.COPY);
}
event.consume();
}
});
target.setOnDragDropped(new EventHandler <DragEvent>() {
@Override
public void handle(DragEvent event) {
Dragboard db = event.getDragboard();
if(db.hasImage()){
insertImage(db.getImage(), target);
event.setDropCompleted(true);
}else{
event.setDropCompleted(false);
}
event.consume();
}
});
}
void insertImage(Image i, HBox hb){
ImageView iv = new ImageView();
iv.setImage(i);
setUpGestureSource();
hb.getChildren().add(iv);
}
@Override
public void setScreenParent(ScreensController screenParent) {
myController=screenParent;
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
拖放事件没有被触发。我不知道代码有什么问题。请帮助
所有用 @FXML
注释的方法 可能有也可能没有 有参数。如果需要参数,可以直接将specific Event
作为参数传递给方法。
让我们举个例子,假设您在 fxml 中为 HBox 添加了一个 onDragOver
事件。
<HBox fx:id="targetBox" onDragOver="#setupGestureTarget">
...
</HBox>
那么你可能有一个方法可以在控制器内部完成所需的工作class。
@FXML
public void setupGestureTarget(DragEvent event) {
Dragboard db = event.getDragboard();
if(db.hasImage()){
event.acceptTransferModes(TransferMode.COPY);
}
event.consume();
}
如果您需要调用该方法的源节点,您可以通过事件的 getSource()
访问它,然后将其类型转换为 Node
.
public void setupGestureTarget(DragEvent event) {
...
((Node)event.getSource()).setId("myHbox");
System.out.println(targetBox.getId()); // Prints - myHbox
}
注意: 要使用特定于 HBox
的方法,您可以将其类型转换为 HBox
而不是 Node
。
编辑 - 根据用户评论和更新
您的方法存在多个问题。让我来解决它们。
1.Values 到用 @FXML
注释的字段是在加载 FXML 时注入的,不应携带 new
关键字。
@FXML
final HBox target=new HBox();
应替换为
@FXML
final HBox target;
2.As 我已经说过你的方法可以有一个定义事件的参数。所以方法 setUpGestureSource()
和 setUpGestureTarget()
可以定义为:
@FXML
public void setUpGestureSource(DragEvent event) {
...
}
@FXML
public void setUpGestureTarget(DragEvent event) {
...
}
3.The方法setUpGestureSource
在ImageView
上出现drag-event
时调用,所以你不需要添加另一个 EventHandler
给它。
@FXML
public void setUpGestureSource(MouseEvent event) {
/* drag was detected, start drag-and-drop gesture*/
System.out.println("onDragDetected");
* allow MOVE transfer mode */
Dragboard db = source.startDragAndDrop(TransferMode.COPY);
/* put a string on dragboard */
ClipboardContent content = new ClipboardContent();
Image sourceImage = sourceimg.getImage();
content.putImage(sourceImage);
db.setContent(content);
event.consume();
}
同理,把另一种方法也改一下