0

メインプログラムによる大量のデータロード中にローダーを表示することに問題があります。その下には、ローダーの .gif アニメーションを表示するSplashScreenというクラスがあります。

public class SplashScreen extends JWindow {

public SplashScreen() {
    super();
    Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/resources/load.gif"));
    try {
        if (image != null) {
            JLabel imageLabel = new JLabel();
            imageLabel.setIcon(new ImageIcon(image));
            this.getContentPane().setLayout(new BorderLayout());
            this.getContentPane().add(imageLabel, BorderLayout.CENTER);
            this.pack();
            Dimension screenSize =
                    Toolkit.getDefaultToolkit().getScreenSize();
            Dimension labelSize = imageLabel.getPreferredSize();
            setLocation(screenSize.width / 2 - (labelSize.width / 2),
                    screenSize.height / 2 - (labelSize.height / 2));
            addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    dispose();
                }
            });
            addKeyListener(new KeyAdapter() {
                public void keyTyped(KeyEvent e) {
                    dispose();
                }
            });
        }
    } catch (Exception ex) {
    }
}

このコードを実行すると、次の結果が得られます。

ローダーgif

しかし、大量のデータ (たとえば 100 万レコード) をロードしたい場合は、次のようなものがあります。

ローダー gif ブランク

Thread、EventQueue.invokeLater、および SwingUtilities を使用して SplashScreen を別の Thread で表示していましたが、機能しません。重いデータをロードすると、常に空白になります。残念ながら、EventQueue や SwingUtilities を使用するのは非常に難しいと言わざるを得ません。これらのユーティリティによって開始されたタスクを終了できないからです。

4

1 に答える 1

1

私は最終的に、このケースを適切に実装する方法を見つけました。

1) ローダー (.gif) を表示する SplashScreen を実装します。

    public class SplashScreen extends JWindow {

        public SplashScreen() {
            super();
            Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/resources/load.gif"));
            try {
                if (image != null) {
                    JLabel imageLabel = new JLabel();
                    imageLabel.setIcon(new ImageIcon(image));
                    this.getContentPane().setLayout(new BorderLayout());
                    this.getContentPane().add(imageLabel, BorderLayout.CENTER);
                    this.pack();
                    Dimension screenSize =
                            Toolkit.getDefaultToolkit().getScreenSize();
                    Dimension labelSize = imageLabel.getPreferredSize();
                    setLocation(screenSize.width / 2 - (labelSize.width / 2),
                            screenSize.height / 2 - (labelSize.height / 2));
                    addMouseListener(new MouseAdapter() {
                        public void mouseClicked(MouseEvent e) {
                            dispose();
                        }
                    });
                    addKeyListener(new KeyAdapter() {
                        public void keyTyped(KeyEvent e) {
                            dispose();
                        }
                    });
                }
            } catch (Exception ex) {
            }
        }

        @Override
        public void dispose() {
            setVisible(false);
        }
}

2) ScheduledExecutorService の初期化

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

3) SplashScreen の表示を担当する Thread を実装する

Thread splashThread = new Thread(new Runnable() {
            public void run() {
                setSplashScreen(new SplashScreen());
                getSplashScreen().setVisible(true);
                getSplashScreen().toFront();
                getSplashScreen().setAlwaysOnTop(true);
            }
        });

4) 新しく作成されたスレッドのスケジュール

executor.schedule(splashThread, 0, TimeUnit.MILLISECONDS);

5) SplashScreenを廃棄する必要がある場合

getSplashScreen().dispose();

さらに、別のスレッドを作成して、SplashScreen を破棄する必要があるかどうかを確認できます。

private void invokeExecutor() {
    executor.scheduleAtFixedRate(new DoneTask(), 0, 200, TimeUnit.MILLISECONDS);
}

private class DoneTask implements Runnable {
    @Override
    public void run() {
        if (fileWorker.isDone()) { //SwingWorker
            getSplashScreen().dispose();
        }
    }
}
于 2015-02-04T11:50:24.633 に答える