`
xiao_feng68
  • 浏览: 104093 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

(XF - 5)值得一看的ZK 常见操作

    博客分类:
  • ZK
阅读更多
How to access resources in another application
1.Let us assume you have another application called app2. Then, you can access the resource by use of "~app2/your/resource/path".

For example,

<include src="~app2/main/foo.zul"/>
Notice that the Web container might prevent you from accessing other Web applications. In this case, org.zkoss.lang.SystemException(("Context not found or not visible to....") will be thrown. To enable it you have to configure the Web container properly.

2.In context.xml, specify crossContext="true" to the Context element:

<Context crossContext="true">
[edit] How to add a hyperlink?
Use toolbarbutton or button component and specify the href attribute. e.g. The following code would generate ZK - Simple and Rich hyperlink.

<toolbarbutton label="ZK - Simple and Rich" href="http://tw.yahoo.com"/>
<button label="Rich Internet Application" href="http://www.zkoss.org/zkdemo/userguide"/>
You can also mix xhtml and xul together so you can create normal hyperlinks e.g

<window title="mix HTML demo" xmlns:h="http://www.w3.org/1999/xhtml">
<button label="zul hyperlink button" href="http://www.google.com/"/>
<h:a href="http://www.google.com">xhtml hyperlink</h:a>
</window>
see the demo and the developer guide for more examples.

[edit] How to convert AWT Image to ZK Image
import java.io.ByteArrayOutputStream;
import java.awt.image.RenderedImage;
import javax.imageio.ImageIO;
import org.zkoss.image.Image;
import org.zkoss.image.AImage;

Image encode(RenderedImage image) {
  ByteArrayOutputStream os = new ByteArrayOutputStream();
  ImageIO.write(image, "png", os);
  return new AImage("my-image.png", os.toByteArray());
}
Since 3.0.7 and 3.5.0, there is an utility class called org.zkoss.image.Images to simply the encoding job.

[edit] How to include the same page twice?
With the include component, you could include any page multiple times as follows.

<include src="/mypage.zul"/>
<include src="/mypage.zul"/>
However, if you want to access the component inside of them, you have to assign a unique identifier of the page being included. Here is what you can do.

<include src="/mypage.zul?pageId=first"/>
<include src="/mypage.zul?pageId=second"/>
In additions, in the page being include, i.e., mypage.zul in this example, you have to write

<?page id="${param.pageId}"?>
Then, you could access their component.

Path.getComponent('//first/asdf/');
Path.getComponent('//second/asdf/');
Notice that components are created as late as the Rendering phase, so you could access them only in the event listener for the following events:

<window>
<zscript><![CDATA[
        /**
         * in a real application we would use something like
         *         List iterateOverMe = sessionScope.get("listToRender");
         */
        String[][] iterateOverMe = {
                {"99", "Fred Flintstone"}
                ,{"8", "Wilma Flintstone"}
                ,{"65", "Barney Rubble"}
                ,{"32", "Betty Rubble"}
        };
]]></zscript>
<tabbox mold="accordion">
<tabs>
<!-- more realisticly my iterateOverMe would be a List of
pojos so that I can write ${each.label} -->
<tab forEach="${iterateOverMe}" label="${each[1]}"/>
</tabs>
<tabpanels>
<!-- more realisticly my iterateOverMe would be a List of
pojos so that I can write ${each.id} -->
<tabpanel forEach="${iterateOverMe}" >
<include src="/render-item.zul?pageId=${each[0]}"/>
</tabpanel>
</tabpanels>
</tabbox>
</window>
In that page we pull in search-item.zul once for each object the search results list and we give the included page a pageId that is the identifier of the item that is to be rendered i.e. 99,8,65,32. Within render-item.zul:

<?page id="${param.pageId}"?>
<zscript>
// Here we have to use param.pageId to locate the object that we will render
Object itemToRender = ... // use param.pageId as the identifer to locate specific object to render at this time
</zscript>
<vbox>
<button label="${itemToRender.label}"/>
</vbox>
In this file is included four separate times and param.pageId differs each time i.e. 99,8,65,32. Each time the page is called we use the param.pageId to find the business item to be rended.

[edit] How to initialize a component if extending it to a custom class?
Say, we extend Tabbox with MyTabbox as follows.

public class MyTabbox extends Tabbox {
...
Then, you could initialize it using two methods: the constructor and the onCreate event.

public class MyTabbox extends Tabbox {
  public MyTabbox() {
    ...//some init
  }
  public void onCreate() {
    ...//other init
  }
}
The constructor is called before members are assigned with initial values, while onCreate is processed after the whole page is loaded.

However, the onCreate event will not be sent if you create the component programmatically, instead of declaring in a ZUML page.

[edit] How to redirect to another page when processing an event?
Use the sendRedirect method of the Execution interface to ask the browser to redirect to another page. All updates to the current page/desktop are dropped.

void onClick() {
  if (some_condition)
    Executions.sendRedirect("another_page");
}
[edit] How to refresh inner pages only?
First, use include component and specifies the src attribute to include whatever page you want (ZK, JSP, JSF or whatever) inside a ZK page. Second, you can dynamically change it by changing the src attribute. e.g. The following code would change the inner page from hello.zul to byebye.zul when an end user press the Bye! button.

<include id="inner" src="hello.zul"/>
<button label="Bye!" onClick="inner.src = &quot;byebye.zul&quot;"/>
If you simply want to reload the same page(and not to change to another page), you have to set the src attribute to null first; then set the src attribute back to what it was. Because ZK optimizes operations, set same value to the same attribute would be deemed doing nothing. e.g. The following code would refresh the hello.zul page when an end user press the Reload button.

<include id="inner" src="hello.zul"/>
<button id="reload" label="Reload" onClick="String tmp=inner.src; inner.src=null; inner.src=tmp;"/>
If you want to programmatically call the reload button from the event handler of another button after doing some other work you can dispatch the current event to the button just by refering to it by id with

Events.sendEvent(reload,event)
as follows:

<button label="Do Lots Of Stuff Then Pass The Click To The Reload Button">
<attribute name="onClick">
{
doLotsOfStuff();
Events.sendEvent(reload, event);
}
</attribute>
</button>
[edit] How to lazy load tabs to speed up the loading of a very large page?
Cread the following page and two other pages "tab1.zul" and "tab2.zul" in the same folder. In tab1.zul and tab2.zul put a <window> containing any zul that you would like (hint go to the demo page and click the "Try Me" buttons and cut-n-paste some large source).

<?page id="main-page"?>
<window id="main-window">
<tabbox width="400px">
<attribute name="onSelect">{
//alert("selected index:"+self.selectedIndex);
if(self.selectedIndex > 0 ) {
Include inc = (Include)Path.getComponent("//main-page/main-window/tab"+self.selectedIndex);
inc.setSrc("tab"+self.selectedIndex+".zul");
}
}</attribute>
<tabs>
<tab label="Tab 0"/>
<tab label="Tab 1"/>
<tab label="Tab 2"/>
</tabs>
<tabpanels>
<tabpanel>This is panel 0 and it does not have an include</tabpanel>
<tabpanel>
<include id="tab1" src=""/>
</tabpanel>
<tabpanel>
<include id="tab2" src=""/>
</tabpanel>
</tabpanels>
</tabbox>
</window>
Only when you click on "Tab 1" and "Tab 2" are is the content of tab1.zul and tab2.zul loaded and their components created. To prove this to yourself comment out the line starting

inc.setSrc("tab"+self.selectedIndex+".zul");
then refresh the page and click on the tabs and you wont see any xul from tab1.zul or tab2.zul as these files will not be loaded after commenting out the event handler code that loads them.

[edit] How to specify line-break in Label's attribute
XML parses considers line breaks as regular whitespaces, so it won't work by using

<label value="line 1
line 2"/>
Instead, use the attribute element as follows:

<label>
  <attribute name="value">line 1
line 2</attribute>
</label>
[edit] How to use "each" variable of "forEach" attribute in onXxx event handler?
[edit] Example1 (incorrect)
<window title="Countries" border="normal" width="100%">
     <zscript><![CDATA[
         // Here we have an array of countries
         // We will generate a bunch of buttons per this array
         // When the button is click, an alert window will show the country name.
        
         String[] countries = {"China", "France", "Germany", "United Kindom", "United States"};
     ]]></zscript>
    
     <hbox>
          <!-- WARNING THIS IS INCORRECT USE "Example 3" -->
         <button label="${each}" forEach="${countries}" onClick="alert(${each})"/>
     </hbox>
</window>
The Example1 is not correct. The EL expression cannot be used in onXxx() event handler. It will throws an exception "Attempt to access property on undefined variable or class name" when button is clicked because the alert(${each}) in onClick is directly interpreted as java codes.

[edit] Example2 (incorrect)
<window title="Countries" border="normal" width="100%">
     <zscript><![CDATA[
         // Here we have an array of countries
         // We will generate a bunch of buttons per this array
         // When the button is click, an alert window will show the country name.
        
         String[] countries = {"China", "France", "Germany", "United Kindom", "United States"};
     ]]></zscript>
    
     <hbox>
          <!-- WARNING THIS IS INCORRECT USE "Example 3" -->
         <button label="${each}" forEach="${countries}" onClick="alert(each)"/>
     </hbox>
</window>
Example2 rewrites alert(${each}) to alert(each). Because each is an implicit object, it should be ok to write it directly in onClick just like other implicit object. However, click the button would still throw an exception "Undefined argument: each". The reason is simple. While each is an implicit object, it is a temporary implicit object. It exists only when the zuml page is being evaluated. When the button is clicked, that original each has gone already.

Then how do we reference each variable of forEach attribute in onXxx() event handler? The key is to store the temporary each variable when the zuml page is evaluated and use that stored object when onXxx event is fired.

[edit] Example3 (correct)
<window title="Countries" border="normal" width="100%">
    <zscript><![CDATA[
        // Here we have an array of countries
        // We will generate a bunch of buttons per this array
        // When the button is click, an alert window will show the country name.
       
        String[] countries = {"China", "France", "Germany", "United Kindom", "United States"};
    ]]></zscript>
   
    <hbox>
        <button label="${each}" forEach="${countries}"
            onClick="alert(componentScope.get(&quot;country&quot;))">
            <custom-attributes country="${each}"/>
        </button>
    </hbox>
</window>
Example3 uses the button's custom-attributes map (componentScope) to store the temporary each object when the zuml page is evaluated and use that stored object later when the button is clicked.

[edit] How to make a Grid's row and column drag-n-drop?
By Bakoma


--------------------------------------------------------------------------------

A Grid consists of Columns and Rows where each Columns has columns as the Columns' children. Similarly, Rows has rows as its children.

Here is a simple Grid with head columns and three rows:

        Name  Age Grade
        Mike  29    C
        Todd  21    B
        Tony  37    A
The following codes will put the above into a Grid with the rows and columns draggable and droppable. Here are the steps:

Create Grid
Add Columns, and specify each column is draggable and droppable provided that they are of the same type , columns.
<columns> 
    <column label="Name" draggable="col" droppable="col" onDrop="move(event.dragged)"/>gunawan
    <column label="Age" draggable="col" droppable="col" onDrop="move(event.dragged)"/>
    <column label="Grade" draggable="col" droppable="col" onDrop="move(event.dragged)"/>
</columns>
Add Rows, and specify each row is draggable and droppable.
<rows> 
    <row draggable="row" droppable="row" onDrop="move(event.dragged)"> 
        <label value="Mike" /> 
        <label value="29" />
        <label value="C" />
    </row> 
    <row draggable="row" droppable="row" onDrop="move(event.dragged)"> 
        <label value="Todd" /> 
        <label value="21" />
        <label value="B" />
    </row> 
    <row draggable="row" droppable="row" onDrop="move(event.dragged)"> 
        <label value="Tony" /> 
        <label value="31" />
        <label value="A" />
    </row>
</rows>
Implement the event handling function. Make sure to move the corresponding cells as well when moving the columns.
void move(Component dragged) {
    if(dragged.getClass().getName().endsWith("Column")) {
        int maxRows=dragged.getGrid().getRows().getChildren().size();
        int i= dragged.getParent().getChildren().indexOf(dragged);
        int j= self.getParent().getChildren().indexOf(self);

        //move celles for each row
        for(int k=0; k < maxRows; k++)
            self.getGrid().getCell(k,j).parent.insertBefore(self.getGrid()
              .getCell(k,i),self.getGrid().getCell(k,j));
   }

    self.parent.insertBefore(dragged, self); 
}
Put them together to get the complete codes:
<zk>
<grid> 
  <columns> 
    <column label="Name" draggable="col" droppable="col" onDrop="move(event.dragged)"/>
    <column label="Age" draggable="col" droppable="col" onDrop="move(event.dragged)"/>
    <column label="Grade" draggable="col" droppable="col" onDrop="move(event.dragged)"/>
  </columns>
  <rows> 
    <row draggable="row" droppable="row" onDrop="move(event.dragged)"> 
        <label value="Mike" /> 
        <label value="29" />
        <label value="C" />
    </row> 
    <row draggable="row" droppable="row" onDrop="move(event.dragged)"> 
        <label value="Todd" /> 
        <label value="21" />
        <label value="B" />
    </row> 
    <row draggable="row" droppable="row" onDrop="move(event.dragged)"> 
        <label value="Tony" /> 
        <label value="31" />
        <label value="A" />
    </row>
  </rows>
</grid> 
<zscript><![CDATA[
  void move(Component dragged) {
    if(dragged.getClass().getName().endsWith("Column")) {
        int maxRows=dragged.getGrid().getRows().getChildren().size();
        int i= dragged.getParent().getChildren().indexOf(dragged);
        int j= self.getParent().getChildren().indexOf(self);

        //move celles for each row
        for(int k=0; k < maxRows; k++)
           self.getGrid().getCell(k,j).parent.insertBefore(self.getGrid()
              .getCell(k,i),self.getGrid().getCell(k,j));
   }

    self.parent.insertBefore(dragged, self); 
  } 
]]></zscript>
</zk>
[edit] How to generate ©?
<html>Copyright &amp;copy; Super Co.</html>

Explanation: &amp; is a way to pass & to the content property of the html component. And, the html component directly outputs the content property to the browser.

On the other hand, it won't work if the label component, since label will encode its content.

<label>Copyright &amp;copy; Super Co.</label>

[edit] How to set the forward property by program
org.zkoss.zk.ui.sys.ComponentsCtrl.applyForward(comp, "onClick");

[edit] How to enable logging in ZK
1. First, Set up the log configuration in your application's zk.xml file. I just used an empty string.

<zk>
    <log>
        <log-base></log-base>
    </log>
</zk>
2. Create an i3-log.conf configuration file and place it in the Tomcat's /conf folder. It should include the following lines.

org.zkoss.testlog=DEBUG
org.zkoss=ERROR
3. Remember to modify the logging.properties file in your Tomcat's /conf folder. The default ConsoleHandler's level is INFO, so you won't see any DEBUG message otherwise. java.util.logging.ConsoleHandler.level = INFO to java.util.logging.ConsoleHandler.level = FINEST 4. If you want to output specific messages from your program

private static final Log log = Log.lookup(org.zkoss.testlog.Foo.class);
if(log.debugable()){
    log.debug("a log for debug message");
}
if(log.infoable()){
    log.info("a log for info message");
}




http://en.wikibooks.org/wiki/ZK/How-Tos/Frequently_Asked_Questions
分享到:
评论

相关推荐

    xf-a2010.64.zip

    1. "cpexym_70773.exe":这看起来像是一个可执行文件(.exe),可能是“xf-a2010”的安装程序。"cpexym"可能是软件的一部分代码名,而"70773"可能是版本号或者是内部编译的标识符。 2. "xf-a2010.exe":这是另一个可...

    xf-a2010注册机.rar

    xf-a2010注册机.rarx

    xf-adesk2012x64.rar

    最新的 autodesk2012 注册机 64位xf-adesk2012x64.rar

    xf-adsk2015_x64.exe

    xf-adsk2015_x64.exe inwentor註冊機

    xf-adsk2016_x64 CAD2016注册机

    xf-adsk2016_x64 CAD2016注册机

    xf-adobecc2015

    AE用于产生注册码的 xf-adobecc2015

    3D MAX2011注册机xf-a2011-64bits

    3D MAX 2011 注册机xf-a2011-64bits

    语音合成模块-XF-S4240

    XF-S4240语音合成模块便是该公司推出的一款高效能、易操作的文本转语音产品。这款模块能够将输入的文本信息实时转化为高质量的语音输出,广泛应用于智能语音交互、语音播报系统以及各种有语音需求的场合。 该模块的...

    xf-adobecc

    2.打开 xf-adobecc.exe 注册机,生成序列号(请勿关闭注册机), 安装 ADOBE CC 软件: 点击“安装”(我已经购买), 点击登录 ADOBE ID,(请确保已经断网), 选择稍后连接, 接受许可协议,输入刚注册的序列号,...

    XF-S4040中文语音合成芯片数据手册1.0

    - **产品背景**:XF-S4040是科大讯飞推出的一款高性能中文语音合成芯片,旨在满足日益增长的语音交互需求。该芯片集成了先进的语音合成技术,能够实现高质量的语音输出。 - **手册版本**:本手册为V1.0版本,发布于...

    xf-mccs6.exe

    5、解压成功后,请不要关掉注册机进行软件安装; 6、当出现“请连接于是internet,然后重试”时,请点击“稍后链接”; 7、然后依提示点击“安装”即可; 8、软件正在安装中,请稍后; 9、成功安装后,打开桌面上...

    xf-adsk2018_x64

    2018版AutoCAD加入了高分辨率4k支持,用户体验视觉效果会更好,但在网上找AutoCAD2018版的软件很难找,下载也非常慢,小编这里附上AutoCAD2018的64位简体中文破解版,还有注册,可以完美激活软件。

    Dahua大华DH-S3100C-24GT4XF-V2以太网交换机电汇聚和光汇聚快速操作手册.docx

    "Dahua大华DH-S3100C-24GT4XF-V2以太网交换机电汇聚和光汇聚快速操作手册" 本资源为Dahua大华DH-S3100C-24GT4XF-V2以太网交换机电汇聚和光汇聚快速操作手册,旨在提供正确的使用方法、安全须知、安装要求、维修要求...

    xf-adsk2016(x86/x64)注册机.rar

    软件介绍: AUTODESK 2016系列软件注册机-32及64位,网上转载过来的,仅供测试后删除。

    (XF - 8)ZK 宏的使用与定义Demo

    本主题“(XF - 8)ZK 宏的使用与定义Demo”着重讨论ZK框架中的宏定义及其应用。 ZK框架的核心理念是通过事件驱动和组件模型来简化Web开发,它提供了丰富的组件库,使得开发者可以像操作桌面应用一样操作Web界面。...

    xf-adesk2012x32.rar

    最新的 autodesk 2012 注册机 xf-adesk2012x32.rar

    (XF - 2)ZK 入门

    【标题】:“(XF - 2) ZK 入门” 在IT行业中,ZK(Zul Kernel)是一个流行的开源Java轻量级Web组件库,主要用于构建富客户端用户界面。ZK提供了一种简单的方式来创建交互式的Web应用,无需处理JavaScript、Ajax或...

    xf86-video-intel-2.2.99.901

    在Linux操作系统中,硬件驱动是连接硬件设备与操作系统的重要桥梁,它负责管理和控制硬件设备的工作。针对Intel 945和960集成显卡,xf86-video-intel-2.2.99.901是一款专为这些显卡设计的开源显示驱动程序。本文将...

    xf86-video-qxl

    "xf86-video-qxl" 是一个专门为Linux操作系统设计的QXL图形显示适配器的开源驱动程序。这个驱动使得Linux系统能够识别并充分利用QXL显卡的特性,提供高效且稳定的图形性能。QXL显卡是专为虚拟化环境设计的,其独特之...

    1-2-TL665xF-EasyEVM开发板硬件说明书.pdf

    广州创龙结合TI KeyStone系列多核架构TMS320C665x及Xilinx Artix-7系列FPGA设计的TL665xF-EasyEVM开发板是一款DSP+FPGA高速大数据采集处理平台,其底板采用沉金无铅工艺的6层板设计,适用于高端图像处理、软件无线电...

Global site tag (gtag.js) - Google Analytics