Skip to content
Advertisement

Adding hover listener to cells of a specific column in javafx table

I want to create a OnMouseOver Listener to cells of a specific column of a TableView, such that a popup window should appeared with some message, when I hover to it’s cells. This is how I am creating a table and its columns.

private TableView<Stock> stockTable = new TableView<>();
ObservableList columns = stockTable.getColumns();
public TableColumn createTextColumn(String columnName, String columnCaption,BooleanProperty editingStarted) {
    TableColumn column = new TableColumn(columnCaption);
    column.setCellValueFactory(new PropertyValueFactory<>(columnName));
    column.setCellFactory(TextFieldTableCell.forTableColumn());
    return column;
}
final TableColumn nameColumn 
                         = createTextColumn("name", "Product Name", editingStarted);
columns.add(nameColumn);

So is it possible to do it. I know how to create listeners for rows. But I found nothing on internet on listening to cells of table. Thanks in advance for any help.

Advertisement

Answer

You already used the TextFieldTableCell.forTableColumn() which you need to rewrite to suit your needs

import javafx.event.EventHandler;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.input.MouseEvent;
import javafx.stage.Popup;
import javafx.util.Callback;
import javafx.util.StringConverter;
import javafx.util.converter.DefaultStringConverter;

public final class CustomTextFieldTableCell<S, T> extends TextFieldTableCell<S, T> {

    public static <S> Callback<TableColumn<S, String>, TableCell<S, String>> forTableColumn() {
        return forTableColumn(new DefaultStringConverter());
    }

    public static <S, T> Callback<TableColumn<S, T>, TableCell<S, T>> forTableColumn(final StringConverter<T> converter) {
        return new Callback<TableColumn<S, T>, TableCell<S, T>>() {
            @Override
            public TableCell<S, T> call(TableColumn<S, T> list) {
                final TextFieldTableCell<S, T> result = new TextFieldTableCell<S, T>(converter);
                final Popup popup = new Popup();
                popup.setAutoHide(true);

                final EventHandler<MouseEvent> hoverListener = new EventHandler<MouseEvent>() {

                    @Override
                    public void handle(MouseEvent event) {
                        final Label popupContent = new Label("this is a popup showing the content = '" + result.getText() + "'");
                        popupContent.setStyle("-fx-background-color: #64b5f6; -fx-border-color: #000000; -fx-border-width: 1px; -fx-padding: 5px; -fx-text-fill: white;");

                        popup.getContent().clear();
                        popup.getContent().addAll(popupContent);

                        if (event.getEventType() == MouseEvent.MOUSE_EXITED) {
                            popup.hide();
                        } else if (event.getEventType() == MouseEvent.MOUSE_ENTERED) {
                            popup.show(result, event.getScreenX() + 10, event.getScreenY());                
                        }
                    }
                };

                result.setOnMouseEntered(hoverListener);
                result.setOnMouseExited(hoverListener);
                return result;
            }
        };
    }
}

To use it you need to change your code to

column.setCellFactory(CustomTextFieldTableCell.forTableColumn());

The result looks like this

enter image description here

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement