1

指定されたディレクトリから画像を表示できるものを作成しましImagePanelた-> 1 秒間スリープし、Java プロジェクトのディレクトリから次の画像をロードします。実際には次の画像をロードしますが、表示されません (パネルを更新しません)。ディレクトリのすべてのファイルを処理すると、ディレクトリの最後の画像のみが表示されます。すべての画像を読み込んだ後に更新したいと思います。

  import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;

public class Okno extends JFrame {
    JPanel jp;
    ImagePanel ImagePanel;
    JButton buttonExit;
    JButton buttonWyjscie;

    public Okno() {

    }

    public void createGUI() {
        setSize(400, 400);
        setLayout(new GridLayout());
        buttonExit = new JButton("Exit");
        buttonWyjscie = new JButton("Wyjscie");
        // Sluchacz sluchacz = new Sluchacz();

        // buttonExit.addActionListener(sluchacz);
        buttonExit.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);

            }
        });

        jp = new JPanel();
        jp.setBorder(new LineBorder(new Color(40, 120, 80), 4));

        ImagePanel = new ImagePanel();
        ImagePanel.setBorder(new LineBorder(Color.blue, 4));
        jp.add(buttonExit);
        add(jp);
        add(ImagePanel);

        setVisible(true);
        slajd();
        setDefaultCloseOperation(EXIT_ON_CLOSE);

    }

    public void slajd() {
        try {
            File f = new File(".");
            File[] tablicaPlikow = f.listFiles();
            for (File el : tablicaPlikow) {

                String rozszerzenie = el.getName().substring(
                        el.getName().length() - 3);

                if (rozszerzenie.equals("jpg") || rozszerzenie.equals("peg")) {
                    System.out.println(rozszerzenie);
                    ImagePanel.setImage(el);
                }
                repaint();
            }
            setVisible(true);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Okno().createGUI();
            }
        });

    }

}

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class ImagePanel extends JPanel {
    private BufferedImage image;

    public ImagePanel() {
    }

    public ImagePanel(String sciezka) {
        setImage(new File(sciezka));
    }

    public void setImage(File plik) {
        try {
            image = ImageIO.read(plik);
            System.out.println("tutaj");
            repaint();
            Thread.sleep(1000);
        } catch (Exception e) {

            e.printStackTrace();
        }
    }

    public void paint(Graphics g) {
        if (image != null) {
            Image b = image.getScaledInstance(getWidth(), getHeight(),
                    Image.SCALE_FAST);
            g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
        }

    }

}
4

2 に答える 2

3

EDTでスリープすると、swing がペイントを実行できなくなり、最後のイメージしか表示されません。イベント ディスパッチ スレッドでスリープする代わりに、swing Timerを使用して繰り返しタスクを実行します。

private final ActionListener timerTask = new ActionListener() {
    @Override
    public void actionPerformed(final ActionEvent e) {
        // Whatever you need to to that
        showNextImage();
    }
};

Timer timer = new Timer(1000, timerTask);
timer.start();

イメージの読み込みに時間がかかる場合は、EDT をブロックせずに、バックグラウンド タスクを使用して次のイメージをメモリにプリロードすることを検討してください。

于 2013-08-18T09:42:30.123 に答える
2

短い答えは次のようになりslajdますrepaint();

Thread.sleep(1000);

repaint()ただし、これは Swing のイベントベースの性質に完全に反しており、この特定のケースでは機能しません。これは、効率上の理由から、Swing が呼び出しをすぐに実行しないためです。すべてのイベント処理が終了した後、一度だけそれらを「収集」して実行します。イベント ハンドラーにスリープ期間 (またはその他の実行時間の長い操作) を (直接的または間接的に) 含めると、再描画が遅延し、この場合のように、実際には機能していない点までアプリケーションが非常に応答しなくなります。

あなたがする必要があるのは、 を呼び出す代わりに 1 秒ごとに起動createGUIする Swing Timer (; や他のいくつかのパッケージのクラスと混同しないでください) をインスタンス化することjavax.swing.Timerです。最初の起動は即時である必要があります。または、最初のファイルを表示するコードを含めることができます。関連するリスナーは、次に表示するファイルを追跡する必要があります。ほとんどの場合、このリスナーを、この追跡をサポートするフィールド、ファイルを表示する場所へのポインターなどを備えた本格的なクラスにしたいと思うでしょう。java.util.TimerTimerslajd()slajd()ImagePanel

詳細については、Swing タイマーの使用方法に関する Java のチュートリアルを参照してください。

于 2013-08-18T09:26:55.687 に答える