Java 将EventHandler添加到标签中包含的ImageView
我最近开始探索JavaFX,并希望创建一个自定义标签,其中包含一个ImageView 这是我的自定义标签的代码Java 将EventHandler添加到标签中包含的ImageView,java,javafx,imageview,eventhandler,mouseclick-event,Java,Javafx,Imageview,Eventhandler,Mouseclick Event,我最近开始探索JavaFX,并希望创建一个自定义标签,其中包含一个ImageView 这是我的自定义标签的代码 Image image = new Image(getClass().getResourceAsStream("/img/remove.png"), 20, 20, true, true); ImageView removeImageView = new ImageView(image); Label customLabel = new Label(labelText, remove
Image image = new Image(getClass().getResourceAsStream("/img/remove.png"), 20, 20, true, true);
ImageView removeImageView = new ImageView(image);
Label customLabel = new Label(labelText, removeImageView);
customLabel.setFont(Font.font("Arial", FontWeight.BOLD, 20));
这就是我的自定义标签的外观
现在我想向ImageView添加鼠标单击事件处理程序。这是我处理鼠标点击的代码
removeImageView.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
System.out.println("Imageview Clicked");
}
});
removeImageView.addEventHandler(MouseEvent.MOUSE_单击,新建事件处理程序(){
@凌驾
公共无效句柄(MouseeEvent事件){
System.out.println(“单击Imageview”);
}
});
但是,当我单击十字
图像时,事件没有被捕获
我做了一点实验,试图向customLabel
添加一个EventHandler。标签能够捕捉鼠标点击
在我看来,我面临这个问题是因为ImageView包含在标签中。我想知道的是,这是对JFX的限制,还是有其他方法可以实现这一功能。谢谢。这似乎是修复的结果。将以下内容添加到
LabeledSkinBase#updateChildren()
:
如您所见,当标签为的控件的图形为图像视图时,它被设置为鼠标透明。解决方法是将ImageView
的鼠标透明度设置回false
ImageView view = new ImageView();
view.mouseTransparentProperty().addListener((observable, oldVal, newVal) -> {
if (newVal) {
view.setMouseTransparent(false);
}
});
由于您没有使用CSS根据悬停/待命状态更改图像,因此不应导致与错误相关的问题。不过,我会谨慎行事;以防万一
@fabian提到的一个更好的解决方法是将
图像视图
包装在其他一些节点
(例如窗格
)中
这使图形成为一个
窗格
,这意味着updateChildren()
中的特殊ImageView
处理不会发生。这似乎是修复的结果。将以下内容添加到LabeledSkinBase#updateChildren()
:
如您所见,当标签为的控件的图形为图像视图时,它被设置为鼠标透明。解决方法是将ImageView
的鼠标透明度设置回false
ImageView view = new ImageView();
view.mouseTransparentProperty().addListener((observable, oldVal, newVal) -> {
if (newVal) {
view.setMouseTransparent(false);
}
});
由于您没有使用CSS根据悬停/待命状态更改图像,因此不应导致与错误相关的问题。不过,我会谨慎行事;以防万一
@fabian提到的一个更好的解决方法是将
图像视图
包装在其他一些节点
(例如窗格
)中
这使得图形成为一个
窗格
,这意味着在updateChildren()
中不进行特殊的ImageView
处理。另一个鼠标透明的ImageView
解决方法是处理ImageView
父级(标签
)上的事件并重新触发它:
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class PropegateEvent extends Application {
@Override
public void start(Stage stage) {
Image image = new Image("https://addons-media.operacdn.com/media/extensions/65/165965/1.1.0.0-rev1/icons/icon_64x64_6dd346d4c61d287ae74c612622d1353f.png");
ImageView removeImageView = new ImageView(image);
Label customLabel = new Label("rito", removeImageView);
Pane root = new Pane(customLabel);
stage.setScene(new Scene(root));
//////////////////////////////////////////////////////////////
//handle mouse event click on label - refire it as image view event:
customLabel.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> removeImageView.fireEvent(event));
///////////////////////////////////////////////////////////////
removeImageView.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
System.out.println("Imageview Clicked");
event.consume();
}
});
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
导入javafx.application.application;
导入javafx.event.EventHandler;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.image.image;
导入javafx.scene.image.ImageView;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.layout.Pane;
导入javafx.stage.stage;
公共类PropegateEvent扩展应用程序{
@凌驾
公众假期开始(阶段){
图像=新图像(“https://addons-media.operacdn.com/media/extensions/65/165965/1.1.0.0-rev1/icons/icon_64x64_6dd346d4c61d287ae74c612622d1353f.png");
ImageView removeImageView=新的ImageView(图像);
标签customLabel=新标签(“rito”,removeImageView);
窗格根=新窗格(自定义标签);
舞台场景(新场景(根));
//////////////////////////////////////////////////////////////
//处理鼠标事件单击标签-将其重新刷新为图像视图事件:
customLabel.addEventHandler(MouseEvent.MOUSE_单击,事件->removeImageView.fireEvent(事件));
///////////////////////////////////////////////////////////////
removeImageView.addEventHandler(单击MouseEvent.MOUSE_,新建EventHandler()){
@凌驾
公共无效句柄(MouseeEvent事件){
System.out.println(“单击Imageview”);
event.consume();
}
});
stage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}
另一个鼠标透明的ImageView
解决方案(请参阅)是处理ImageView
父级(Lable
)上的事件并重新触发它:
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class PropegateEvent extends Application {
@Override
public void start(Stage stage) {
Image image = new Image("https://addons-media.operacdn.com/media/extensions/65/165965/1.1.0.0-rev1/icons/icon_64x64_6dd346d4c61d287ae74c612622d1353f.png");
ImageView removeImageView = new ImageView(image);
Label customLabel = new Label("rito", removeImageView);
Pane root = new Pane(customLabel);
stage.setScene(new Scene(root));
//////////////////////////////////////////////////////////////
//handle mouse event click on label - refire it as image view event:
customLabel.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> removeImageView.fireEvent(event));
///////////////////////////////////////////////////////////////
removeImageView.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
System.out.println("Imageview Clicked");
event.consume();
}
});
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
导入javafx.application.application;
导入javafx.event.EventHandler;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.image.image;
导入javafx.scene.image.ImageView;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.layout.Pane;
导入javafx.stage.stage;
公共类PropegateEvent扩展应用程序{
@凌驾
公众假期开始(阶段){
图像=新图像(“https://addons-media.operacdn.com/media/extensions/65/165965/1.1.0.0-rev1/icons/icon_64x64_6dd346d4c61d287ae74c612622d1353f.png");
ImageView removeImageView=新的ImageView(图像);
标签customLabel=新标签(“rito”,removeImageView);
窗格根=新窗格(自定义标签);
舞台场景(新场景(根));
//////////////////////////////////////////////////////////////
//处理鼠标事件单击标签-将其重新刷新为图像视图事件:
customLabel.addEventHandler(MouseEvent.MOUSE_单击,事件->removeImageView.fireEvent(事件));
///////////////////////////////////////////////////////////////
removeImageView.addEventHandler(单击MouseEvent.MOUSE_,新建EventHandler()){
@凌驾
公共无效句柄(MouseeEvent事件){
System.out.println(“单击Imageview”);
event.consume();
ImageView removeImageView = new ImageView(image);
Label customLabel = new Label("rito");
customLabel.setFont(Font.font("Arial", FontWeight.BOLD, 20));
HBox hbox = new HBox(removeImageView,customLabel);
root.getChildren().add(hbox);
removeImageView.setOnMouseClicked(e->{
System.out.println("ImageView clicked");
});
customLabel.setOnMouseClicked(e->{
System.out.println("Lable clicked");
});