แสดงบทความที่มีป้ายกำกับ zk แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ zk แสดงบทความทั้งหมด

วันพฤหัสบดีที่ 15 กันยายน พ.ศ. 2554

การแก้ไข error zk-spring duplicate class definition: org/zkoss/spring/beans/zkcomponents/ZKComponentBeanMethods

ถ้าลองทำตามตัวอย่าง จากที่ ZK มาให้จากลิงค์ http://books.zkoss.org/wiki/ZK_Spring_Essentials/Working_with_ZK_Spring/Working_with_ZK_Spring_Core/Inject_ZK_Components_in_Spring_Beans
นี้ แล้วอาจจะเกิด exception ตามนี้ครับ
Caused by: java.lang.LinkageError: duplicate class definition: org/zkoss/spring/beans/zkcomponents/ZKComponentBeanMethods
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:592)
        at javassist.ClassPool.toClass2(ClassPool.java:1098)
        at javassist.ClassPool.toClass(ClassPool.java:1079)
        ... 44 more


      ซึ่งมาจาก เรา เรียงลำดับการโหลดผิดใน web.xml โดยจะต้องเอา org.zkoss.spring.web.context.CoreContextListener ขึ้นก่อน org.springframework.web.context.ContextLoaderListener จะทำให้แก้ปัญหานี้ได้ครับ

วันอังคารที่ 16 กันยายน พ.ศ. 2551

Basic ZK Framework ตอนที่ 6 การใช้งาน paging

อันนี้ทำแบบง่ายๆ ครับ คือใช้หลักการ Event Listener แบบ ตอนที่ 5 ครับ
แต่อันนี้เราจะใช้ onPaging แทน โดยทำดังนี้
1. โดยเราไปเขียนเพิ่มที่ Zul File เพิ่ม paging เข้าไป แล้ว เราจะใช้ id เป็นตัวเรียก
2. ก็ไป AddEventListener ที่ paging ตัวนั้นเป็น onPaging โดยตัว paging จะมี Config 
  1. pageSize จะเป็นตัวบอกว่าในหน้านึงมีกี่อัน
  2. totalSize จะเป็นบอกว่ามีข้อมูลทั้งหมดเท่าไร
  3. activePage เป็นตัวบอกว่าเราอยู่หน้าไหน โดยจะเริ่มที่ 0

ต่อไปเป็นตัวอย่าง

Paging pag = (Paging)this.getFellow("pageUser"); --> id ที่เรา Config ไว้ที่ Zul File
pag.setPageSize(10); --> จำนวนข้อมูลต่อหน้า

pag.setTotalSize(100); --> จำนวนข้อมูลทั้งหมด
pag.addEventListener("onPaging", new EventListener() {
public void onEvent(Event event) {
PagingEvent pe = (PagingEvent) event;
int pgno = pe.getActivePage();
int ofs = pgno * 10;

//ใส่เพื่อจะให้ทำอะไร ถ้ากดที่ Paging แล้ว

}
});

วันจันทร์ที่ 15 กันยายน พ.ศ. 2551

Basic ZK Framework ตอนที่ 5 วิธี Add EventListener บน Java

การ Add EventListener ก็เหมือนกับว่าเราร้อยสายจาก Java ไปที่หน้าจอน่ะครับ เช่น เราบอกว่า onClick จะให้ไปทำอะไรเราสามารถมาเขียนที่ Java ได้เลย ว่าถ้ามี onclick แล้วจะให้ไปทำอะไรต่อ โดยที่เราไม่ได้ไปทำที่ ZUL File น่ะครับ (ถ้าไม่ เข้าใจโทษทีครับ ลองทำดูจะเข้าใจมากขึ้น) 

ที่ผมจะสอนคือวิธีแบบธรรมดาที่เราใช้กับพวก onClick, onChange, etc... วิธีีดังนี้
1. เราจะทำการใช้ method ที่ชื่อ  addEventListener ซึ่งจะมีอยู่แล้วในพวก class ใน package org.zkoss.zul เช่น Label, Image
2. ซึ่งใน Method นี้จะมีการใส่ 2 ค่า โดยค่าแรกจะเป็น Event ที่เราต้องการจะดักจับ เช่น onClick เป็นต้น --> ใส่คำนี้ลงไปเลยครับ เพราะรับค่า็เป็น String อยู่แล้ว
3. ต่อไปค่าอีกค่าจะใส่ Class EventListener เราจำต้อง สร้าง Class นี้ขึ้นมาเพื่อรับ ซึ่งจะมี Method บังคับคือ onEvent ซึ่งส่วนนี้นี่ล่ะ เราจะเอาไว้สำหรับว่าจะทำอะไรที่เราต้องการ

ตัวอย่่างที่ทำไว้นะครับ

อันแรกตัว EventListener

private EventListener selectItemListener = new EventListener() {

public void onEvent(Event evt) {

Image img = (Image)evt.getTarget(); เราจะทำการดึงค่าออกมาจากที่เรา addEventListener ไว้ครับ

UserM userM = (UserM)img.getAttribute("sampleUserM"); ดึงค่า attribute ที่เรา set ลงเราสร้าง Image ขึ้นมา

Executions.getCurrent().sendRedirect("zk/sample/userEdit.zul");

}

public boolean isAsap() {
return true;
}
};


ส่วนวิธีเรียกใช้งาน อันนี้ผมทำแบบ Add ใส่ตารางไว้แล้วถ้าเรามา Click จะไปทำงานที่ Event นะครับ

Listcell listCell = new Listcell();
listCell.setStyle("cursor: default");
listCell.appendChild(image);
Image image = new Image("images/edit.gif");
image.setAttribute("sampleUserM", userM); ทำการ set Attribute ชื่อ SampleUserM ขึ้นมา เราสามารถไปเรียกค่าขึ้นมาได้ที่ onEvent ใน EventListener เลยครับ
image.setWidth("23px");
image.setHeight("21px");
image.setStyle("cursor: pointer;");

image.addEventListener("onClick",selectItemListener); ทำการ Add EventListener ในกรณีที่เรา Click ที่รูปนี้


Reference
http://www.zkoss.org/smalltalks/mvc3/ จาก @chanwit  อันนี้จะมีวิธีอื่นด้วยน่ะครับ

วันอังคารที่ 9 กันยายน พ.ศ. 2551

Basick ZK Framework ตอนที่ 4 Config ZK ให้เรียก EJB [On Java File]

เหมือนกับตอนก่อนหน้านี้น่ะครับ แต่อันนี้จะเรียกผ่าน Java เลย ซึ่งที่ผมลอง มีได้ตามนี้ครับ
  1. ถ้าเรียกแบบ Remote EJB สามารถเรียกได้อยู๋แล้วนะครับ คือเรียกอบบบอก IP ไปเลยว่าจะไปที่ไหน สามารถเรียกได้ไม่มีปัญหาครับ
  2. เรียก Local EJB ผมใช้วิธีนี้นะ่ัครับ มีสองวิธี แต่การทำงานคล้ายๆ กัน (โดย Load ใน Servlet ก่อน หรือ บน ZUL File ครับ)
    1. ไป Lookup EJB เสร็จแล้วเก็บค่าไว้ที่ static class สักตัวนึง เช่น Map
    2. ไป Lookup EJB เหมือกนั แต่เก็บไว้ที่ ServletContext เลยครับ
ตัวอย่างการเขียนแบบง่ายๆ ครับ ผมเขียนตอนเรียกไว้ที่ init ใน Servlet แล้วสั่งให้มัน Load on start up

แบบแรกเก็บค่าไว้ที่ static class

public class SampleContext {
private static Map contextJNDI;

เรียกตอน init ใน servlet แล้วสั่งให้ทำตอน load on startup
public void initContext(String jndiName) throws NamingException, CreateException {
Context context = new InitialContext();

ZKServiceEJBLocalHome home = (ZKServiceEJBLocalHome) context.lookup(jndiName);

ZKServiceEJBLocal localObject = home.create();

if(contextJNDI == null) {
contextJNDI = new HashMap();
}

if(contextJNDI.get(jndiName) == null) {
contextJNDI.put(jndiName,localObject);
}
}

อันนี้จะไปเรียกตอนทำงานใน Java ครับ
public ZKServiceEJBLocal getEJB(String jndiName) {

return (ZKServiceEJBLocal)contextJNDI.get(jndiName);

}
}


แบบที่สอง เก็บไว้ที่ ServletContext

เขียนไว้ที่ init ใน Servlet แ ล้ว Config ให้ Load on startup
servletConfig.getServletContext().setAttribute(jndiName, EJBLocalObject); --> jndiName ให้ตอนเวลาจะดึงข้อมูลมาใช้ให้ดึงด้วย jndiName ส่วน EJBLocalObject คือตัว EJBLocal ที่เรา Lookup ใน Context เรียบร้อยแล้ว ล้วเอามาเก็บไว้ที่นี่แทนครับ

ตอนเรียกใช้
ServletContext servletContext = (ServletContext)this.getDesktop().getWebApp().getNativeContext();
servletContext.getAttribute(jndiName);

วันจันทร์ที่ 8 กันยายน พ.ศ. 2551

Basick ZK Framework ตอนที่ 3 Config ZK ให้เรียก EJB [On ZUL File]

สามารถใช้เรียกได้หมดเลยนะครับ ที่เรียกโดยใช้ JNDI แต่เรียกบน ZUL File นะครับ 
โดยเราเพิ่มว่าโหลด JNDIResolver เข้าไปน่ะครับ

<?variable-resolver class="org.zkoss.zkplus.jndi.JndiVariableResolver"
arg0="ZKSampleEAR" --> ใช้สำหรับบอกว่า Application Name ของ Ear File
arg1="sampleEJB=java:comp/env/ejb/sample/zkservice"  --> บอกว่าใช้ EJB Name ชื่ออะไรน่ะครับ แล้วเวลาตอนเรียกใช้จะใช้ sampleEJB ครับ
?>


โดยวิธีการเรียกใช้งานจะเป็นดังนี้


<zscript>
import sample.zk.SampleServiceLocal; <--- Import Class ที่เราใช้เข้ามา
SampleServiceLocal sampleBean = (SampleServiceLocal)sampleEJB; <-- Cast Class ให้เป็นตัวที่เราต้องใช้งานครับ
SampleServiceLocal.doService(); <--- เรียกการทำงาน
</zscript>

*สำหรับคนที่ใช้ Rad deploy บน Websphere ครับ
อันที่จริง Application Server ก็ต้องทำเหมือนกันครับ แต่ผมจะบอกวิธีสำรับคนที่ใช้บน Rad ครับ โดยไป double click ที่ web.xml แล้วไปที่ Tab Reference แล้ว Add EJB Reference เข้าไป โดยชื่อที่เราใช้เรียกจะเป็น อันบนด้านขวา แต่อันล่างด้านขวาจะไป mapping กับ ที่ไปเรียกที่ EJB Project น่ะครับ


Reference

วันพฤหัสบดีที่ 4 กันยายน พ.ศ. 2551

Basick ZK Framework ตอนที่ 2 มาลองใช้ Zk

มาต่อตอนที่ 2 กันครับ ตอนที่ 1 ดู ที่นี่
ตอนนี้มาลองเล่นกันเลยว่ามันทำงานอย่างไรบ้าง


ตัวอย่าง index.zul

<?xml version="1.0" encoding="UTF-8"?>
<?page title="Welcome to ZK Web"?> <-- กำหนดว่า title ของหน้าใช้ชื่ออะไร
<window title="Welcome to ZK Web" 
border="normal" id="login" use="com.zk.LoginView" onOK="login.onOk()">
use ใช้สำหรับว่าจะไปใช้ Java Class ไหน ส่วน id จะเป็น Reference ไว้สำหรับใน window ตัวนี้ โดยเวลาใช้จะใช้ id.method ที่จะใช้น่ะครับ
<textbox id="username"/> <--  กำหนดว่าเป็น input แบบข้อความ โดยกำหนดชื่อเป็น username
และ onOK หมายถึงถ้าเรากด Enter ที่หน้านี้จะเข้าไปทำงานที่ login.onOk()
<button label="OK" onClick="login.onOk()"/> <-- เป็นการบอกว่าถ้ากดปุ่มนี้จะไปที่ Method ชื่อ onOk() ใน Class com.zk.LoginView
<button label="Cancel" onClick="login.onCancel()"/> <-- จะเหมือนกับ ข้างบนครับ
</window>


ต่อไปตัวอย่างของ Java Class นะครับ

package com.zk.service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.log4j.Logger;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;


public class LoginView extends Window { <-- ทำเพื่อให้เพื่อเราสามารถดึงค่าได้

private static final long serialVersionUID = -8725354218872079732L;
private static Logger log = Logger.getLogger(LoginView.class);

public void onCreate(Window main) { //does initialization
log.debug("..... init(Window main)");
}

public void onOk() {  <-- พอเรากด Ok ที่หน้าจอจะมาเข้า Method นี้
log.debug("..... save(Window main)");
String userName = ((Textbox)getFellow("username")).setValue(""); <-- ดึงค่าจาก textbox เมื่อกี้ที่ใช้ id เป็น username
Messagebox.show("Username correct.", "Ok", Messagebox.OK, Messagebox.OK); <-- โชว์ Popup บอกว่า Username correct. 

}

public void onCancel() { //cancel any changes
log.debug("..... cancel(Window main)");

((Textbox)getFellow("username")).setValue(""); <-- เป็นการกำหนดค่าให้ username เป็นค่าว่าง

}
}

วันอังคารที่ 2 กันยายน พ.ศ. 2551

Basick ZK Framework ตอนที่ 1 Config ZK

สามารถ Download ได้ ที่นี่
เป็น Ajax Framework ที่ไม่ต้องมานั่งเขียน Java script น่ะครับ หาข้อมูลเพิ่มเติมได่ที่หน้าเวบ

* สามารถใช้บน Websphere 6.x ได้ครับ ลองมาแล้ว Config เหมือนกันเลย

ตอนนี้จะบอกว่าเราต้อง Config อะไรเพิ่มใน web.xml บ้างนะ่ครับ ที่จริงก็อ่านได้ตามเวบเหมือนกัน ผมรวบรวมไว้จะได้ค้นง่ายๆ

เพิ่มส่วนของ Listener ด้วย

<listener>
<description>Used to cleanup when a session is destroyed</description>
<display-name>ZK Session Cleaner</display-name>
<listener-class>org.zkoss.zk.ui.http.HttpSessionListener</listener-class>
</listener>


ต่อไปเพิ่มในส่วยของ Servlet

<servlet>
<description>ZK loader for ZUML pages</description>
<servlet-name>zkLoader</servlet-name>
<servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class>
<init-param>
<param-name>update-uri</param-name>
<param-value>/zkau</param-value>
</init-param>
<load-on-startup>1</load-on-startup> สำหรับตรงนี้ ถ้า Config บน Websphere อาจจะต้องลองเปลี่ยนเลขดูน่ะครับ ถ้ามันยังไม่ได้
</servlet>

<servlet>
<description>The asynchronous update engine for ZK</description>
<servlet-name>auEngine</servlet-name>
<servlet-class>org.zkoss.zk.au.http.DHtmlUpdateServlet</servlet-class>
</servlet>


หลังจากนั้นก็เพิ่ม Servlet-Mapping

<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zul</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zhtml</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>auEngine</servlet-name>
<url-pattern>/zkau/*</url-pattern>
</servlet-mapping>


เป็นอันเสร็จครับ ก็จะทำให้ใช้ Zk Framework ได้ล่ะ


ลองเทสโดยการเขียน index.zul แบบนี้ดูครับ ว่ามันขึ้นหน้าจอหรือเปล่า

<window title="My First window" border="normal" width="200px">
Hello, World!
</window>