JavaFX - ScrollPane中的大量数据冻结了UI

时间:2016-01-14 08:20:56

标签: java javafx

我需要做什么?

我需要显示大量数据 1 GridPane存在约25个标签。需要显示100-500个GridPane。

我是怎么做到的?

我使用了ScrollPane 因此,VBox中有许多GridPane放入ScrollPane 我在一个额外的Thread中生成GridPanes,并在JavaFX-Thread中设置ScrollPane的内容。

其中一些标签是经过修改的标签,因此它们可以复制或链接。

会发生什么?

UI会冻结几秒钟,然后显示数据。

问题1:我是否可以进行一些修改以防止用户界面冻结? 问题2:是否还有其他组件更适合显示此类数据?

ExampleCode:

package samples.longload;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Longload extends Application
{
    private final Button runButton = new Button("Run");
    private final Label label = new Label();
    final ScrollPane sp = new ScrollPane();
    final VBox vb = new VBox();

    private final Service service = new Service()
    {
        @Override
        protected Task createTask()
        {
            return new Task<Void>()
            {
                @Override
                protected Void call() throws Exception
                {
                    final List<Node> nodeList = new ArrayList<Node>();
                    for (int i = 0; i < 500; i++)
                    {
                        final GridPane grid = defineGrid();
                        nodeList.add(grid);
                    }
                    vb.getChildren().addAll(nodeList);

                    Platform.runLater(new Runnable()
                    {
                        @Override
                        public void run()
                        {
                            sp.setContent(vb);
                        }
                    });

                    return null;
                }
            };
        }
    };

    @Override
    public void start(final Stage stage)
    {
        final VBox layout = createLayout();

        final Scene scene = new Scene(layout, 1500, 1000);
        stage.setScene(scene);

        bindUIandService(stage);

        stage.show();
    }

    private void bindUIandService(final Stage stage)
    {
        label.textProperty()
             .bind(service.stateProperty().asString()
             );

        stage.getScene()
             .getRoot()
             .cursorProperty()
             .bind(
                   Bindings
                           .when(service.runningProperty())
                           .then(Cursor.WAIT)
                           .otherwise(Cursor.DEFAULT)
             );

        runButton
                 .disableProperty()
                 .bind(
                       service.runningProperty()
                 );

        runButton.setOnAction(new EventHandler<ActionEvent>()
        {
            @Override
            public void handle(final ActionEvent event)
            {
                service.restart();
            }
        });
    }

    private VBox createLayout()
    {
        final VBox layout = new VBox(10);
        sp.setPrefSize(300, 500);
        sp.setVmax(440);
        sp.setContent(new ProgressIndicator());
        layout.getChildren().setAll(runButton, label, sp);
        layout.setPadding(new Insets(10));
        layout.setAlignment(Pos.CENTER);

        return layout;
    }

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

    private LinkedHashMap<Node, Node> createContentMap()
    {
        final LinkedHashMap<Node, Node> contentMap = new LinkedHashMap<Node, Node>();

        // ID-KONSEH
        contentMap.put(new Label("1"), new Label("1", null));
        // ID-DOKUMENT
        contentMap.put(new Label("2"), new Label("2"));
        // DISCRIMINATOR
        contentMap.put(new Label("3"), new Label("3"));
        // AKT
        contentMap.put(new Label("4"), new Label("4"));
        // FASSUNGSNR
        contentMap.put(new Label("5"), new Label("5"));
        // KORREKTURNR
        contentMap.put(new Label("6"), new Label("6"));
        // STATUS
        contentMap.put(new Label("7"), new Label("7"));
        // NEUZUGANG
        contentMap.put(new Label("8"), new Label("8"));
        // NEUZDAT
        contentMap.put(new Label("9"), new Label("9"));
        // APPDATVON
        contentMap.put(new Label("10"), new Label("10"));
        // APPDATBIS
        contentMap.put(new Label("11"), new Label("11"));
        // BEZUGVON
        contentMap.put(new Label("12"), new Label("12"));
        // BEZUGBIS
        contentMap.put(new Label("13"), new Label("13"));
        // INKRAFTVON
        contentMap.put(new Label("14"), new Label("14"));
        // INKRAFTBIS
        contentMap.put(new Label("15"), new Label("15"));
        // APPROBANT
        contentMap.put(new Label("16"), new Label("16"));
        // SACHBEARBEITER
        contentMap.put(new Label("17"), new Label("17"));
        // KURZTEXT
        contentMap.put(new Label("18"), new Label("18"));
        // PERSANMERKUNG
        contentMap.put(new Label("19"), new Label("19"));
        // LASTCHANGEDAT
        contentMap.put(new Label("20"), new Label("20"));
        // WIEDERVORLAGE_DATUM
        contentMap.put(new Label("21"), new Label("21"));
        // TEMP_GID
        contentMap.put(new Label("22"), new Label("22"));
        // DOK_MULTIFASSUNG
        contentMap.put(new Label("23"), new Label("23"));
        // ABGEFERTIGT_VON
        contentMap.put(new Label("24"), new Label("24"));
        // KORRIGIERT_VON
        contentMap.put(new Label("25"), new Label("25"));

        return contentMap;
    }

    public GridPane defineGrid()
    {
        final GridPane grid = new GridPane();

        grid.setPadding(new Insets(10, 10, 10, 10)); // top, right, bottom, left
        grid.setHgap(10); // horizontaler Abstand
        grid.setVgap(10); // vertikaler Abstand
        final int columnWidthDescription = 150; // breite der Beschreibungs-Spalten
        final int columnWidthContent = 250; // breite der Inhalts-Spalten
        final ColumnConstraints columnDescription1 = new ColumnConstraints(columnWidthDescription, columnWidthDescription, columnWidthDescription);
        final ColumnConstraints columnContent1 = new ColumnConstraints(columnWidthContent, columnWidthContent, columnWidthContent);
        final ColumnConstraints columnDescription2 = new ColumnConstraints(columnWidthDescription, columnWidthDescription, columnWidthDescription);
        final ColumnConstraints columnContent2 = new ColumnConstraints(columnWidthContent, columnWidthContent, columnWidthContent);
        final ColumnConstraints columnDescription3 = new ColumnConstraints(columnWidthDescription, columnWidthDescription, columnWidthDescription);
        final ColumnConstraints columnContent3 = new ColumnConstraints(columnWidthContent, columnWidthContent, columnWidthContent);
        grid.getColumnConstraints().addAll(columnDescription1, columnContent1, columnDescription2, columnContent2, columnDescription3,
                                           columnContent3);

        final LinkedHashMap<Node, Node> contentMap = createContentMap();
        int column = 0;
        int row = 1;
        for (final Node desc : contentMap.keySet())
        {
            final Node content = contentMap.get(desc);
            if (row > contentMap.size() / 3)
            {
                column = column + 2;
                row = 1;
            }
            grid.add(desc, column, row);
            grid.add(content, column + 1, row);
            row++;
        }
        return grid;
    }
}

最终应该是这样的: enter image description here

0 个答案:

没有答案