Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 仅绘制应显示在屏幕上的节点?_Java_Javafx_Nodes_Bounds - Fatal编程技术网

Java 仅绘制应显示在屏幕上的节点?

Java 仅绘制应显示在屏幕上的节点?,java,javafx,nodes,bounds,Java,Javafx,Nodes,Bounds,我正在使用场景图(而不是画布)在JavaFX中进行模拟,并且在屏幕上仅绘制所需内容时遇到问题 此模拟中有1000多万个节点,但用户只需要在屏幕上同时看到这些节点的一小部分,最多160000个节点。我关心的所有节点都是400x400图像视图 每个节点都是包含大约40000个节点的组节点块的成员,因此每次需要显示4个或更少的“节点块”。为了显示这些“节点块”,它们被添加到一个静态窗格中,该窗格位于根节点中,根节点是一个组 因此,我从第一个父对象到最后一个子对象的图表如下所示: 根节点组\显示窗格\多

我正在使用场景图(而不是画布)在JavaFX中进行模拟,并且在屏幕上仅绘制所需内容时遇到问题

此模拟中有1000多万个节点,但用户只需要在屏幕上同时看到这些节点的一小部分,最多160000个节点。我关心的所有节点都是400x400图像视图

每个节点都是包含大约40000个节点的组节点块的成员,因此每次需要显示4个或更少的“节点块”。为了显示这些“节点块”,它们被添加到一个静态窗格中,该窗格位于根节点中,根节点是一个组

因此,我从第一个父对象到最后一个子对象的图表如下所示:


根节点组\显示窗格\多个节点块组\注意:这不是您确切问题的答案

我不知道为什么要为每个图像创建ImageView。我宁愿为每个nodeChunk 160000个图像绘制一个图像,并为这个nodeChunk创建一个ImageView

从功能上来说,我看不出这两种方法之间有任何区别。您可以让我知道为什么要使用每个imageview。但从性能上看,这种方法是非常快速和平滑的

请找到下面我所说内容的演示。


最后,我为每个“节点块”创建了一个矩形,将不透明度设置为零,然后检查是否与用户看到的显示窗格部分发生冲突。当与矩形发生碰撞时,相应的“节点块”将添加到显示窗格。

我一半的大脑说我理解问题,另一半说。。不,我还是不清楚!!。你能不能提供一个屏幕截图,说明你到目前为止做了什么,这样我就可以了解你的具体要求:@SaiDandem没问题,已经添加了一个屏幕截图。谢谢。我假设您是从一堆图像文件构建ImageView的。因此,作为第一步,您是为每个imageView构造加载图像,还是将它们保存在缓存中?@SaiDandem我将所有图像保存在缓存中谢谢您的回答!我对每个图像都使用ImageView,因为它们被实时操作、移动、删除、重新存储、拆分等。我不完全确定我是否可以不用使用ImageViews,我会尝试为任何操作重建适当的块。只是出于好奇,当你知道某些事情发生了变化时,你想做什么。?您是否获得特定的imageView并更新其图像?这取决于imageView的变化情况。imageview在某些时间更改其图像,但大部分时间imageview的重新定位或重新存储部分取决于用户单击的内容。因此,每个imageview都需要自行选择和区分
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.security.SecureRandom;
    import java.util.HashMap;
    import java.util.Map;

    /**
     * Combining 4,000,000 images
     */
    public class ImageLoadingDemo extends Application {

        SecureRandom rnd = new SecureRandom();
        // I created 5 images of dimension 1 x 1  each with new color
        String[] images = {"1.png", "2.png", "3.png", "4.png", "5.png"};
        Map<Integer, BufferedImage> buffImages = new HashMap<>();
        Map<Integer, Image> fxImages = new HashMap<>();

        @Override
        public void start(Stage primaryStage) throws IOException {
            ScrollPane root = new ScrollPane();
            root.setPannable(true);
            Scene scene = new Scene(root, 800, 800);
            primaryStage.setScene(scene);
            primaryStage.show();

            root.setContent(approach1());  // Fast & smooth rendering

            // Your approach of creating ImageViews
            // root.setContent(approach2());  // Very very very very very slow rendering
        }

        private Node approach1(){
            // Creating 5 x 5 nodeChunk grid
            GridPane grid = new GridPane();
            for (int i = 0; i < 5; i++) {
                for (int j = 0; j < 5; j++) {
                    ImageView nodeChunk = new ImageView(SwingFXUtils.toFXImage(createChunk(), null));
                    grid.add(nodeChunk, i, j);
                }
            }
            return grid;
        }

        private BufferedImage createChunk() {
            // Combining 160000 1px images into a single image of 400 x 400
            BufferedImage chunck = new BufferedImage(400, 400, BufferedImage.TYPE_INT_ARGB);
            Graphics2D paint;
            paint = chunck.createGraphics();
            paint.setPaint(Color.WHITE);
            paint.fillRect(0, 0, chunck.getWidth(), chunck.getHeight());
            paint.setBackground(Color.WHITE);
            for (int i = 0; i < 400; i++) {
                for (int j = 0; j < 400; j++) {
                    int index = rnd.nextInt(5); // Picking a random image
                    BufferedImage buffImage = buffImages.get(index);
                    if (buffImage == null) {
                        Image image = new Image(ImageLoadingDemo.class.getResourceAsStream(images[index]));
                        buffImages.put(index, SwingFXUtils.fromFXImage(image, null));
                    }
                    paint.drawImage(buffImage, i, j, null);
                }
            }
            return chunck;
        }

        private Node approach2(){
            GridPane grid = new GridPane();
            for (int i = 0; i < 5; i++) {
                for (int j = 0; j < 5; j++) {
                    grid.add(createGroup(), i, j);
                }
            }
            return grid;
        }
        private Group createGroup() {
            GridPane grid = new GridPane();
            for (int i = 0; i < 400; i++) {
                for (int j = 0; j < 400; j++) {
                    int index = rnd.nextInt(5);
                    Image fxImage = fxImages.get(index);
                    if (fxImage == null) {
                        fxImage = new Image(ImageLoadingDemo.class.getResourceAsStream(images[index]));
                        fxImages.put(index, fxImage);
                    }
                    grid.add(new ImageView(fxImage), i, j);
                }
            }
            return new Group(grid);
        }



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