我正在尝试获取填充有图像的 GridView 当前可见单元格/行索引。
我找到了从侦听器中取出 id 的方法,但是当我开始在图像上添加文本/标签并将其作为
StackPane
到 GridView
而不是 Images
时,它停止工作(类强制转换异常IndexedCell
)。
这是主课:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class MainApp extends Application {
public MyGridView myGridView;
@Override
public void start(final Stage primaryStage) {
myGridView = new MyGridView();
HBox row1 = new HBox(myGridView);
HBox.setHgrow(myGridView, Priority.ALWAYS);
Scene scene = new Scene(row1, 1200, 800, Color.BLACK);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
这是
MyGridView
课程:
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.IndexedCell;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import org.controlsfx.control.GridCell;
import org.controlsfx.control.GridView;
import org.controlsfx.control.cell.ImageGridCell;
import java.awt.*;
import java.awt.image.BufferedImage;
public class MyGridView extends GridView {
public static final int GRID_CELL_WIDTH = 512;
public static final int GRID_CELL_HEIGHT = 360;
public static final int GRID_CELL_SPACING_HORIZONTAL = 5;
public static final int GRID_CELL_SPACING_VERTICAL = 5;
public MyGridView() {
setCellWidth(GRID_CELL_WIDTH);
setCellHeight(GRID_CELL_HEIGHT);
setHorizontalCellSpacing(GRID_CELL_SPACING_HORIZONTAL);
setVerticalCellSpacing(GRID_CELL_SPACING_VERTICAL);
addEventHandler(MouseEvent.MOUSE_CLICKED, e -> {
Node clickedNode = e.getPickResult().getIntersectedNode();
IndexedCell index = ((IndexedCell) clickedNode);
int clickedItemId = index.getIndex();
System.out.println("Clicked id = " + clickedItemId);
});
addEventFilter(ScrollEvent.ANY, e -> {
Node clickedNode = e.getPickResult().getIntersectedNode();
System.out.println(clickedNode.getClass());
IndexedCell index = ((IndexedCell) clickedNode);
int clickedItemId = index.getIndex();
System.out.println("Scrolled id = " + clickedItemId);
});
//scroll/click cells is working with this, comment it and uncomment next one
setCellFactoryWorking();
// setCellFactoryNotWorking();
addImagesToGrid(this);
}
private void setCellFactoryWorking() {
setCellFactory(gv -> new GridCell<Image>() {
private final ImageView imageView = new ImageView();
{
imageView.setFitHeight(GRID_CELL_HEIGHT);
imageView.setPreserveRatio(true);
}
@Override
protected void updateItem(Image image, boolean empty) {
super.updateItem(image, empty);
imageView.setImage(image);
setGraphic(imageView);
}
});
}
private void setCellFactoryNotWorking() {
setCellFactory(gv -> new GridCell<Image>() {
private final ImageView imageView = new ImageView();
{
imageView.setFitHeight(GRID_CELL_HEIGHT);
imageView.setPreserveRatio(true);
}
@Override
protected void updateItem(Image image, boolean empty) {
super.updateItem(image, empty);
imageView.setImage(image);
Text text = new Text(" Lorem Ipsum");
text.setFill(javafx.scene.paint.Color.rgb(255, 255, 255));
StackPane pane = new StackPane();
pane.getChildren().add(imageView);
pane.getChildren().add(text);
pane.setAlignment(Pos.TOP_LEFT);
setGraphic(pane);
}
});
}
private void addImagesToGrid(GridView<Image> gridView) {
for (int i = 1; i < 200; i++) {
final Image image = createFakeImage(i, GRID_CELL_WIDTH, GRID_CELL_HEIGHT);
gridView.getItems().add(image);
}
}
private static Image createFakeImage(int imageIndex, int width, int height) {
BufferedImage image = new BufferedImage(width, width, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
for (int i = 1; i < width; i++) {
g.setColor(new Color(i * imageIndex % 256, i * 2 * (imageIndex + 40) % 256, i * 3 * (imageIndex + 60) % 256));
double proportion = width / height;
g.drawRect(i, i, width - i * 2, (int) ((width - i * 2) * proportion));
}
return SwingFXUtils.toFXImage(image, null);
}
}
如果将
setCellFactoryWorking()
功能切换为 setCellFactoryNotWorking()
,您将看到鼠标悬停的参考类已更改,并且 id 中不再存在 IndexedCell
。实际上,这是检测 GridView
的实际可见元素的一种不好的方法,是否有更通用的方法不依赖于单元格元素类类型,并且可以告诉:
可见行 ID
可见单元格的id
如果用鼠标单击单元格,那么它也是 id
也很高兴知道鼠标悬停在其上的单元格 ID
我在搜索过程中没有看到任何表明您可以获得行 ID 或列 ID 的内容。如您所知,您可以获得索引。我不确定为什么在将
Labels
和 Images
\ImageViews
添加到 StackPane
时出现错误。下面是一个示例,它将在输入、退出或单击时提供单元格的 ID 和索引。您有代表一个细胞的模型吗?此示例使用带有图像和字符串的模型来表示单元格。
主要
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.paint.Color;
import org.controlsfx.control.GridCell;
import org.controlsfx.control.GridView;
public class App extends Application {
public static void main(String[] args) {
launch(args);
}
public static final int GRID_CELL_WIDTH = 50;
public static final int GRID_CELL_HEIGHT = 50;
public static final int GRID_CELL_SPACING_HORIZONTAL = 5;
public static final int GRID_CELL_SPACING_VERTICAL = 5;
List<Color> defaultColors = getAllDefaultColors();
@Override
public void start(Stage primaryStage) {
ObservableList<ImageModel> modelList = FXCollections.observableArrayList();
for(int i = 1; i <= 1000; i++)
{
modelList.add(new ImageModel(i, createFakeImage(GRID_CELL_WIDTH, GRID_CELL_HEIGHT)));
}
GridView<ImageModel> gridView = new GridView();
gridView.setCellWidth(GRID_CELL_WIDTH);
gridView.setCellHeight(GRID_CELL_HEIGHT);
gridView.setHorizontalCellSpacing(GRID_CELL_SPACING_HORIZONTAL);
gridView.setVerticalCellSpacing(GRID_CELL_SPACING_VERTICAL);
gridView.setItems(modelList);
gridView.setCellFactory((GridView<ImageModel> param) -> {
GridCell<ImageModel> cell = new GridCell<ImageModel>() {
ImageView imageView = new ImageView();
Label label = new Label();
StackPane spRoot = new StackPane(imageView, label);
@Override
protected void updateItem(ImageModel item, boolean empty) {
super.updateItem(item, empty);
if (item != null) {
label.setText(Integer.toString(item.getId()));
imageView.setImage(item.getImage());
setOnMouseClicked((mouseEvent) -> {
System.out.println("Clicked: index-" + getIndex() + "\tID-" + item.getId());
mouseEvent.consume();
});
setOnMouseEntered((mouseEvent) -> {
System.out.println("Entered: index-" + getIndex() + "\tID-" + item.getId());
mouseEvent.consume();
});
setOnMouseExited((mouseEvent) -> {
System.out.println("Exited: index-" + getIndex() + "\tID-" + item.getId());
mouseEvent.consume();
});
setGraphic(spRoot);
} else {
setText("");
setGraphic(null);
}
}
};
return cell;
});
StackPane root = new StackPane(gridView);
Scene scene = new Scene(root, 1080, 720);
primaryStage.setScene(scene);
primaryStage.setTitle("JavaFX App");
primaryStage.show();
}
private Image createFakeImage(int width, int height) {
Color currentColor = defaultColors.get(ThreadLocalRandom.current().nextInt(defaultColors.size()));
WritableImage writableImage = new WritableImage(width, height);
PixelWriter pixelWriter = writableImage.getPixelWriter();
for(int x = 0; x < width; x++)
{
for(int y = 0; y < height; y++)
{
pixelWriter.setColor(x, y, currentColor);
}
}
return writableImage;
}
private List<Color> getAllDefaultColors(){
List<Color> colors = new ArrayList<>();
try
{
Class clazz = Class.forName("javafx.scene.paint.Color");
if (clazz != null) {
Field[] field = clazz.getFields();
for (Field f : field) {
Object obj = f.get(null);
if(obj instanceof Color){
colors.add((Color) obj);
}
}
}
} catch (ClassNotFoundException | IllegalArgumentException | IllegalAccessException ex) {
System.out.println(ex.toString());
}
return colors;
}
}
图像模型
import javafx.scene.image.Image;
/**
*
* @author sedj601
*/
public class ImageModel {
private int id;
private Image image;
public ImageModel(int id, Image image) {
this.id = id;
this.image = image;
}
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
输出
我没有发布输出 GIF,因为 StackOverflow 已将接受的图像尺寸减小到 50 兆像素。