Javafx ListCell中的图形如何捕获MouseEvents?

时间:2016-02-16 22:14:24

标签: javafx

我有一个带有ImageView的自定义ListCell作为图形。我希望这个ImageView能够捕获MouseEvents(如mouse_over或mouse_click)。但它没有发现任何事件。 然而,自定义ListCell会捕获事件。

这是不寻常的行为还是我需要将事件从ListCell传递到其图形(以某种方式)? 如果我添加一个Button,奇怪的是它会获得Mouseevents。 如果你只是一个工作示例的链接,我会很高兴地通过它爬行;) 谢谢你的努力。

Class CustomCell:

package test;

import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.ListCell;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;

public class CustomCell extends ListCell<String>{
    ImageView removeTrack;

public CustomCell(){
    removeTrack = new ImageView("https://lh3.googleusercontent.com/-lbN1Ca63JPs/AAAAAAAAAAI/AAAAAAAAAAQ/smvshnyosS4/s46-c-k/photo.jpg");
    removeTrack.setOnMouseClicked(e -> {
        System.out.println("test");
    });
}

    @Override
    protected void updateItem(String t, boolean bln) {
        super.updateItem(t, bln);
        if (t != null) {
            setText(t);
            setGraphic(removeTrack);
            setContentDisplay(ContentDisplay.RIGHT);
            addEventFilter(MouseEvent.MOUSE_MOVED, new EventHandler<MouseEvent>() {

                @Override
                public void handle(MouseEvent arg0) {
                    removeTrack.setVisible(true);
                }
            });
            addEventFilter(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>() {

                @Override
                public void handle(MouseEvent arg0) {
                    removeTrack.setVisible(false);
                }
            });
        }
    }

}

主类:

package test;


import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
import javafx.util.Callback;

public class JAVAtest extends Application{

 public static void main(String[] args) {
     launch(args);

 }

@Override
public void start(Stage stage) throws Exception {
    ObservableList<String> names = FXCollections.observableArrayList(
              "Julia", "Ian", "Sue", "Matthew", "Hannah", "Stephan", "Denise");
    ListView lv = new ListView(names);
    lv.setCellFactory(new Callback<ListView<String>, ListCell<String>>(){

        @Override
        public ListCell<String> call(ListView<String> p) {
             return new CustomCell();
        }
    });
    Scene scene = new Scene(lv);



    stage.setScene(scene);
    stage.show();
}


}

1 个答案:

答案 0 :(得分:1)

嗯..我看不出为什么你的代码不能正常工作。看起来像一个错误。

如果将图像视图包装在某种容器中,它可以正常工作。例如:

import javafx.event.EventHandler;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.ListCell;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;

public class CustomCell extends ListCell<String> {
    ImageView removeTrack;
    StackPane imageContainer ;

    public CustomCell() {
        removeTrack = new ImageView(
                "https://lh3.googleusercontent.com/-lbN1Ca63JPs/AAAAAAAAAAI/AAAAAAAAAAQ/smvshnyosS4/s46-c-k/photo.jpg");
        removeTrack.setOnMouseClicked(e -> {
            System.out.println("test");
        });
        imageContainer = new StackPane(removeTrack);
    }

    @Override
    protected void updateItem(String t, boolean bln) {
        super.updateItem(t, bln);
        if (t != null) {
            setText(t);
            setGraphic(imageContainer);
            setContentDisplay(ContentDisplay.RIGHT);
            addEventFilter(MouseEvent.MOUSE_MOVED, new EventHandler<MouseEvent>() {

                @Override
                public void handle(MouseEvent arg0) {
                    imageContainer.setVisible(true);
                }
            });
            addEventFilter(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>() {

                @Override
                public void handle(MouseEvent arg0) {
                    imageContainer.setVisible(false);
                }
            });
        } else {
            setText(null);
            setGraphic(null);
        }
    }

}

(顺便说一下:总是处理updateItem(...)方法中的所有可能情况。如果你开始删除项目或者可能在滚动时你的代码会有bug,因为你不处理空单元格/空项目案例。)