2010-07-01 155 views
12

我正在嘗試創建一個模式確認對話框。我希望它能像Window.confirm("")那樣工作,我可以在其中調用它,並獲得布爾響應。GWT確認對話框

我的麻煩是我不知道該怎麼做。我試圖在我的應用程序中使用MVP。這裏是我的代碼至今:

public class DialogBoxPresenter implements Presenter { 

    public interface Display { 

     Label getDialogText(); 

     Button getAffirmativeButton(); 

     Button getCancelButton(); 

     Widget asWidget(); 

     public void center(); 

     public void hide(); 

     public void setHeader(String text); 
    } 
    private Display display; 
    private String header; 
    private String dialogText; 
    private String cancelButtonText; 
    private String affirmativeButtonText; 

    protected DialogBoxPresenter() { 
    } 

    public DialogBoxPresenter(Display display, String header, String dialogText, String cancelButtonText, String affirmativeButtonText) { 
     this.display = display; 
     this.header = header; 
     this.dialogText = dialogText; 
     this.cancelButtonText = cancelButtonText; 
     this.affirmativeButtonText = affirmativeButtonText; 

     bind(); 
    } 

    public DialogBoxPresenter(Display display, String header, String dialogText) { 
     this.display = display; 
     this.header = header; 
     this.dialogText = dialogText; 
     this.cancelButtonText = "Cancel"; 
     this.affirmativeButtonText = "OK"; 

     bind(); 
    } 

    private void bind() { 

     this.display.getDialogText().setText(dialogText); 
     this.display.getAffirmativeButton().setText(affirmativeButtonText); 
     this.display.getCancelButton().setText(cancelButtonText); 
     this.display.setHeader(header); 

     addClickHandlers(); 

    } 

    private void addClickHandlers() { 
     this.display.getAffirmativeButton().addClickHandler(new ClickHandler() { 

      @Override 
      public void onClick(ClickEvent event) { 
       doAffirmative(); 
      } 
     }); 

     this.display.getCancelButton().addClickHandler(new ClickHandler() { 

      @Override 
      public void onClick(ClickEvent event) { 
       doCancel(); 
      } 
     }); 
    } 

    private void doAffirmative() { 
     //do something 
     display.hide(); 
    } 

    private void doCancel() { 
     //do something 
     display.hide(); 
    } 

    public void init() { 
     display.center(); 
    } 

    @Override 
    public void go(HasWidgets container) { 
     container.clear(); 
     container.add(display.asWidget()); 
    } 
} 

和我的觀點:

public class DialogBoxView extends DialogBox implements DialogBoxPresenter.Display { 

    private Label dialogText; 
    private Button affirmativeButton; 
    private Button cancelButton; 
    private VerticalPanel container; 

    public DialogBoxView() { 
     //init items 
     dialogText = new Label(); 

     affirmativeButton = new Button(); 
     cancelButton = new Button(); 

     container = new VerticalPanel(); 

     setGlassEnabled(true); 
     setAnimationEnabled(true); 
     setModal(false); 

     init(); 
    } 

    private void init() { 
     //add items 
     container.add(dialogText); 

     HorizontalPanel hp = new HorizontalPanel(); 
     hp.add(affirmativeButton); 
     hp.add(cancelButton); 

     container.add(hp); 
     this.add(container); 
    } 

    @Override 
    public Widget asWidget() { 
     return this; 
    } 

    @Override 
    public Label getDialogText() { 
     return dialogText; 
    } 

    @Override 
    public Button getAffirmativeButton() { 
     return affirmativeButton; 
    } 

    @Override 
    public Button getCancelButton() { 
     return cancelButton; 
    } 

    @Override 
    public void setHeader(String text) { 
     this.setText(text); 
    } 

} 

回答

19

你不會要能夠把它完全相同的方式Window.confirm()工作。問題是,網頁中的所有JavaScript運行在單個線程中。您會注意到,只要打開標準確認對話框,頁面的其餘部分就會失效。這是因爲一個JavaScript線程被阻塞,等待confirm()返回。如果您要爲對話創建一個類似的方法,只要它正在等待該方法返回,則不會處理用戶生成的事件,因此您的對話將不起作用。我希望這是有道理的。

您將能夠做的最好的事情類似於GWT庫爲RPC調用所做的 - AsyncCallback接口。你甚至可以重新使用自己的接口,或者你可能更願意推出自己:

public interface DialogCallback { 
    void onOk(); 
    void onCancel(); 
} 

而不是Window.confirm(String),你的方法的簽名會更喜歡Dialog.confirm(String,DialogCallback)。然後,您的對話框只是保留對傳入的回調的引用,並且您的代碼中的// do something的位置可撥打電話onOkonCancel

+0

這很有效。謝謝你,先生。對於任何好奇的人,我都會在另一個答案中發佈我的代碼。 – KevMo 2010-07-02 16:36:11

8

這是我工作的代碼,如果任何人都好奇。

public class DialogBoxPresenter implements Presenter { 

     public interface Display { 

      Label getDialogText(); 

      Button getAffirmativeButton(); 

      Button getCancelButton(); 

      Widget asWidget(); 

      public void center(); 

      public void hide(); 

      public void setHeader(String text); 
     } 
     private Display display; 
     private String header; 
     private String dialogText; 
     private String cancelButtonText; 
     private String affirmativeButtonText; 
     private ConfirmDialogCallback confirmCallback; 
     private AlertDialogCallback alertCallback; 

     protected DialogBoxPresenter() { 
     } 

     public DialogBoxPresenter(Display display, String header, String dialogText, String cancelButtonText, String affirmativeButtonText, ConfirmDialogCallback callback) { 
      this.display = display; 
      this.header = header; 
      this.dialogText = dialogText; 
      this.cancelButtonText = cancelButtonText; 
      this.affirmativeButtonText = affirmativeButtonText; 
      this.confirmCallback = callback; 

      bind(); 
     } 

     public DialogBoxPresenter(Display display, String header, String dialogText, String affirmativeButtonText, AlertDialogCallback callback) { 
      this.display = display; 
      this.header = header; 
      this.dialogText = dialogText; 
      this.affirmativeButtonText = affirmativeButtonText; 
      this.alertCallback = callback; 

      this.display.getCancelButton().setVisible(false); 

      bind(); 
     } 

     private void bind() { 

      this.display.getDialogText().setText(dialogText); 
      this.display.getAffirmativeButton().setText(affirmativeButtonText); 
      this.display.getCancelButton().setText(cancelButtonText); 
      this.display.setHeader(header); 

      addClickHandlers(); 

     } 

     private void addClickHandlers() { 
      this.display.getAffirmativeButton().addClickHandler(new ClickHandler() { 

       @Override 
       public void onClick(ClickEvent event) { 
        doAffirmative(); 
       } 
      }); 

      this.display.getCancelButton().addClickHandler(new ClickHandler() { 

       @Override 
       public void onClick(ClickEvent event) { 
        doCancel(); 
       } 
      }); 
     } 

     private void doAffirmative() { 
      if (confirmCallback != null) { 
       confirmCallback.onAffirmative(); 
      } else { 
       alertCallback.onAffirmative(); 
      } 
      display.hide(); 
     } 

     private void doCancel() { 
      confirmCallback.onCancel(); 
      display.hide(); 
     } 

     public void init() { 
      display.center(); 
     } 

     @Override 
     public void go(HasWidgets container) { 
      container.clear(); 
      container.add(display.asWidget()); 
     } 
    } 




    public class DialogBoxView extends DialogBox implements DialogBoxPresenter.Display { 

     private Label dialogText; 
     private Button affirmativeButton; 
     private Button cancelButton; 
     private VerticalPanel container; 

     public DialogBoxView() { 
      //init items 
      dialogText = new Label(); 

      affirmativeButton = new Button(); 
      cancelButton = new Button(); 

      container = new VerticalPanel(); 

      setGlassEnabled(true); 
      setAnimationEnabled(true); 
      setModal(false); 

      init(); 
     } 

     private void init() { 
      //add items 
      container.add(dialogText); 

      HorizontalPanel hp = new HorizontalPanel(); 
      hp.add(affirmativeButton); 
      hp.add(cancelButton); 

      container.add(hp); 
      this.add(container); 
     } 

     @Override 
     public Widget asWidget() { 
      return this; 
     } 

     @Override 
     public Label getDialogText() { 
      return dialogText; 
     } 

     @Override 
     public Button getAffirmativeButton() { 
      return affirmativeButton; 
     } 

     @Override 
     public Button getCancelButton() { 
      return cancelButton; 
     } 

     @Override 
     public void setHeader(String text) { 
      this.setText(text); 
     } 

    } 


    public class DialogBoxWidget implements LensooConstant { 

     private static DialogBoxView view = null; 
     private static DialogBoxPresenter presenter = null; 

     public static DialogBoxPresenter confirm(String header, String dialogText, String cancelButtonText, String affirmativeButtonText, ConfirmDialogCallback callback) { 
      view = new DialogBoxView(); 
      presenter = new DialogBoxPresenter(view, header, dialogText, cancelButtonText, affirmativeButtonText, callback); 

      presenter.init(); 

      return presenter; 
     } 

     public static DialogBoxPresenter confirm(String header, String dialogText, ConfirmDialogCallback callback) { 
      return DialogBoxWidget.confirm(header, dialogText, constants.cancelButton(), constants.okButton(), callback); 
     } 

     public static DialogBoxPresenter alert(String header, String dialogText, String affirmativeButtonText, AlertDialogCallback callback) { 
      view = new DialogBoxView(); 
      presenter = new DialogBoxPresenter(view, header, dialogText, affirmativeButtonText, callback); 

      presenter.init(); 

      return presenter; 
     } 

     public static DialogBoxPresenter alert(String header, String dialogText, AlertDialogCallback callback) { 
      return DialogBoxWidget.alert(header, dialogText, constants.okButton(), callback); 
     } 

     protected DialogBoxWidget() { 
     } 
    } 

public interface AlertDialogCallback { 

    void onAffirmative(); 

} 

public interface ConfirmDialogCallback { 

    void onAffirmative(); 

    void onCancel(); 
} 
+0

什麼是LensooConstant?謝謝。 – Eugen 2011-07-13 13:46:04

+0

哦,對不起。我沒有意識到我把它留在那裏。它只是一個包含我的字符串常量的接口,用於不同的語言支持。這是一個愚蠢的方式來實施它,並且它從那以後被改變了。 – KevMo 2011-07-14 17:11:28

+0

偉大的例子MVP簡單! – MatejC 2013-07-18 15:09:50