问题描述
我正在JavaFX应用程序中使用controlsfx GridView。它在需要时显示滚动条,但是我找不到确定滚动条位置的方法,也无法更新它。我需要能够执行诸如响应用户“转到顶部”命令并向上滚动的操作;或滚动以使所选缩略图保持可见,因为用户使用箭头键在网格中导航。但是我没有看到如何访问当前的滚动位置,也没有像使用ScrollPane那样操纵它。
例如,这是一个示例应用程序,它创建了一个GridView,其中包含100个生成的图像。我在“ onScrollProperty”中添加了一个侦听器,但从未调用过它。我也不知道如何使它滚动到某个滚动位置(0..1):
import java.awt.image.BufferedImage;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import org.controlsfx.control.GridView;
import org.controlsfx.control.cell.ImageGridCell;
// Demo class to illustrate the slowdown problem without worrying about thumbnail generation or fetching.
public class GridViewDemo extends Application {
private static final int CELL_SIZE = 200;
public static void main(String[] args) {
launch(args);
}
public void start(Stage primaryStage) {
// Create a Scene with a ScrollPane that contains a TilePane.
GridView<Image> gridView = new GridView<>();
gridView.setCellFactory(gridView1 -> new ImageGridCell());
gridView.setCellWidth(CELL_SIZE);
gridView.setCellHeight(CELL_SIZE);
gridView.setHorizontalCellSpacing(10);
gridView.setVerticalCellSpacing(10);
addImagesToGrid(gridView);
gridView.onScrollproperty().addListener((observable,oldValue,newValue) -> {
// Never called
System.out.println("Scrolled...");
});
primaryStage.setScene(new Scene(gridView,1000,600));
primaryStage.setonCloseRequest(x -> {
Platform.exit();
System.exit(0);
});
primaryStage.show();
}
private void addImagesToGrid(GridView<Image> gridView) {
for (int i = 0; i < 100; i++) {
final Image image = createFakeImage(i,CELL_SIZE);
gridView.getItems().add(image);
}
}
// Create an image with a bunch of rectangles in it just to have something to display.
private static Image createFakeImage(int imageIndex,int size) {
BufferedImage image = new BufferedImage(size,size,BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
for (int i = 1; i < size; i ++) {
g.setColor(new Color(i * imageIndex % 256,i * 2 * (imageIndex + 40) % 256,i * 3 * (imageIndex + 60) % 256));
g.drawRect(i,i,size - i * 2,size - i * 2);
}
return SwingFXUtils.toFXImage(image,null);
}
}
所需的行家包括:
<dependency>
<groupId>org.controlsfx</groupId>
<artifactId>controlsfx</artifactId>
<version>8.0.6_20</version>
</dependency>
这是它的外观的屏幕截图。
解决方法
对于提问者来说可能迟到了。但是在我偶然发现同样的问题之后,经过数小时的调查,希望对其他人有用...
我向“onScrollProperty”添加了一个侦听器,但它从未被调用。
这“按预期工作”。 :-/ 见 https://bugs.openjdk.java.net/browse/JDK-8096847。 您必须使用“addEventFilter()”。请参阅下面的示例。
设置滚动位置很痛苦。您必须获得 GridView 的底层“VirtualFlow”对象。 VirtualFlow 包含将滚动位置设置为特定行的方法。奇怪的是 GridView 似乎没有针对这个常见用例的 API。 :-(
“概念证明”示例如何为带有图像的 GridView 设置滚动位置:
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public SpriteRenderer[] renderers;
private void Start() {
renderers[0].material.color = Color.red;
}
}
(使用 javafx 15.0.1 和 controlsfx 11.0.3 测试)