从java中的图像列表制作幻灯片?

时间:2017-12-21 10:32:36

标签: java multithreading swt slideshow

我正在尝试播放幻灯片,gif等。我列出了从文件夹中读取的图像,并使它们成为在 SWT 对话框中显示的序列。现在我遇到线程访问问题。在SWT中制作幻灯片的方式是什么?感谢任何建议和纠正。

这是实施

    public class ImageShowDialog extends Dialog {

    Shell                    dialog;
    private Label            labelImage;
    private Canvas           canvas;
    int                      numberImage = 0;
    private volatile boolean running     = true;

    ImageShowDialog(Shell parent) {
        super(parent);
    }

    public String open() {
        Shell parent = getParent();
        dialog = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
        dialog.setSize(600, 400);
        dialog.setText("Show Begins!!!");
        dialog.setLayout(new FillLayout());
        this.func();
        dialog.open();

        Display display = parent.getDisplay();
        while (!dialog.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
        return "After Dialog";
    }

    public void func() {
        final List<byte[]> imageCollection = new ArrayList<byte[]>();

        File path = new File("..\\folder");

        File[] files = path.listFiles();
        for (int i = 0; i < files.length; i++) {
            if (files[i].isFile()) { // this line weeds out other
                // directories/folders
                try {
                    imageCollection.add(loadImage(files[i]));
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (running) {

                    ImageData imageData = new ImageData(
                            new ByteArrayInputStream(
                                    imageCollection.get(numberImage)));
                    final Image image = new Image(Display.getDefault(),
                            imageData);
                    canvas = new Canvas(dialog, SWT.NONE);
                    canvas.addPaintListener(new PaintListener() {
                        public void paintControl(PaintEvent e) {
                            e.gc.setAlpha(255);
                            e.gc.drawImage(image, 0, 0);

                        }
                    });

                    numberImage++;
                    if (numberImage == imageCollection.size())
                        try {
                            running = false;
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

    }

    public byte[] loadImage(File file) throws IOException {

        BufferedImage image = ImageIO.read(file);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", bos);
        return bos.toByteArray();
}

和例外:

Exception in thread "Thread-45" org.eclipse.swt.SWTException: Invalid thread access
    at org.eclipse.swt.SWT.error(SWT.java:4282)
    at org.eclipse.swt.SWT.error(SWT.java:4197)
    at org.eclipse.swt.SWT.error(SWT.java:4168)
    at org.eclipse.swt.widgets.Widget.error(Widget.java:468)
    at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:359)
    at org.eclipse.swt.widgets.Widget.checkParent(Widget.java:279)
    at org.eclipse.swt.widgets.Widget.<init>(Widget.java:149)
    at org.eclipse.swt.widgets.Control.<init>(Control.java:110)
    at org.eclipse.swt.widgets.Scrollable.<init>(Scrollable.java:75)
    at org.eclipse.swt.widgets.Composite.<init>(Composite.java:95)
    at org.eclipse.swt.widgets.Canvas.<init>(Canvas.java:79)

2 个答案:

答案 0 :(得分:1)

您只能在主UI线程中创建和访问SWT控件,任何在其他线程中执行此操作的尝试都将使“无效线程访问”无法访问。你得到的错误。

您可以在后台线程中使用asyncExecsyncExec方法在主线程中运行代码:

Display

(使用lambda的Java 8/9代码,对旧Java使用Display.getDefault().asyncExec(() -> { ... code accessing the UI }); 。)

Runnable以异步方式运行代码,asyncExec等待UI线程在返回之前运行代码。

答案 1 :(得分:1)

SWT是单线程的,正如Riduidel在本文中所述:Updating SWT objects from another thread

所以,不要做你做的事,试试下面的事情:

SELECT f.userId, f.following, p.postId, p.content, p.file, p.type
FROM follow f 
JOIN post p ON p.userId = f.userId
WHERE f.userId =  '$userId' 
LIMIT 0 , 30