Jumat, 2009 Mei 29

Mootools: Introduction of 'Element'



After almost one year i haven't touch GWT-Ext, and i almost forgot about how to use it, for 4 months now i play with Mootools for building dynamic web site (an online store with new way ordering system). I think it is a fun way to build interactive website with Mootools, since i avoid code using Java (my team mainly use PHP for it's developing language). Since i have learn it, maybe i can share my experience about Mootools.

Mootools 1.2 (there are many Mootools version, and it is incompatibility between version. Mootools 1.2 is the newest one), is a javascript framework that make you ease to build interactive, dynamic, and rich website. Actually, in beginning i was forced to use it since Joomla/Virtuemart use it (and i don't know that they use Mootools 1.11 when i use Mootools 1.2). I found it quite interesting, well because when I can't get component / widget / something that ready to use for my requirement, I can easily make it by myself. And many components in my project was built by me.

Hmm.. maybe the first thing to introduce Mootools is the Element. Why do i choose this, it's because from Element we can do many thing in advance.

What is Element? maybe it will be easier when we look its example first.

html:
<div id="somepartofwebpage"></div>

javascript:
var somepart = $('somepartofwebpage');

So, what we've got in here. Firstly, Element is an HTML element, which is also same as the HTML's object, such as <html>, <body>, <table>, <div>, etc. The example above describe a 'div' element with id property 'somepartofwebpage' to be stored in somepart variable. With Mootools, we can do some awesome thing with this Element, like creating new element, change, delete, add events, add effects, and many more. Okay, let's look another example:

html:
<div id="somepartofwebpage"></div>

javascript:
var somepart = $('somepartofwebpage');
var newinnerpart = new Element('div',{'id': 'newinnerpart', 'text':'This is new element created with javascript'});
newinnerpart.inject(somepart);
var anotherinnerpart = new Element('a', {'id': 'newinnerpart', 'html': 'this is another element that created with javascript', 'href': 'http://jonif.blogspot.com'});
anotherinnerpart.inject(somepart, 'top');

This example show how to create new element and fill it in another element (somepart element). newinnerpart and anotherinnerpart is just a same way how to create an element. newinnerpart create div element with its content defined in text property. And anotherinnerpart create a link with its text defined in html property and its target to jonif.blogspot.com. There several way to insert the element into another element besides using inject, there are grab, wrap, adopt, and appendText. For each of its function please take a look its API.

From example above, it is showed that the constructor of Element are two parameters, the type of element as a string, and the properties. Its properties can be the attribute of the element (such as 'id', 'class', 'style', etc), 'text' which is the text inside the element, 'html' which is the HTML inside the element, events, or something else (try to look the API to be more detail).

Now, take a look at this:

html:
<div id="'somepartofwebpage'">Hai</div>
<input type='button' id='showtextbutton' value='Show Text'/>

javascript:
var initializeJS = function() {
   var showtextbutton = $('showtextbutton');
   showtextbutton.addEvent('click', function(e) {
      e.stop();
      $('somepartofwebpage').set('html',"<strong>Hello World!</strong>");
   });
};

window.addEvent('domready', initializeJS);

This example explain how to add an event and change the text (or the property of the Element). initializeJS function made to be called after the all DOM ready, this is because Mootools need all DOM to be ready. By using method set() we can change any properties of the element. And of course with method get() we can get the property's value of the element. For other event type please take a look of the API documentation.

Another example:

html:
<div id="somepartofwebpage">Hai</div>
<input type='button' id='emptybutton' value='Empty the div'/>
<input type='button' id='destroybutton' value='Destroy the div'/>

javascript:
var initializeJS = function() {
   var emptybutton = $('emptybutton');
   var destroybutton = $('destroybutton');
   emptybutton.addEvent('click', function(e) {
      e.stop();
      $('somepartofwebpage').empty();
   });
   destroybutton.addEvent('click', function(e) {
      e.stop();
      $('somepartofwebpage').destroy();
   });
};

window.addEvent('domready', initializeJS);


This example show us how to empty the content of the element and how to destroy / remove the element. Make the element empty means all of elements inside the element will be removed, but the element itself and its properties still exist.

Okay, I think that is all the basic about how to use Element of Mootools. There are also called Elements, that consist of elements that match with the condition given. Elements is array of Element. Example:

html:
<div class="dummyclass" style="width:300px;height:40px;background-color:yellow;">Panel 1</div>
<div class="dummyclass" style="width:300px;height:40px;background-color:red;">Panel 2</div>

javascript:
var initializeJS = function() {
   var somepart = $$('div.dummyclass');
   somepart.addEvents('mouseenter': function(){
      this.set('tween', {duration: 1000}).tween('height', '200px');
      },
      'mouseleave': function(){
         this.set('tween', {}).tween('height', '40px');
      }

   );
};

window.addEvent('domready', initializeJS);


This example show you about adding an effect when the event occur. But i'm afraid i don't want to discuss about the effect, and it will have its time later. The example show about using Elements. The story is like this, there are two div element that have same class property and at the javascript all of these div grabbed into an array of Element by using $$ (which is the symbol of Elements). By using Elements, we can add events to all of its member.

Jumat, 2008 Desember 12

Netbeans UML Plugin Just Got Better

I download and install Netbeans 6.5, and use Netbeans to make UML diagrams for documenting our system. I've realized that it just got better.

Floating toolbar
At the first time I'm surprised that there is no pallets for relation symbol. But I quickly found it when I choose one of the object.



it just like toolbay-axis mouse position and it is too small.

Snapping Object Location
Now, when you move object, it will try to snap its location according to other objects. This way, I can arrange objects more neat easily than before, except that it is snapping according only to the edge of others object, not the center of it.



I hope Netbeans will improve it more.

Kamis, 2008 Juli 03

[TUTORIAL] Simple Insert data GWT-Ext and Servlet

After making simple form with GWT-Ext in my previous blog, now I'll try to make an example how to submit its form to a server. I use simple servlet web server to start with so I can focus on explaining how interaction happens.

Activate Submit Function
Now reopen the GWT module class that you've made before so we can activate 'Save' button to submit the form onto the server. Change these statement:
Button saveButton = new Button("Save");

to:

Button saveButton = new Button("Save", new ButtonListenerAdapter(){
public void onClick(Button button, EventObject event) {
UrlParam[] params = new UrlParam[1];
params[0] = new UrlParam("mode","add");

form.getForm().submit("/JourneySimpleServlet/journey",params,
Connection.POST, "Saving...", true);
}
});

By doing this, we define the act for button's onClick event. All fields inside FormPanel will be automatically included as request parameter. UrlParam is an object that we can use for defining additional parameter. submit() method will submit to given servlet url (in this case is "/JourneySimpleServlet/journey"). Please change the white text (servlet url) to your own servlet. In the last parameter of submit method is for whether the form needs to be validate or not.

Servlet
When the form submitted, it will send request just like ordinary form, so handling the GWT-Ext form request is not much different. The different is the response. Actually event it is fine if there is no response, but of course this is bad idea to do with it. There are two types of responses, success response and failed response. Success response only tell client that the request has successfully processed. And failed response tell to client that request has failed to processed, and it also can tell which field is invalid.
Let's see the code:

protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String mode = request.getParameter("mode");

if (mode.equals("add")) {
add(request, response);
}
}

"mode" parameter that has been added as request parameter when submitting form is used to tell what kind of operation needs to be done.

private void add(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String title = request.getParameter("title");
String startDate = request.getParameter("startDate");
String endDate = request.getParameter("endDate");
String story = request.getParameter("story");

SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
boolean valid = true;
String failedMessages = "";
Date startD = null;
Date endD = null;

try {
startD = format.parse(startDate);
} catch (ParseException ex) {
Logger.getLogger(JourneySimpleServlet.class.getName()).log(
Level.SEVERE, null, ex);

failedMessages += "<field>\n";
failedMessages += "<id>startDate</id>\n";
failedMessages += "<msg><![CDATA[" +
"Invalid date format.]]>" +
"</msg>\n";
failedMessages += "</field>\n";
valid = false;
}

try {
endD = format.parse(endDate);
} catch (ParseException ex) {
Logger.getLogger(JourneySimpleServlet.class.getName()).log(
Level.SEVERE, null, ex);

failedMessages += "<field>\n";
failedMessages += "<id>endDate</id>\n";
failedMessages += "<msg><![CDATA[" +
"Invalid date format.]]>" +
"</msg>\n";
failedMessages += "</field>\n";
valid = false;
}

if (startD != null && new Date().before(startD)) {
failedMessages += "<field>\n";
failedMessages += "<id>startDate</id>\n";
failedMessages += "<msg><![CDATA[" +
"<b>It can't be.</b><br/>" +
"<i>You can't tell what gonna happen tommorrow right?</i>]]>" +
"</msg>\n";
failedMessages += "</field>\n";
valid = false;
}
if (startD != null && endD != null && startD.after(endD)) {
failedMessages += "<field>\n";
failedMessages += "<id>endDate</id>\n";
failedMessages += "<msg><![CDATA[" +
"<b>Invalid date range.</b><br/>" +
"<i>Start date must before end date.</i>]]>" +
"</msg>\n";
failedMessages += "</field>\n";
valid = false;
}

response.setContentType("application/xml");
PrintWriter out = response.getWriter();
if (valid) {
Journey journey = new Journey();
journey.setTitle(title);
journey.setStartdate(startD);
journey.setEnddate(endD);
journey.setStory(story);

journeyService.createJourney(journey);
valid = true;

out.println("<trip success='true'>");
out.println("</trip>");
} else {
out.println("<trip success='false'>");
out.println(failedMessages);
out.println("</trip>");
}
}

When the process is running smoothly then there is nothing to worry about. But when it is failed, then we can tell client which fields is invalid. success attribute in trip tag is to determine whether process is failed or success.
When we define error reader for FormPanel in previous GWT-Ext module, we define <field> that have two tags, <id> tag to define which field is invalid, and <msg> as an error message. Put <field> inside root tag so it can be read by client.
If you wonder what is journeyService class is, then it is just a class that will handle the process.

Rabu, 2008 Juni 25

Hacking GWT Compiler to Compile Only for Specific Browser

When you want to compile your GWT module for only specific browser, you can hack UserAgent.gwt.xml inside gwt-user.jar in package com.google.gwt.user. Find this text and change it as you wish:
<define-property name="user.agent" values="ie6,gecko,gecko1_8,safari,opera">

I want to compile for only IE and mozilla, then I change it into
<define-property name="user.agent" values="ie6,gecko,gecko1_8">

I want to do this because we limit specification of browser for our application, and by doing this we can get more space up to 20% :D

Selasa, 2008 Juni 24

[TUTORIAL] GWT-EXT 2.0...An Introduction Study Case

Google Web Toolkit (GWT) is a compiler of your java code into optimized javascript and make it easier to use AJAX. I, Java programmer, who have a problem with javascript, found GWT as a very useful tools to build such an interactive user interface. And also I found GWT-RPC as a great tool for communicating between clients and server, and its I18N capabilities. GWT will compile your java code into several files javascript, html, xml, and sometime .rpc files. It is because GWT will compile for each popular browser, so there will be javascript file for Firefox, for Internet Explorer, etc.
Ext-Js is quite popular javascript library with sophisticated looks and feels. Even its license become GPL from LGPL, which is it indicate that Ext-Js become more popular and its developer wants to give more service to the clients, of course by paying them.
GWT-Ext is the combination of those two library. While Ext is library for user interface, the GWT will compile java code into javascript that use Ext-Js capabilities. So GWT-Ext is a library, that needs GWT library and Ext-Js library. IMHO, GWT-Ext can produce a very nice user interface that looks alike with desktop application, and if you use this library then I would like to recommend that your web application doesn't have many page, so I think one page can handle many job, since downloading needed Ext-Js library can be more than 600Kb.
Okay, now I try to show you how to make a web page form using GWT-Ext. Make sure you have downloaded all 3 libraries that we needed GWT, Ext-Js, and GWT-Ext. If you want Ext-Js LGPL license version then you can download ext-2.0.2. Also if you use Firefox 3, then you should download the latest GWT-Ext. I use Netbeans 6.1 for IDE, and gwt4nb plugin for Netbeans to ease building a GWT application. So if you want to start with GWT, I recommend you Netbeans and gwt4nb plugin :D

Create New Project
First of all, let's make a new project with GWT-ready. Create a new Web Application project, and for the frameworks add Google Web Toolkit as your frameworks. Point GWT installation folder field to your GWT library folder. You can add other frameworks that you like, since it will not causing special treatment when you combine frameworks. GWT Module is a name for your package that act as a module, for this I give a package of net.arenaling.java.mygwtextapp.
When you finish create new project, then there will be several java code and package generated. There will be client package and server package under module package, mygwtextapp.gwt.xml under module package, and MainEntryPoint.java under client package.
GWT will search any java source code to be compiled into javascript under client package, and compile java source code under server package to be a servlet (but of course you must configure by yourself web.xml configuration for the servlet).


You can run it now. And it will show:


mygwtextapp.gwt.xml file is used to define module and should be reside in roots of module package. Inside of it, there is <entry-point> tag which is stands for to locate your main module class, just like a class that have public static void main(String[] args) method to run a desktop/console application. Entry-point class must implements com.google.gwt.core.client.EntryPoint interface and override onModuleLoad() method.

Building GWT-Ext Application
So far, we have built a GWT Application and this is not what we expected. We need to add Ext-Js library and GWT-Ext library. Open project properties, in Libraries add gwtext.jar file. To add Ext-Js, make a new package under GWT module package, name it with public. And then copy the Ext-Js folder into it. So my package will become like this:

Reconfigure mygwtextapp.xml file so we can use GWT-Ext library and Ext-Js library. Open it and add these lines:
<?xml version="1.0" encoding="UTF-8"?>
<module>
<inherits name="com.google.gwt.user.User"/>
<inherits name='com.gwtext.GwtExt' />
<entry-point class="net.arenaling.java.client.mygwtextappEntryPoint"/>
<!-- Do not define servlets here, use web.xml -->
<stylesheet src="js/ext/resources/css/ext-all.css" />
<script src="js/ext/adapter/ext/ext-base.js" />
<script src="js/ext/ext-all.js" />
</module>


Case Study: Journey Input Form
For this tutorial, I choose a simple case study that use some input fields and html editor.
We can define what kind of data for the form. Using RecordDef object to define fields data type:
FieldDef[] formFieldDef = new FieldDef[]{
new StringFieldDef("title"),
new DateFieldDef("startDate","startDate","d/m/Y"),
new DateFieldDef("endDate","endDate","d/m/Y"),
new StringFieldDef("story")
};
RecordDef formDef = new RecordDef(formFieldDef);
XmlReader formReader = new XmlReader("trip", formDef);
formReader.setSuccess("@success");

FieldDef is used for define the name of a field. Because we will have 4 fields, which is title field, start date field, end date field, and story field, then I define String type for title and story, and date for startDate and endDate. This name of field not only reflect the structure of the form, but also the data structure of XML or JSon when there is a communication with server. In this case, I choose XML as its data communication with server.
We can also define an error data type message. I'll give an example for using it later, but for now I'll just give you its code:
XmlReader errorReader = new XmlReader("field", errorRecordDef);
errorReader.setSuccess("@success");


Programming GWT is much more like desktop/Swing programming. There will be a panel that will host components. Panel can have layout to arrange components, and panel can have another panel inside. There is also a specialized panelt that we will be use, and that is FormPanel. It is a panel that will collect any fields and can be used to load and submit data. I will give another example of form communication with server. Here is the example of building panel and its components:
final FormPanel form = new FormPanel();

form.setFrame(false);
form.setLabelAlign(Position.TOP);
form.setBorder(false);
form.setWidth(700);
form.setAutoHeight(true);
form.setErrorReader(errorReader);
form.setReader(formReader);

TextField titleField = new TextField("Title","title");
titleField.setAllowBlank(false);

DateField startDateField = new DateField("Start Date","startDate",150);
startDateField.setFormat("d/m/Y");
startDateField.setAllowBlank(false);

DateField endDateField = new DateField("End Date","endDate",150);
endDateField.setFormat("d/m/Y");

HtmlEditor storyEditor = new HtmlEditor("Story","story");
storyEditor.setWidth(600);
storyEditor.setHeight(400);

DateField is a specialized field for date input, and HtmlEditor is similar with text area that have a toolbar for formatting like rich text editor. After defining each components, then add into panel:
MultiFieldPanel oneRowPanel = new MultiFieldPanel();
oneRowPanel.setBorder(false);
oneRowPanel.setAutoHeight(true);
oneRowPanel.addToRow(startDateField,200);
oneRowPanel.addToRow(endDateField,200);

form.add(titleField, new AnchorLayoutData("90%"));
form.add(oneRowPanel);
form.add(storyEditor, new AnchorLayoutData("90%"));

For start date and end date I want to put it in one line, so I use MultiFieldPanel and then put it in FormPanel.
Form usually have a button or more. Panel have its own layout for buttons, by using addButton() method. We must handle click event on button by using ButtonListener interface or ButtonListenerAdapter abstract class.
Button saveButton = new Button("Save");
Button resetButton = new Button("Reset", new ButtonListenerAdapter(){
public void onClick(Button button, EventObject event) {
form.getForm().reset();
}
});

form.addButton(saveButton);
form.addButton(resetButton);

Okay, now we have a form with its fields. Next step is to add the panel into the browser. There are several way to show GWT-Ext components onto browser. We can RootPanel.get().add(component), RootPanel.get("idchosendiv").add(component), or by using Viewport. I don't know who have the bug, but when we use HtmlEditor and then we use RootPanel, then it has a bug that disable formatting toolbar, so we need to use Viewport. So far I still don't know how to handle it without Viewport.
Viewport viewport = new Viewport(form);
viewport.doLayout();

Now, let's run it and see the result:


I think that's all for now. In near future I'll make more tutorial for GWT-Ext. Thanks ;)

Rabu, 2008 Juni 18

Can't Leave Java Coding

Eventhough now I've been assigned in Microsoft Office Sharepoint Server to maintain web site content by doing some CSS and ASP.NET programming, but still, my body want to move by itself and my mind thinking by its own to code Java app.
I'm always trying to use my time to continue my experiment with Java. Even when changing ASP.NET or HTML I'll use Netbeans for my editor, and then copied it to Sharepoint Designer to publish it.
Hope assigment for this project will be finish or maybe I wish to be assigned to another Java project. fiuhh

Minggu, 2008 Februari 17

[Case Studies] Create JawaPos News's Crawler

When I bore with my training, sometimes I open JawaPos news in pdf format. Others like to do it too. So I think if many of us often open it, then it would made the office’s internet speed slowdown. I create a crawler for JawaPos news and share it to all, so the others don’t have to access the sites to read the news. And I start to create it.

December 29th, 2007

When we want to create a crawler, then things that we must do are:

  1. Find the patterns of address that we have to download / get the information.
  2. Make the method to process the pages / files.

For advanced crawler, maybe we must create an AI to find the pattern or can be an agent, but for simple crawler, it can be a statement that contains the URL or a piece of information that can be composed with other information. For this case (JawaPos Crawler), I only need to make a simple crawler, that search the page ID of each page, make compose the URL, grab the pages, and save it to .pdf file.

To read JawaPos online in pdf format, you can go to http://versipdf.jawapos.co.id/ . The information that contain which URL i supposed to grab the file must be found first. To find it, I read its source file (just go to “View Page Source” in Mozilla Firefox or “View Source” in Internet Explorer. Well, when looking for pattern, for human, can use intuition which one will be the pattern, but there is a step for it. Firstly, just go to one of the news pages, look for its URL, and then make a notes what kind of URL that differ to other news pages, and that will be the pattern. After knowing the pattern, search in previous page source, find information that contain the pattern. And that would be step one.

For getting the pages source as well as download the pdf file, you can use :

 

    protected StringBuffer getPage(String url) throws MalformedURLException, IOException {

        StringBuffer ret = new StringBuffer();

       

        URL site = new URL(url);

        InputStream in = site.openStream();

       

        byte[] buffer = new byte[1024];

        int len = 0;

        while((len = in.read(buffer))>0) {

            ret.append(new String(buffer,0,len));

        }

        in.close();

       

        return ret;

    }

Just pass its URL, and it will retrieve the page source. To find the pattern, I use Regex. After getting information, I dont use getPage() method, but create other method that download and save it to whatever file :

 

    public static void saveURL2File(String urlString, File file) throws MalformedURLException, IOException {

        java.net.URL url = new URL(urlString);

       

        InputStream in = url.openStream();

        OutputStream out = new FileOutputStream(file);

       

        byte[] buffer = new byte[1024];

        int length = 0;

        while((length = in.read(buffer)) > 0) {

            out.write(buffer,0,length);

            out.flush();

        }

        in.close();

        out.close();

    }

 

Well, it is very simple right. With this crawler i can download all the pages and share it.

 

December 31st, 2008

My crawler produces many files, which is every file only contain one page. Well, it can be tiresome to open each file. Even my friend complain it. It makes me want to develop once more of my crawler, How about after I download all the pages, I combined it into one file that contain all pages. And I start to search a library that can manipulate pdf file. I use iText for its library to combine all pages and it needs bcprov and bcmail that you can get from BouncyCastle.