2

如何以编程方式显示/调用对话框并将其添加到舞台(实际浏览器窗口)?

我想每 2 小时触发一次数据库更新。我已经用TimerTask. 这对我来说很好,计时器任务从数据库中获取我想要的所有数据。在触发此计时器任务之前,我想将屏幕“锁定”几秒钟,以使用户(会话范围)无法访问数据库(我也知道这将如何工作)。我的问题是我不知道/找不到以编程方式调用对话框的方法。


更新我想设置这个 primefaces 对话框:

Dialog dialog = new Dialog(); 
dialog.setAppendToBody(true);
dialog.setModal(true);
dialog.setVisible(true);
dialog.setWidgetVar("generatedDialog");
dialog.setId("fancyDialog");
dialog.setClosable(false);
dialog.setHeader("Getting latest information from the database");
dialog.setDynamic(true);
dialog.setResizable(false);
dialog.setDraggable(false);

如何将其显示到我的浏览器?

4

3 回答 3

1

您不需要以编程方式创建对话框。您需要的是Push Technlogogy,即服务器发起与客户端的交互。PrimeFaces 已经拥有这项技术,可以随时为您使用。

满足您需求的基本案例是PrimePush - FacesMessage

  • 用户编写通知。
  • 服务器收到通知。
  • 通知被发送到channel下的PushContext /notifications
  • 对于包含该/notifications通道的每个客户端,将执行一个操作。在这种情况下,频道仅在同一页面中,并且操作将显示通知。

您可以通过在两个不同的导航器中打开同一页面并发送通知来测试此行为。所有页面都将显示通知(并且看起来像您想要的那样)。

有了这个例子,你唯一需要做的就是:

  1. 在每个页面(这确实是一项繁琐的工作,但这是您想要/需要的)或母版页(如果您使用模板系统)上设置一个频道。
  2. 您的计时器必须在某种程度上调用服务器请求来启动通知。这里有一个关于如何以编程方式上传文件的示例,但您只需启动请求1,无需发送任何参数。
  3. Timer 调用的请求将向通道添加通知。
  4. 该频道将自动触发该操作并可以执行您想要/需要的操作。在提供的示例中,它显示了咆哮声,但您可以修改它以显示<p:dialog>.

1为了防止用户为你调用这个请求,最好设置一个过滤器,阻止除你的计时器之外的任何人执行请求。

于 2012-11-03T16:57:55.487 回答
0

有一个简单的解决方案:

  1. 首先向母版页添加一个对话框。此对话框的渲染属性应首先设置为 false。

  2. 其次刷新当前页面以下代码

    protected void refreshPage() { 
        FacesContext fc = FacesContext.getCurrentInstance(); 
        String refreshpage = fc.getViewRoot().getViewId();
    
        ViewHandler ViewH = fc.getApplication().getViewHandler(); 
        UIViewRoot UIV = ViewH.createView(fc,refreshpage);
        UIV.setViewId(refreshpage); 
        fc.setViewRoot(UIV); 
    }
    
  3. 第三次使用 TimerTask 类相关方法调用上述方法,并在此 TimerTask 类的相关方法中将对话框呈现属性设置为 true。

就这样 :)

于 2012-11-03T16:27:19.273 回答
0

根据@Luiggi Mendoza 的想法,我有点卡住了......

我在我的 jsf 中添加了以下内容:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui"
    xmlns:f="http://java.sun.com/jsf/core"
    template="/templates/layoutUser.xhtml">

    <ui:define name="content">

        <p:growl widgetVar="growl" showDetail="true" />

        <h:form>
        Fanciest Page ever          
        </h:form>

        <p:socket onMessage="handleMessage" channel="/notifications" />

        <script type="text/javascript">
            function handleMessage(facesmessage) {
                facesmessage.severity = 'info';

                growl.show([ facesmessage ]);
            }
        </script>

    </ui:define>
</ui:composition>

我在会话范围的 bean 中调用 TimerTask:

@PostConstruct
    public void initLazyModel() {
        getTimerMB().startTimer(this);
        System.out.println("Timer started");

    }

我的计时器看起来像这样:

@ManagedBean(name = "timerMB")
@SessionScoped
public class TimerManagedBean extends TimerTask {

    private int counter;
    private Timer timer;
    private ArtikelManagedBean artikelMB;

    public void startTimer(ArtikelManagedBean artikelMB){
        this.artikelMB = artikelMB;
        this.timer = new Timer(); 
        Calendar date = Calendar.getInstance();  
        date.set(2012, 3, 28, 21, 28);
        //execute every 10 seconds  
        timer.schedule(this, date.getTime(), 10000);
    }

    @PreDestroy
    public void cancelTimer(){
        this.timer.cancel();
        System.out.println("UpdateTimer cancelled!");
    }

    @Override
    public void run() {
        counter++;
        System.out.println("Upadatetimer started: "+ new Date()+" ("+counter+")");
            PushContext pushContext = PushContextFactory.getDefault()
            .getPushContext();

    pushContext.push("/notifications", new FacesMessage("Simple",
            "Test"));
    }
}

嗯......什么都没有发生,但应该发生什么,不是吗?它应该给我一个“简单”和“测试”的通知,我猜......

更新:

谢谢路易吉·门多萨!以一种非常简单的方式管理它以显示我的对话框(称为服务器端)。我将以下 Servlet 添加到我的 web.xml 中。

<servlet>
    <servlet-name>Push Servlet</servlet-name>
    <servlet-class>org.primefaces.push.PushServlet</servlet-class>

    <init-param>
    <param-name>org.atmosphere.useBlocking</param-name>
    <param-value>true</param-value>
</init-param>

    <init-param>
        <param-name>org.atmosphere.cpr.sessionSupport</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Push Servlet</servlet-name>
    <url-pattern>/primepush/*</url-pattern>
</servlet-mapping>
于 2012-11-03T21:17:14.273 回答