【问题标题】:onScroll listener does not working in TableView in JavaFX 2onScroll 侦听器在 JavaFX 2 的 TableView 中不起作用
【发布时间】:2014-05-22 06:14:12
【问题描述】:

我正在尝试使用 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());
}

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

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

谢谢大家!

【问题讨论】:

    标签: java javafx


    【解决方案1】:

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

    最初,我认为您可能想要使用 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;
            }
        }
    }
    

    tablescroller.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>
    

    【讨论】:

    • 太棒了@jewelsea!添加过滤器的位置帮助我完成了我需要的操作:获取垂直 ScrollBar 实例。有了它,我能够检测到滚动位置并在滚动结束时获取数据。非常感谢!
    猜你喜欢
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    • 2022-10-17
    • 1970-01-01
    • 2013-04-30
    相关资源
    最近更新 更多