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中睡觉会阻止摇摆不定进行绘画,因此您只能看到最后一张图像。不要在事件派发线程中休眠,而是使用摇摆定时器来执行重复任务:

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

简短的回答可能是:在 method 中slajd,在调用 to 之后repaint();,添加

Thread.sleep(1000);

然而,这与 Swing 基于事件的性质完全相反,在这种特殊情况下甚至不起作用,因为出于效率原因,Swing 不会repaint()立即执行调用。在所有事件处理结束后,它只“收集”并执行一次。如果您在事件处理程序(直接或间接)中包含睡眠期(或任何其他长时间运行的操作),则重新绘制将被延迟,并且应用程序对这一点非常无响应,就像在这种情况下,不是真正工作。

您需要做的是createGUI实例化每 1 秒触发一次而不是javax.swing.Timer调用. 第一次触发应该是立即的,或者您可以包含显示第一个文件的代码。将替换的关联侦听器应跟踪要显示的下一个文件。您很可能希望将此侦听器设置为一个成熟的类,其中包含支持此跟踪的字段、指向显示文件的位置的指针等。java.util.TimerTimerslajd()slajd()ImagePanel

有关更多信息,请阅读Java 的关于如何使用 Swing 计时器的教程

于 2013-08-18T09:26:55.687 回答