JSF:以编程方式显示/调用对话框

时间:2012-11-03 15:51:16

标签: java jsf primefaces

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

我想每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);

如何在浏览器中显示它?

3 个答案:

答案 0 :(得分:1)

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

您需要的基本案例是PrimePush - FacesMessage

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

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

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

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

  5. 1 为了防止用户为您调用此请求,最好设置Filter以阻止除计时器之外的任何人执行请求。

答案 1 :(得分: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类的相关方法中将dialog dialog属性设置为true。

  4. 多数民众赞成:)

答案 2 :(得分: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>

我在一个使用sessioncoped的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"));
    }
}
嗯......什么都没发生,但任何事都应该发生,不是吗? 它应该给我一个“简单”和“测试”的通知,我猜......

<强>更新

谢谢Luiggi Mendoza!以一种非常简单的方式管理它来显示我的对话框(称之为服务器端)。我将以下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>