2017-12-21 32 views
1

슬라이드 쇼, 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(); 
} 

예외 : 여기

구현 메인 UI 스레드에서

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
에서만 만들 수 있습니다

및 액세스 SWT 제어, 모든 시도는해야 할 일 다른 스레드에서 '잘못된 스레드 액세스'오류가 발생합니다.

당신은 메인 스레드에서 코드를 실행하기 위해 백그라운드 스레드에서 DisplayasyncExec 또는 syncExec 방법을 사용할 수 있습니다 :

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

(자바 8/9 코드 람다를 사용하여, 기존 자바에 대한 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); 
        ... 
     } 
    });