[英]How can I access scroll position in controlsfx GridView for JavaFX?
我在 JavaFX 應用程序中使用了controlfx 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);
}
}
所需的 Maven 包括:
<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 設置滾動位置:
/**
* Register a scroll event and a key event listener to gridView.
* After that navigate with "arrow up" and "arrow down" the grid.
* @param gridView
*/
private void addScrollAndKeyhandler(final GridView<Image> gridView) {
// example for scroll listener
gridView.addEventFilter(ScrollEvent.ANY, e-> System.out.println("*** scroll event fired ***"));
// add UP and DOWN arrow key listener, to set scroll position
gridView.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
if (e.getCode() == KeyCode.UP) oneRowUp(gridView);
if (e.getCode() == KeyCode.DOWN) oneRowDown(gridView);
});
}
int selectedRow = 0; // current "selected" GridView row.
/**
* Scrolls the GridView one row up.
* @param gridView
*/
private void oneRowUp(final GridView<Image> gridView) {
// get the underlying VirtualFlow object
VirtualFlow<?> flow = (VirtualFlow<?>) ((GridViewSkin<?>) gridView.getSkin()).getChildren().get(0);
if (flow.getCellCount() == 0) return; // check that rows exist
if (--selectedRow < 0) selectedRow = 0;
if (selectedRow >= flow.cellCountProperty().get()) selectedRow = flow.getCellCount() - 1;
System.out.println("*** KeyEvent oneRowUp " + selectedRow + " ***");
flow.scrollTo(selectedRow);
}
/**
* Scrolls the GridView one row down.
* @param gridView
*/
private void oneRowDown(final GridView<Image> gridView) {
// get the underlying VirtualFlow object
VirtualFlow<?> flow = (VirtualFlow<?>) ((GridViewSkin<?>) gridView.getSkin()).getChildren().get(0);
if (flow.getCellCount() == 0) return; // check that rows exist
if (++selectedRow >= flow.cellCountProperty().get()) selectedRow = flow.getCellCount() - 1;
System.out.println("*** KeyEvent oneRowDown " + selectedRow + " ***");
flow.scrollTo(selectedRow);
}
(使用 javafx 15.0.1 和 controlsfx 11.0.3 測試)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.