2017-12-21 15 views
1

私はスライドショーやgifなどを実現しようとしています。私はフォルダから読み込んだ画像をリストアップし、SWTダイアログに表示するシーケンスにしました。スレッドアクセスに問題があります。 SWTでスライドショーを作成する方法は何ですか?アドバイスや訂正ありがとうございます。javaの画像のリストからスライドショーを作成していますか?

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) 

答えて

1

あなたが唯一、メインUIスレッドでそうしようとする試みを作成し、アクセスSWTコントロールすることができます他のスレッドでは、「無効なスレッドアクセス」エラーが表示されます。

あなたはメインスレッドでコードを実行するために、あなたのバックグラウンドスレッドでDisplayasyncExecまたはsyncExecメソッドを使用することができます。

Display.getDefault().asyncExec(() -> 
    { 
    ... code accessing the UI 
    }); 

(ラムダを使用してJava 8/9コード、古いJava用Runnableを使用) 。

asyncExecコードを非同期に実行すると、syncExecは、UIスレッドがコードを実行して戻る前に待機します。この記事でRiduidelによって記載されているように

1

SWTは、singlethreadedさ:Updating SWT objects from another thread

ので、代わりにあなたが何を行うのは、以下試してください。

Display.getDefault().asyncExec(new Runnable() { 
     public void run() { 
ImageData imageData = new ImageData(
          new ByteArrayInputStream(
            imageCollection.get(numberImage))); 
        final Image image = new Image(Display.getDefault(), 
          imageData); 
        canvas = new Canvas(dialog, SWT.NONE); 
        ... 
     } 
    }); 
関連する問題