小编典典

onScroll侦听器在JavaFX 2的TableView中不起作用

java

我正在尝试使用TableView组件的onScroll事件侦听器:

FXML:

<TableView fx:id="table" onScroll="#doSomething" tableMenuButtonVisible="true" VBox.vgrow="ALWAYS">
    <columnResizePolicy>
        <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
    </columnResizePolicy>
</TableView>

Java控制器:

@FXML
void doSomething(ActionEvent event)
{
    System.out.println("Object: " + event.getSource());
}

但这不起作用!我做错了什么?

我需要捕获垂直滚动器以手动控制滚动位置并根据向下或向上滚动获取相关数据。

谢谢大家!


阅读 237

收藏
2020-11-30

共1个答案

小编典典

我认为可能发生的情况是TableView包含的自身正在消耗scroll事件并在内部对其进行处理,因此它永远不会到达您的应用程序处理程序。

最初,我认为您可能要使用onScrollTo而不是onScroll,但这似乎并不能真正解决问题。

我认为有效的解决方案是在滚动事件上应用过滤器。

此外,您可以编写代码来使用scrollTo“手动控制滚动位置”的调用。

这是您可以尝试的一些示例代码(Java 8):

TableScrollerApp.java

package finder;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class TableScrollerApp extends Application {
    @Override public void start(final Stage stage) throws Exception {
        FXMLLoader loader = new FXMLLoader(
            getClass().getResource("tablescroller.fxml")
        );
        Parent parent = loader.load();

        stage.setScene(new Scene(new Group(parent)));
        stage.show();
    }

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

TableScrollerController.java

package finder;

import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.fxml.FXML;
import javafx.scene.control.ScrollToEvent;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.ScrollEvent;

import java.util.Arrays;
import java.util.stream.Collectors;

public class TableScrollerController {
    private static final String[] fruitNames = {
            "apples", "oranges", "pears", "peaches", 
            "guavas", "bananas", "jackfruit", "durians"
    };

    @FXML
    private TableView<Fruit> fruitsTable;

    @FXML
    private TableColumn<Fruit, String> fruitsColumn;

    @FXML
    protected void initialize() {
        fruitsColumn.setCellValueFactory(new PropertyValueFactory<>("name"));

        fruitsTable.addEventFilter(ScrollEvent.ANY, event ->
                System.out.println("Coded scroll filter: " + event)
        );

        fruitsTable.getItems().setAll(
                Arrays.stream(fruitNames)
                        .map(Fruit::new)
                        .collect(Collectors.toList())
        );

        fruitsTable.scrollTo(5);
    }

    @FXML
    protected void onScrollHandler(ScrollEvent scrollEvent) {
        System.out.println("FXML referenced scroll handler: " + scrollEvent);
    }

    @FXML
    protected void onScrollToHandler(ScrollToEvent<Integer> scrollToEvent) {
        System.out.println("FXML referenced onScroll handler: " + scrollToEvent);
    }

    public static class Fruit {
        private ReadOnlyStringWrapper name;

        public Fruit(String name) {
            this.name = new ReadOnlyStringWrapper(name);
        }

        public String getName() {
            return name.get();
        }

        public ReadOnlyStringProperty nameProperty() {
            return name;
        }
    }
}

tablecroller.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>

<TableView fx:id="fruitsTable" 
           maxHeight="-Infinity" maxWidth="-Infinity" 
           minHeight="-Infinity" minWidth="-Infinity" 
           onScroll="#onScrollHandler" 
           onScrollTo="#onScrollToHandler" 
           prefHeight="100.0" prefWidth="250.0" 
           xmlns="http://javafx.com/javafx/8" 
           xmlns:fx="http://javafx.com/fxml/1" 
           fx:controller="finder.TableScrollerController">
  <columns>
    <TableColumn fx:id="fruitsColumn" 
                 maxWidth="800.0" minWidth="200.0" prefWidth="-1.0" 
                 text="Fruits" />
  </columns>
</TableView>
2020-11-30