Showing posts with label tutorial. Show all posts
Showing posts with label tutorial. Show all posts

Wednesday, September 1, 2010

iOS - Adding a stretchable UIImage as background


Often i need to use some image as a background for many visual components, like views, scrollviews, buttons, other images… and most of time i ended using a large enough image to cover the front image.
So, if my view was 1000x700 i needed to load an 1000x700 image for the background. But this image will eat a lot of memory just to be there as a background. There should be a better way to do this. And there is a better way to do this.
All you have to do is create your UIImage like this
UIImage* backgroundImage = [[UIImage imageNamed:@”stretchableImage.png”] stretchableImageWithLeftCapWidth:44 topCapHeight:45];
this stretchableImageWithLeftCapWidth specify how many pixel in the left must be kept. The same goes to the topCapHeight, and in this case it specifies the number of pixels in the top.
So in the example, the sdk will keep the first 44 pixels, copy the 45th along all the way of the image, and in the end keep again the last 44 pixels. It will do the same for the height.
So you wont need to keep a large image in memory. And you can also use this technique to create dynamic buttons, views and anything that you may even not know how length it is.

Here you can find an image as example (but keep in mind that as a designer, i’m a good programmer ^_^” )



Visit my tumblr for more iphone tips and tricks

Thursday, September 10, 2009

Using jQuery to build a feature carrousel

Well, it's been a while since my last post, but now I'm back!

After talking a little about GWT, i will start talking a little about jQuery as well and show some sort of animations that can be made using jQuery.

As my first example, we will build a very stylish carrousel, not to just show some image, but also show the features of your site.

You will need:
  • some large images for the features background.
  • some small images to use as menu items.
  • some images with the same height/width as the large one, but transparent with the text you want to show with the background image.
Also if your large image is named photo1.png, the small one should be photo1_small.png and the text image photo1_text.png

we will start by coding the HTML elements of the carrousel:
<div id="main-carrousel">
<div id="shadow"></div>
<img id="text-img" src="/images/foto1_text.png"/>
<div id="bottom">
<div id="controls">
<img src="/images/foto1_small.jpg" class="select"/>
<img src="/images/foto2_small.jpg"/>
<img src="/images/foto3_small.jpg"/>
</div>
</div>
</div>

The div main-carrousel will have in it's background the current feature image.
The div shadow will give the transition effect
The img text-img will have the image with the text of the feature.
The div bottom will hold the controls to change the feature.

Now the javascript code:
$(function(){
var carrousel = $("#main-carrousel");
if (carrousel != null && carrousel != undefined){
$("#controls img").each(function(){
$(this).click(function(){
if (!$(this).hasClass("select")){
var photoUrl = "url("+ $(this).attr("src").replace(/_small/,"") +")";
var textUrl = $(this).attr("src").replace(/_small/,"_text").replace(/jpg/,"png");
$("#text-img").fadeOut("fast",function(){
$(this).attr("src",textUrl);
$("#shadow").fadeIn("fast",function(){
carrousel.css("background-image",photoUrl);
$("#shadow").fadeOut("fast",function(){
$("#text-img").fadeIn("slow");
});
});
});
$("#controls .select").removeClass("select");
$(this).addClass("select");
}
});
});
}
});
Well, we start by getting all the images in the "controls" div.
For each one we add a listerner to the "click" action where our magic will happen.
In this function we confirm if the current item is the not one selected.
After we find the photo url by removing the "_small" from the src of the img. Also we find the text image by replacing the "_small" with "_text".
Now that we know the new urls we start the animation.
First we fade out the text image and replace its src attribute with the new text-img url.
the we fade in the shadow div, so we can update the main-carrousel background with the new image url.
After we fade out the shadow div and fade in the text image.

To speed up the images loading process you can create a invisible div to pre-load the images.
<div id="pre-loader" style="display:none">
<img src="/images/foto1.jpg"/>
<img src="/images/foto2.jpg"/>
<img src="/images/foto3.jpg"/>
</div>

You can also style the carrousel, here is an example:
#main-carrousel{
width:700px;
height:300px;
background:#fff url(/images/foto1.jpg) no-repeat;
position:relative;
top:-25px;
margin:0 auto;
border:1px solid #999;
}
#shadow {
width:100%;
height:100%;
background:#DDD;
display:none;
}
#bottom {
position:absolute;
bottom:0;
width:100%;
height:50px;
background:url(/images/transpBlack25.png);
}
#controls {
float:right;
padding-top:10px;
padding-right:10px;
}
#controls img {
margin-left:10px;
float:left;
cursor:pointer;
}
.select {
border:3px solid #DDD;
margin-top:-3px;
}


you can see it live at http://brunogb.appspot.com

Hope you enjoyed it.

Friday, July 17, 2009

Composites - When you need to group widgets

When developing an user interface it's quite common to need components more complex than the ones that are available to us. By example the textfield widget does not have a label by default and every time we need to put a text field on a form, we also need to put a label with it.
And if we could create a new widget that was composed of a label and a textfield?
That's the main purpose of the Composite class. The Composite is a widget composed of widgets.
You may create a LabelTextBox composite, that has a label and a textfield. This way you don't need anymore to create each time a label and a textbox (and maybe some panel to layout them). Now you just need to create a LabelTextBox.
Also, using the composite helps you to keep your code clean and organized, by encapsulating all the logic and configuration of those widgets inside the composite class.
Here is an example of a composite:

public class LabelTextField extends Composite {


private HorizontalPanel hPanel;

private Label lblField;

private TextBox txtField;

public LabelTextField(Label lbl, TextBox txt) {

lblField = lbl;

txtField = txt;

hPanel = new HorizontalPanel();

hPanel.add(lblField);

hPanel.add(txtField);

initWidget(hPanel);

}

public String getValue(){

return txtField.getText();

}

public String getLabel(){

return lblField.getText();

}

}

One of the rules to use the composite class is that we must associate another widget as the main widget of this composite, through the method initWidget(Widget w).
In this case the main widget is a HorizontalPanel.
Also note that we hided the TextBox and the Label objects from the external access, and only exposed the getText() methods of the objects.

Thursday, July 16, 2009

How to upload the chat application to google AppEngine

In the last post we finished the chat application. Now we will learn how to upload it to google appengine.

First log in to the appEngine site with your google account.
If this is the first time you log in into appengine it will ask to validate your mobile number. (Please, don't forget to put also the country code and the area code. )
After you validate you will be able to create your first application.
Choose an application ID avaliable and the application title hit the save button.

After all you need to do is open your eclipse project. Select the project properties -> Google -> AppEngine and set the id of the application. You may also set the version of the application(the AppEngine keeps track of the versions, and you can make any version the one default). After just click on the appengine icon (its close to the button you hit to create a google project and the button to compile the gwt). Fillin your email and password, and you're done.
That's all you need to create a chat application and publish it to the internet.

Wednesday, July 15, 2009

How to create a simple chat using GWT and AppEngine - Second Part

Now comes the second part of the tutorial to create a basic chat.

In the last part we created the base of the interface and the base of the server.
Now we will create the Persistence Manager.

Create a new package under the server package named persist.

Now create a Class named PMF. Here is the code:

public final class PMF {


private static final PersistenceManagerFactory pmfInstance = JDOHelper.getPersistenceManagerFactory("transactions-optional");


private PMF(){ }

public static final PersistenceManagerFactory getFactory(){

return pmfInstance;

}

public static final PersistenceManager getManager(){

return getFactory().getPersistenceManager();

}

public static final void saveObject(Object obj){

getManager().makePersistent(obj);

}

}

This class uses the PersistenceManagerFactory to get a PersistenceManager. This manager is responsable for saving, updating and deleting the objects. (Notice that this class is very simple just to explain this example).
Now open the Shout class. We need to set the time that the message was sent.
Add the Date field sentAt to it.

@Persistent

private Date sentAt;

also great the get and set for this field.
Now change the shoutToServer method of the ShoutServiceImpl class. This is the code:

public String shoutToServer(Shout s){

s.setSentAt(new Date());

PMF.saveObject(s);

return s.getMessage();

}

we just set the date to today and save the message.
Now all of our messages been saved. We need now to display them on the browser.
Create a method getAllShouts in the ShoutServiceImpl class. This is the code:

public List getAllShouts() {

Query query = PMF.getManager().newQuery(Shout.class);

query.setOrdering("sentAt ascending");

List resultset = (List)query.execute();

return resultset;

}

Here we get the PersistenceManager and create a new query based on the Shout class.
next we order the results acording to the sentAt field.
This will return all the messages in the server.
Next we need to create a method that will return only messages newer than a date we will pass.
Create a method called get getNewerThan that will receive a Date parameter. This is the code:

public List getNewerThan(Date now) {

PersistenceManager manager = PMF.getManager();

Query q = manager.newQuery(Shout.class);

ArrayList result = new ArrayList();

List resultset = (List)q.execute();

for (Shout a: resultset){

if (a.getSentAt().after(now)){

result.add(a);

}

}

return result;

}

Here we filter the messages to the ones that were sent only after some specific date. We will need this to update the browser with new messages.
Now we need to update the ShoutService and ShoutServiceAsync with this methods too. Here are the codes:
ShoutService:

public List getAllShouts();

public List getNewerThan(Date now);

ShoutServiceAsycn:

void getAllShouts(AsyncCallback> callback);

void getNewerThan(Date now, AsyncCallback> callback);

Now that your interfaces are updated let's change the EntryPoint (The .java).

First create a Date attribute called lastUpdatedAt and a Timer attribute caled t.
Here is the code:

final VerticalPanel messagesPanel = new VerticalPanel();

private Date lastUpdatedAt;

Timer t;

private void checkMessages(){

t.schedule(1000);

}

private void configureTimers(){

t = new Timer(){

@Override

public void run() {

shoutService.getNewerThan(lastUpdatedAt, new AsyncCallback>(){

public void onFailure(Throwable caught) {

checkMessages();

}

public void onSuccess(List result) {

if (result.size() > 0){

for (Shout i: result){

messagesPanel.add(new HTML(i.getMessage()));

}

lastUpdatedAt = result.get(result.size()-1).getSentAt();

}

checkMessages();

};

});

}

};

}

Here we created the Timer and the Date attributes and also changed the scope of the messagesPanel, making it accessible to all methods in the class.
In the checkMessages() method we just start the Timer, and the timer will get all the messages that were sent after the last message received.
Don't forget to remove the messagesPanel from inside the onModuleLoad method.

Finally add this to the end of the onModuleLoad method:

configureTimers();

shoutService.getAllShouts(new AsyncCallback>(){

public void onFailure(Throwable caught) {

checkMessages();

}

public void onSuccess(List result) {

for (Shout i: result){

messagesPanel.add(new HTML(i.getMessage()));

if (i.getSentAt().after(lastUpdatedAt)){

lastUpdatedAt = i.getSentAt();

}

}

checkMessages();

}

});

this will configure the timer object and also get all the messages that were sent before opening the page.
This will also start the Timer, that will loop now forever.

Here we got our chat. Later you may add a name's field to identify who is sending the message if you want.

That's all folks!
Next i will teach how to send this project online to Google AppEngine.

Until there!

Tuesday, July 14, 2009

How to create a simple chat using GWT and AppEngine - First Part

UPDATED - 2009-07-15 - WEB-INF info

Well, today i will start a series of tutorials about making some stuff in gwt.
We will begin transforming the default project the google eclipse plugin generates.

After installing the google plugin for eclipse (you may find here how to install the plugin), let's create a web application project, by clicking the google blue icon in the toolbar

After you choose your Project Name and the initial package of the project

Also select to use both GWT and App Engine sdks.

This will create a simple project with two main packages:
  • Client
  • Server
In the client package will stay all the code GWT will compile to javascript, and in the server package will stay all the code that will run on the app engine server.

Also the plugin already creates a page with a server communication. It has a textbox and a button, and when you click the button it sends the content of the textbox to the server and get a string to show in the page.

We will also add to this page a list with all the messages sent previously and also update it often using ajax.

So these are the steps we will take:
  1. add a new line to the table in the html
  2. Create a Panel and add it to the line created
  3. Create a model class to represent the message sent - We will call this class "Shout"
  4. Create a service to send this shout to the server
  5. implements the client call to the service

First we will create in the html page (it has the name of the project and stay in the war package) a place to put all of the messages.
We will do this by adding a new line to the table:


what we are doing here is creating a new container to put our panel with the messages.


Now we need to edit the java code to add a new panel in this row.
Open the .java (it is the client package) - We will call this file the EntryPoint, as it implements the EntryPoint interface. We will edit the onModuleLoad method.

Add a new final VerticalPanel and call it messagesPanel

public void onModuleLoad() {

final VerticalPanel messagesPanel = new VerticalPanel();

final Button sendButton = new Button("Send");

final TextBox nameField = new TextBox();


now we will add this panel to the row we created in the html :

// Add the nameField and sendButton to the RootPanel

// Use RootPanel.get() to get the entire body element

RootPanel.get("nameFieldContainer").add(nameField);

RootPanel.get("sendButtonContainer").add(sendButton);

RootPanel.get("messagesContainer").add(messagesPanel);


The RootPanel.get(id) method returns the element in the page with the id we passed, so we can add widgets to it.
Now our panel will be placed right under the textbox and the button.
Well now we need to create the Model class tha will represent the message we are sending.
First let's create a new package under the client package, named "model", and inside this package lets create a new Class, called "Shout".
This class must implements the serialize interface.
Also we need to put some JDO information to be able to save it in the database.
This is the code to the Shout class:

@PersistenceCapable(identityType=IdentityType.APPLICATION)

public class Shout implements Serializable{


@PrimaryKey

@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)

private Long id;

@Persistent

private String message;

public Shout(){}

public Shout(String message){

this.message = message;

}


public String getMessage() {

return message;

}


public void setMessage(String message) {

this.message = message;

}


public Long getId() {

return id;

}

}

The @PersistenceCapable annotation mark this class as persistance and each field that shoud be stored must have the @Persistence annotation on it.

Well now that we have our model we must create a service to send it to the server.
First let's create a ShoutService interface in the client package and also a ShoutServiceAsync interface.
In the first we should add a method that will receive a Shout and return a String, this is the code of the ShoutService:

@RemoteServiceRelativePath("shout")

public interface ShoutService extends RemoteService{


String shoutToServer(Shout s);

}

this interface must extends the RemoteService and also must define the path to access this service using the RemoteServiceRelativePath annottation.

In the ShoutServiceAsync we should add a void method that will receive a Shout object and a AsyncCallback object.
This is the code to the ShoutServiceAsync:

public interface ShoutServiceAsync {


void shoutToServer(Shout s, AsyncCallback callback);

}

Now we need to create the server side service.
Let's create the ShoutServiceImpl in the server package.

@SuppressWarnings("serial")

public class ShoutServiceImpl extends RemoteServiceServlet implements ShoutService{


public String shoutToServer(Shout s){

return s.getMessage();

}

}

this class must extend te RemoteServiceServlet and also implements the interface of the Service we created before. Notice that it implements the Service and not the ServiceAsync.
For now our method will just return the message of the Shout object.
Well, now we are almost there.
Let's change now the behavior of the click of the send button.
Get back to the entrypoint class and create a ShoutServiceAsync final variable:

/**

* Create a remote service proxy to talk to the server-side Greeting service.

*/

private final GreetingServiceAsync greetingService = GWT

.create(GreetingService.class);

private final ShoutServiceAsync shoutService = GWT.create(ShoutService.class);


notice that we declare the service using the Asycn interface, but in the GWT method we use the Service class.

Now, look for the method "sendNameToServer". and remove the code inside it, we wont need it anymore.
next put this code:

sendButton.setEnabled(false);

Shout s = new Shout(nameField.getText());

nameField.setText("");

shoutService.shoutToServer(s, new AsyncCallback(){

public void onFailure(Throwable caught) {};

public void onSuccess(String result) {

messagesPanel.add(new HTML(result));

sendButton.setEnabled(true);

};

});

we are just creating a shout using the text in the textfield, reseting the textfield and calling the service method, passing our shout and the asyncCallback.
In the callback we can do something if the method fails, like by connection reset or a exception in the server using the onFailure method.
In the onSuccess method we put our code to treat the answer of the server.
In this case we are just adding the string into a HTML widget inside the panel. As the panel is a VerticalPanel all this widgets will be placed one under the other.

----UPDATED----------

Also you need to edit the web.xml file inside the WEB-INF directory.
You need to configure your servlets (The ShoutServiceImpl).
Just copy and paste the greetServlet and change the servlet-name to shoutServlet and the servlet-class to your.path.to.ShoutServiceImpl . Also copy and paste the servlet-mapping of the greetServlet and change the servlet-name to shoutServlet and the url-pattern to /[module-name]/shout .
Observe that this /shout is the name we put on the service interface annottation: @RemoteServiceRelativePath("shout").

-----UPDATED-----------

In this is it. In the next post we will save this shout in the database and load the shout list when the page is loaded and keeping updating the list while the page is open.

See you there!