2015-10-14 22 views
0

我試圖提供能力上傳文件在我vaadin應用無法訪問UI元素中vaadin的FileUpload FinishListener

protected Upload questionImageUpload = new Upload("Upload question", questionReceiver);

questionImageUpload.addFinishedListener(new Upload.FinishedListener() { 
     @Override 
     public void uploadFinished(Upload.FinishedEvent event) { 
      boolean hasLock = VaadinSession.getCurrent().hasLock(); 
      button.setEnabled(false); 
     } 
    }); 

但是,在我的FinishListener.uploadFinished(),如果我修改了部分UI元素(在上面,我禁用了一個按鈕),修改沒有得到應用。

我認爲這個方法可能會在非UI線程中調用,所以我通過在上面的uploadFinished中放置一個斷點來檢查VaadinSession是否可用。但是,VaadinSession.getCurrent()未返回空值。另外hasLock也是如此。

可能是什麼原因?

我在Google App Engine上運行此vaadin應用程序(仍在IntelliJ IDEA本地運行)。這可能是背後的原因嗎?

回答

0

我真的完成了你想用SuccedListener做什麼。我有一個代碼,用上傳的圖片更新嵌入式組件。你可以看看代碼並從中得到啓示。它也可以禁用按鈕。你可以糾正它不是最優化的,但它的工作原理

公共類PicUploader擴展上傳實現SucceededListener,接收器{

private static final long serialVersionUID = 1L; 
File file; 

public String fileName; 
final String LOCATION = "/home/###"; 

Embedded image = new Embedded(); 
TextField field; 

public PicUploader(Embedded image, String caption) { 
    this.image = image; 
    this.addSucceededListener(this); 
    this.setReceiver(this); 
    this.setCaption(caption); 

    this.setIcon(FontAwesome.UPLOAD);; 

} 

public PicUploader(Embedded image, TextField field) { 
    this.image = image; 
    this.addSucceededListener(this); 
    this.setReceiver(this); 
    this.field = field; 
    this.setButtonCaption(""+FontAwesome.UPLOAD); 
    this.setIcon(FontAwesome.UPLOAD);; 

} 

@Override 
public OutputStream receiveUpload(String filename, String mimeType) { 
    // TODO Auto-generated method stub 
    FileOutputStream stream = null; 

    try { 
     file = new File(LOCATION 
       + "/Pictures/" 
       + System.currentTimeMillis() 
       + filename.substring(filename.length() - 4, 
         filename.length())); 
     fileName = file.getName(); 
     System.out.println("This is the file name " + filename); 
     stream = new FileOutputStream(file); 
    } catch (FileNotFoundException ex) { 

     ex.printStackTrace(); 
    } 

    return stream; 
} 

@Override 
public void uploadSucceeded(SucceededEvent event) { 
    // TODO Auto-generated method stub 
    image.setSource(new FileResource(file)); 
    image.setVisible(true); 
    image.setWidth("150"); 
    image.setHeight("200"); 
    // float ratio = image.getHeight()/image.getWidth(); 
    // image.setWidth(""+image.getWidth()); 
    // image.setHeight(""+image.getHeight()); 
    // field.setValue(getFileName()); 
    this.setEnabled(false); 
} 

public String getFileName() { 
    return fileName; 
} 

}

+0

你的代碼可能工作,但在我的情況下,如果我禁用SucceedListener或CompleteListener中的按鈕,按鈕不會被禁用。我發佈了這個問題尋求一個理由 –

1

文件上傳完成後的POST請求到服務器,包含文件數據。上傳完成後,在POST請求結束時調用Upload.FinishedListeners。雖然所有線程本地設置都正確,但這不是UI更新請求(或UIDL請求),並且發送給瀏覽器的響應僅包含一條文本,通知瀏覽器上傳完成。任何UI更新完成後都會排隊,直到另一個請求請求爲止。

因此,您需要使用@Push,以便通過推送通道將UI更改立即推送到客戶端,或者在開始上傳時最遲啓用輪詢,以便選擇輪詢請求改變用戶界面的變化。

+0

我也想過這個問題。如果是這種情況,我預計在一些其他瀏覽器請求發送到服務器後UI將會更新,所以我做了一些按鈕點擊。不過,上傳完成處理程序所做的更改沒有得到體現。 (我嘗試啓用push,但是我從appengine中得到了很多錯誤) –