Posts Tagged ‘Data Formats’

العربية: Android logo
Get Contact Details (ID, Name, Phone, Photo)

res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent" >
    <Button android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Select a Contact"
            android:onClick="onClickSelectContact" />
    <ImageView android:id="@+id/img_contact"
               android:layout_height="wrap_content"
               android:layout_width="match_parent"
               android:adjustViewBounds="true"
               android:contentDescription="Contacts Image"
                />
</LinearLayout>

Read More »

ListView in simplest form with plain text only. This exercise describe how to add a icon in ListView.

ListView, with icon

create a new file in /res/layout/row.xml, to setup our layout on each row.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon"/>
<TextView
android:id="@+id/weekofday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

AndroidList.java

package com.exercise.AndroidList;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

public class AndroidList extends ListActivity {

String[] DayOfWeek = {"Sunday", "Monday", "Tuesday",
  "Wednesday", "Thursday", "Friday", "Saturday"
};

   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       //setContentView(R.layout.main);
       setListAdapter(new ArrayAdapter<String>(this,
         R.layout.row, R.id.weekofday, DayOfWeek));
   }
}
Enhanced by Zemanta

It’s a simple way to load ImageView with a bitmap from internet, via http connection.

Load ImageView with bitmap from internet

In order to load something from internet, the AndroidManifest.xml have to be modified to grand permission for internet access.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.exercise.AndroidWebImage"
     android:versionCode="1"
     android:versionName="1.0">
   <application android:icon="@drawable/icon" android:label="@string/app_name">
       <activity android:name=".AndroidWebImage"
                 android:label="@string/app_name">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
       </activity>

   </application>
   <uses-sdk android:minSdkVersion="4" />
 <uses-permission android:name="android.permission.INTERNET" />
</manifest>

Modify main.xml to include a ImageView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   >
<TextView 
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="@string/hello"
   />
<ImageView
   android:id="@+id/image"
   android:scaleType="center"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
/>
</LinearLayout>

java code:

package com.exercise.AndroidWebImage;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;

public class AndroidWebImage extends Activity {

String image_URL=
 "http://4.bp.blogspot.com/_C5a2qH8Y_jk/StYXDpZ9-WI/AAAAAAAAAJQ/sCgPx6jfWPU/S1600-R/android.png";

   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);

       ImageView bmImage = (ImageView)findViewById(R.id.image);
    BitmapFactory.Options bmOptions;
    bmOptions = new BitmapFactory.Options();
    bmOptions.inSampleSize = 1;
    Bitmap bm = LoadImage(image_URL, bmOptions);
    bmImage.setImageBitmap(bm);
   }

   private Bitmap LoadImage(String URL, BitmapFactory.Options options)
   {       
    Bitmap bitmap = null;
    InputStream in = null;       
       try {
           in = OpenHttpConnection(URL);
           bitmap = BitmapFactory.decodeStream(in, null, options);
           in.close();
       } catch (IOException e1) {
       }
       return bitmap;               
   }

private InputStream OpenHttpConnection(String strURL) throws IOException{
 InputStream inputStream = null;
 URL url = new URL(strURL);
 URLConnection conn = url.openConnection();

 try{
  HttpURLConnection httpConn = (HttpURLConnection)conn;
  httpConn.setRequestMethod("GET");
  httpConn.connect();

  if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
   inputStream = httpConn.getInputStream();
  }
 }
 catch (Exception ex)
 {
 }
 return inputStream;
}

}
Enhanced by Zemanta

Welcome to Part-4 of the 7-part series where we will go through different aspects for Struts2 Framework with some useful examples. In previous part we went through Struts2 Validation Framework. We saw how easy it is to integrate validation in your struts2 application.

In this part we will discuss about Tiles Framework and its Integration with Struts2. We will add Tiles support to our HelloWorld Struts application that we created in previous parts. I strongly recommend you to go through previous articles and download the source code of our sample application.

Struts 2 Tutorial List

Introduction to Tiles 2

Nowadays, website are generally divided into pieces of reusable template that are being rendered among different web pages. For example a site containing header, footer, menu etc. This items remains same through out the website and give it a common look and feel. It is very difficult to hard code this in each and every webpage and if later a change is needed than all the pages needs to be modified. Hence we use templatization mechanism. We create a common Header, Footer, Menu page and include this in each page.

Tiles Plugin allow both templating and componentization. In fact, both mechanisms are similar: you
define parts of page (a “Tile”) that you assemble to build another part or a full page. A part can
take parameters, allowing dynamic content, and can be seen as a method in JAVA language. Tiles is a templating system used to maintain a consistent look and feel across all the web pages of a web application. It increase the reusability of template and reduce code duplication.

A common layout of website is defined in a central configuration file and this layout can be extended across all the webpages of the web application.

Our Application Layout

Our goal is to add Header, Footer and Menu to our StrutsHelloWorld application. Following will be the layout of the same.
struts2-tiles-layout

Required JAR files

In order to add Tiles support to our Struts2 application, we will need few jar files. Following is the list of JARs in our example. Add these JARs in WEB-INF/lib folder.
struts2-tiles-jar-files

Configuring Tiles in web.xml

To configure Tiles, an entry for listener has to be made in web.xml. Open the web.xml from WEB-INF folder and add following code into it.

01.<listener>
02.<listener-class>
03.
04.org.apache.struts2.tiles.StrutsTilesListener
05.</listener-class>
06.</listener>
07.<context-param>
08.<param-name>tilesDefinitions</param-name>
09.<param-value>/WEB-INF/tiles.xml</param-value>
10.
11.</context-param>

The above code configure Tiles listener in web.xml. An input configuration file /WEB-INF/tiles.xml is passed as argument. This file contains the Tiles definition for our web application.

Create a file tiles.xml in WEB-INF folder and copy following code into it.
struts2-tiles-xml

01.<?xml version="1.0" encoding="UTF-8" ?>
02.
03.<!--DOCTYPE tiles-definitions PUBLIC-->
04."-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
06.<tiles-definitions>
07.<definition name="baseLayout" template="/BaseLayout.jsp">
08.<put-attribute name="title" value="" />
09.
10.<put-attribute name="header" value="/Header.jsp" />
11.<put-attribute name="menu" value="/Menu.jsp" />
12.
13.<put-attribute name="body" value="" />
14.<put-attribute name="footer" value="/Footer.jsp" />
15.
16.</definition>
17.<definition name="/welcome.tiles" extends="baseLayout">
18.<put-attribute name="title" value="Welcome" />
19.
20.<put-attribute name="body" value="/Welcome.jsp" />
21.</definition>
22.<definition name="/customer.tiles" extends="baseLayout">
23.
24.<put-attribute name="title" value="Customer Form" />
25.<put-attribute name="body" value="/Customer.jsp" />
26.
27.</definition>
28.<definition name="/customer.success.tiles" extends="baseLayout">
29.<put-attribute name="title" value="Customer Added" />
30.
31.<put-attribute name="body" value="/SuccessCustomer.jsp" />
32.</definition>
33.</tiles-definitions>

Here in tiles.xml we have define a template baseLayout. This layout contains attributes such as Header, Title, Body, Menu and Footer. The layout is then extended and new definitions for Welcome page and Customer page is defined. We have override the default layout and changed the content for Body and Title.

Creating JSPs

struts-2-tiles-layout-jspWe will define the template for our webapplication in a JSP file called BaseLayout.jsp. This template will contain different segments of web page (Header, Footer, Menu etc). Create 4 new JSP files BaseLayout.jsp, Header.jsp, Menu.jsp and Footer.jsp and copy following content in each of them.
BaseLayout.jsp

01.<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
02.<!--DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"-->
03.
05.<html>
06.<head>
07.<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
08.<title><tiles:insertAttribute name="title" ignore="true" /></title>
09.
10.</head>
11.<body>
12.<table border="1" cellpadding="2" cellspacing="2" align="center">
13.<tr>
14.
15.<td height="30" colspan="2"><tiles:insertAttribute name="header" />
16.</td>
17.</tr>
18.
19.<tr>
20.<td height="250"><tiles:insertAttribute name="menu" /></td>
21.<td width="350"><tiles:insertAttribute name="body" /></td>
22.
23.</tr>
24.<tr>
25.<td height="30" colspan="2"><tiles:insertAttribute name="footer" />
26.
27.</td>
28.</tr>
29.</table>
30.</body>
31.</html>

Header.jsp

1.<%@ page contentType="text/html; charset=UTF-8"%>
2.
3.<%@ taglib prefix="s" uri="/struts-tags"%>
4.<h2>Struts2 Example - ViralPatel.net</h2>

Menu.jsp

1.<%@ page contentType="text/html; charset=UTF-8"%>
2.
3.<%@ taglib prefix="s" uri="/struts-tags"%>
4.<s:a href="customer-form">Customer</s:a>

Footer.jsp

1.<%@ page contentType="text/html; charset=UTF-8"%>
2.
3.<%@ taglib prefix="s" uri="/struts-tags"%>
4.Copyright &copy; ViralPatel.net

Modifications in Struts.xml

In struts.xml we defined result tag which maps a particular action with a JSP page. Now we will modify it and map the result with Tiles. Following will be the content of struts.xml file.

01.<?xml version="1.0" encoding="UTF-8" ?>
02.
03.<!--DOCTYPE struts PUBLIC-->
04."-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
06.
07.<struts>
08.<constant name="struts.enable.DynamicMethodInvocation"
09.value="false" />
10.
11.<constant name="struts.devMode" value="false" />
12.<constant name="struts.custom.i18n.resources"
13.value="ApplicationResources" />
14.
15.<package name="default" extends="struts-default" namespace="/">
16.<result-types>
17.<result-type name="tiles"
18.
19.class="org.apache.struts2.views.tiles.TilesResult" />
20.</result-types>
21.<action name="login"
22.class="net.viralpatel.struts2.LoginAction">
23.
24.<result name="success" type="tiles">/welcome.tiles</result>
25.<result name="error">Login.jsp</result>
26.</action>
27.
28.<action name="customer"
29.class="net.viralpatel.struts2.CustomerAction">
30.<result name="success" type="tiles">/customer.success.tiles</result>
31.
32.<result name="input" type="tiles">/customer.tiles</result>
33.</action>
34.<action name="customer-form">
35.<result name="success" type="tiles">/customer.tiles</result>
36.
37.</action>
38.</package>
39.</struts>

The struts.xml now defines a new Result type for Tiles. This result type is used in tag for different actions. Also note that we have define a new action customer-form. This is just an empty declaration to redirect user to Customer form page when she clicks Customer link from menu.

That’s All Folks

Compile and Execute the application in Eclipse and see that the header, menu and footer are properly applied.
Welcome Page with Tiles
struts3
Customer Page with Tiles
struts2
Customer Success Page with Tiles
struts1

Download Source Code

Click here to download Source Code without JAR files (11KB)

by Paul Beusterien, Mobile Developer Solutions, Carl Stehle, Appception Inc. and Tomaz Kregar, Bucka IT

Image representing PayPal as depicted in Crunc...

Adding the Plugin to your project

Using this plugin requires Android Cordova (PhoneGap) and the PayPal Mobile Payments Library. The PayPal Mobile Payments Library can be downloaded here.

  1. Create an Android Cordova project. Details at http://docs.phonegap.com/en/2.0.0/guide_getting-started_android_index.md.html
  2. Put PayPal_MPL.jar into your project’s libs directory and add it to the build path. In Eclipse, right click on PayPal_MPL.jar and select Add to Build Path.
  3. Copy assets/www/ files into your project’s assets/www/ directory
  4. Copy src/com/phonegap/plugin/ files into your project’s src/com/phonegap/plugin/ directory
  5. Make sure your AndroidManifest.xml includes a superset of the permissions shown in the reference AndroidManifest.xml
  6. Add the com.paypal.android.MEP.PayPalActivity as shown in the reference AndroidManifest.xml
  7. Include the plugin registration in /res/xml/config.xml as shown in the reference config.xml
  8. Make sure the cordova.{version}.js filename in index.html matches the filename in your www directory.
  9. Deploy and test the app. The default environment is ENV_NONE.

Using the PayPal Sandbox

  1. Set up a PayPal buyer and seller sandbox account from https://developer.paypal.com/
  2. Update demo.js to use ENV_SANDBOX instead of ENV_NONE. See comments near bottom of demo.js
  3. In index.html, update the pmt_recipient field to your sandbox seller account

 

Helping URl: https://github.com/phonegap/phonegap-plugins/tree/master/Android/PayPalPlugin

 

Enhanced by Zemanta

English: A download symbol.

When our application does a task that takes a considerable amount of time, it is common sense to show the progress of the task to the user.
This is a good User Experience practice. In this tutorial i will be discussing the implementation of a process-progress dialog.

As an example, i am displaying a progress bar that runs while the app downloads an image from the web. And once the image is downloaded
completely i am showing the image in a image view. You could modify this example and try it with any file type you may wish. That could be fun!

Download Code

Creating new Project

1. Create a new project and fill all the details. File ⇒ New ⇒ Android Project
2. Open your main.xml are create a button to show download progress bar. Also define a ImageView to show downloaded image. Paste the following code in your main.xml

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <!-- Download Button -->
    <Button android:id="@+id/btnProgressBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Download File with Progress Bar"
        android:layout_marginTop="50dip"/>
    <!-- Image view to show image after downloading -->
    <ImageView android:id="@+id/my_image"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

3. Now in your main activity class import necessary classes and buttons. I am starting a new asynctask to download the file after clicking on show progress bar button.

public class AndroidDownloadFileByProgressBarActivity extends Activity {
    // button to show progress dialog
    Button btnShowProgress
    // Progress Dialog
    private ProgressDialog pDialog;
    // Progress dialog type (0 - for Horizontal progress bar)
    public static final int progress_bar_type = 0;
    // File url to download
    private static String file_url = "http://api.androidhive.info/progressdialog/hive.jpg";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // show progress bar button
        btnShowProgress = (Button) findViewById(R.id.btnProgressBar);
        // Image view to show image after downloading
        my_image = (ImageView) findViewById(R.id.my_image);
        /**
         * Show Progress bar click event
         * */
        btnShowProgress.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // starting new Async Task
                new DownloadFileFromURL().execute(file_url);
            }
        });
    }

4. Progress Dialog can be shown using ProgressDialog class. It is a subclass of normal AlertDialog class. So add an alert method in your main activity class.

/**
 * Showing Dialog
 * */
@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
    case progress_bar_type:
        pDialog = new ProgressDialog(this);
        pDialog.setMessage("Downloading file. Please wait...");
        pDialog.setIndeterminate(false);
        pDialog.setMax(100);
        pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        pDialog.setCancelable(true);
        pDialog.show();
        return pDialog;
    default:
        return null;
    }
}

5. Now we need to add our Async Background thread to download file from url. In your main activity add a asynctask class and name it as DownloadFileFromURL(). After downloading image from the web i am reading the downloaded image from the sdcard and displaying in a imageview.

/**
 * Background Async Task to download file
 * */
class DownloadFileFromURL extends AsyncTask<String, String, String> {
    /**
     * Before starting background thread
     * Show Progress Bar Dialog
     * */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        showDialog(progress_bar_type);
    }
    /**
     * Downloading file in background thread
     * */
    @Override
    protected String doInBackground(String... f_url) {
        int count;
        try {
            URL url = new URL(f_url[0]);
            URLConnection conection = url.openConnection();
            conection.connect();
            // getting file length
            int lenghtOfFile = conection.getContentLength();
            // input stream to read file - with 8k buffer
            InputStream input = new BufferedInputStream(url.openStream(), 8192);
            // Output stream to write file
            OutputStream output = new FileOutputStream("/sdcard/downloadedfile.jpg");
            byte data[] = new byte[1024];
            long total = 0;
            while ((count = input.read(data)) != -1) {
                total += count;
                // publishing the progress....
                // After this onProgressUpdate will be called
                publishProgress(""+(int)((total*100)/lenghtOfFile));
                // writing data to file
                output.write(data, 0, count);
            }
            // flushing output
            output.flush();
            // closing streams
            output.close();
            input.close();
        } catch (Exception e) {
            Log.e("Error: ", e.getMessage());
        }
        return null;
    }
    /**
     * Updating progress bar
     * */
    protected void onProgressUpdate(String... progress) {
        // setting progress percentage
        pDialog.setProgress(Integer.parseInt(progress[0]));
   }
    /**
     * After completing background task
     * Dismiss the progress dialog
     * **/
    @Override
    protected void onPostExecute(String file_url) {
        // dismiss the dialog after the file was downloaded
        dismissDialog(progress_bar_type);
        // Displaying downloaded image into image view
        // Reading image path from sdcard
        String imagePath = Environment.getExternalStorageDirectory().toString() + "/downloadedfile.jpg";
        // setting downloaded into image view
        my_image.setImageDrawable(Drawable.createFromPath(imagePath));
    }
}

6. Open your AndroidManifest.xml file and add internet connect permission and writing to sdcard permission.

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
    package="com.example.androidhive"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk android:minSdkVersion="8" />
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".AndroidDownloadFileByProgressBarActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <!-- Permission: Allow Connect to Internet -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- Permission: Writing to SDCard -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>

7. Run your Application and click on show progress bar button to see your progress bar. You can see the downloaded image in imageView once it is downloaded.

android download file and showing progress bar

Final Code

package com.example.androidhive;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class AndroidDownloadFileByProgressBarActivity extends Activity {
    // button to show progress dialog
    Button btnShowProgress;
    // Progress Dialog
    private ProgressDialog pDialog;
    ImageView my_image;
    // Progress dialog type (0 - for Horizontal progress bar)
    public static final int progress_bar_type = 0;
    // File url to download
    private static String file_url = "http://api.androidhive.info/progressdialog/hive.jpg";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // show progress bar button
        btnShowProgress = (Button) findViewById(R.id.btnProgressBar);
        // Image view to show image after downloading
        my_image = (ImageView) findViewById(R.id.my_image);
        /**
         * Show Progress bar click event
         * */
        btnShowProgress.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // starting new Async Task
                new DownloadFileFromURL().execute(file_url);
            }
        });
    }
    /**
     * Showing Dialog
     * */
    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
        case progress_bar_type: // we set this to 0
            pDialog = new ProgressDialog(this);
            pDialog.setMessage("Downloading file. Please wait...");
            pDialog.setIndeterminate(false);
            pDialog.setMax(100);
            pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            pDialog.setCancelable(true);
            pDialog.show();
            return pDialog;
        default:
            return null;
        }
    }
    /**
     * Background Async Task to download file
     * */
    class DownloadFileFromURL extends AsyncTask<String, String, String> {
        /**
         * Before starting background thread
         * Show Progress Bar Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            showDialog(progress_bar_type);
        }
        /**
         * Downloading file in background thread
         * */
        @Override
        protected String doInBackground(String... f_url) {
            int count;
            try {
                URL url = new URL(f_url[0]);
                URLConnection conection = url.openConnection();
                conection.connect();
                // this will be useful so that you can show a tipical 0-100% progress bar
                int lenghtOfFile = conection.getContentLength();
                // download the file
                InputStream input = new BufferedInputStream(url.openStream(), 8192);
                // Output stream
                OutputStream output = new FileOutputStream("/sdcard/downloadedfile.jpg");
                byte data[] = new byte[1024];
                long total = 0;
                while ((count = input.read(data)) != -1) {
                    total += count;
                    // publishing the progress....
                    // After this onProgressUpdate will be called
                    publishProgress(""+(int)((total*100)/lenghtOfFile));
                    // writing data to file
                    output.write(data, 0, count);
                }
                // flushing output
                output.flush();
                // closing streams
                output.close();
                input.close();
            } catch (Exception e) {
                Log.e("Error: ", e.getMessage());
            }
            return null;
        }
        /**
         * Updating progress bar
         * */
        protected void onProgressUpdate(String... progress) {
            // setting progress percentage
            pDialog.setProgress(Integer.parseInt(progress[0]));
       }
        /**
         * After completing background task
         * Dismiss the progress dialog
         * **/
        @Override
        protected void onPostExecute(String file_url) {
            // dismiss the dialog after the file was downloaded
            dismissDialog(progress_bar_type);
            // Displaying downloaded image into image view
            // Reading image path from sdcard
            String imagePath = Environment.getExternalStorageDirectory().toString() + "/downloadedfile.jpg";
            // setting downloaded into image view
            my_image.setImageDrawable(Drawable.createFromPath(imagePath));
        }
    }
}

العربية: Android logo

A layout defines the visual structure for a user interface, such as the UI for an activity or app widget. You can declare a layout in two ways:

  • Declare UI elements in XML. Android provides a straightforward XML vocabulary that corresponds to the View classes and subclasses, such as those for widgets and layouts.
  • Instantiate layout elements at runtime. Your application can create View and ViewGroup objects (and manipulate their properties) programmatically.

The Android framework gives you the flexibility to use either or both of these methods for declaring and managing your application’s UI. For example, you could declare your application’s default layouts in XML, including the screen elements that will appear in them and their properties. You could then add code in your application that would modify the state of the screen objects, including those declared in XML, at run time.

  • The ADT Plugin for Eclipse offers a layout preview of your XML — with the XML file opened, select the Layout tab.
  • You should also try the Hierarchy Viewer tool, for debugging layouts — it reveals layout property values, draws wireframes with padding/margin indicators, and full rendered views while you debug on the emulator or device.
  • The layoutopt tool lets you quickly analyze your layouts and hierarchies for inefficiencies or other problems.

The advantage to declaring your UI in XML is that it enables you to better separate the presentation of your application from the code that controls its behavior. Your UI descriptions are external to your application code, which means that you can modify or adapt it without having to modify your source code and recompile. For example, you can create XML layouts for different screen orientations, different device screen sizes, and different languages. Additionally, declaring the layout in XML makes it easier to visualize the structure of your UI, so it’s easier to debug problems. As such, this document focuses on teaching you how to declare your layout in XML. If you’re interested in instantiating View objects at runtime, refer to the ViewGroup and View class references.

In general, the XML vocabulary for declaring UI elements closely follows the structure and naming of the classes and methods, where element names correspond to class names and attribute names correspond to methods. In fact, the correspondence is often so direct that you can guess what XML attribute corresponds to a class method, or guess what class corresponds to a given xml element. However, note that not all vocabulary is identical. In some cases, there are slight naming differences. For example, the EditText element has a text attribute that corresponds to EditText.setText().

Tip: Learn more about different layout types in Common Layout Objects. There are also a collection of tutorials on building various layouts in the Hello Views tutorial guide.

Write the XML


Using Android’s XML vocabulary, you can quickly design UI layouts and the screen elements they contain, in the same way you create web pages in HTML — with a series of nested elements.

Each layout file must contain exactly one root element, which must be a View or ViewGroup object. Once you’ve defined the root element, you can add additional layout objects or widgets as child elements to gradually build a View hierarchy that defines your layout. For example, here’s an XML layout that uses a vertical LinearLayout to hold a TextView and a Button:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent" 
              android:layout_height="fill_parent" 
              android:orientation="vertical" >
    <TextView android:id="@+id/text"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Hello, I am a TextView" />
    <Button android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello, I am a Button" />
</LinearLayout>

After you’ve declared your layout in XML, save the file with the .xml extension, in your Android project’s res/layout/ directory, so it will properly compile.

More information about the syntax for a layout XML file is available in the Layout Resources document.

Load the XML Resource


When you compile your application, each XML layout file is compiled into a View resource. You should load the layout resource from your application code, in your Activity.onCreate() callback implementation. Do so by calling setContentView(), passing it the reference to your layout resource in the form of: R.layout.layout_file_name For example, if your XML layout is saved as main_layout.xml, you would load it for your Activity like so:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_layout);
}

The onCreate() callback method in your Activity is called by the Android framework when your Activity is launched (see the discussion about lifecycles, in the Activities document).

Attributes


Every View and ViewGroup object supports their own variety of XML attributes. Some attributes are specific to a View object (for example, TextView supports the textSize attribute), but these attributes are also inherited by any View objects that may extend this class. Some are common to all View objects, because they are inherited from the root View class (like the id attribute). And, other attributes are considered “layout parameters,” which are attributes that describe certain layout orientations of the View object, as defined by that object’s parent ViewGroup object.

ID

Any View object may have an integer ID associated with it, to uniquely identify the View within the tree. When the application is compiled, this ID is referenced as an integer, but the ID is typically assigned in the layout XML file as a string, in the id attribute. This is an XML attribute common to all View objects (defined by the View class) and you will use it very often. The syntax for an ID, inside an XML tag is:

android:id="@+id/my_button"

The at-symbol (@) at the beginning of the string indicates that the XML parser should parse and expand the rest of the ID string and identify it as an ID resource. The plus-symbol (+) means that this is a new resource name that must be created and added to our resources (in the R.java file). There are a number of other ID resources that are offered by the Android framework. When referencing an Android resource ID, you do not need the plus-symbol, but must add the android package namespace, like so:

android:id="@android:id/empty"

With the android package namespace in place, we’re now referencing an ID from the android.R resources class, rather than the local resources class.

In order to create views and reference them from the application, a common pattern is to:

  1. Define a view/widget in the layout file and assign it a unique ID:
    <Button android:id="@+id/my_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/my_button_text"/>
  2. Then create an instance of the view object and capture it from the layout (typically in the onCreate() method):
    Button myButton = (Button) findViewById(R.id.my_button);

Defining IDs for view objects is important when creating a RelativeLayout. In a relative layout, sibling views can define their layout relative to another sibling view, which is referenced by the unique ID.

An ID need not be unique throughout the entire tree, but it should be unique within the part of the tree you are searching (which may often be the entire tree, so it’s best to be completely unique when possible).

Layout Parameters

XML layout attributes named layout_something define layout parameters for the View that are appropriate for the ViewGroup in which it resides.

Every ViewGroup class implements a nested class that extends ViewGroup.LayoutParams. This subclass contains property types that define the size and position for each child view, as appropriate for the view group. As you can see in figure 1, the parent view group defines layout parameters for each child view (including the child view group).

Figure 1. Visualization of a view hierarchy with layout parameters associated with each view.

Note that every LayoutParams subclass has its own syntax for setting values. Each child element must define LayoutParams that are appropriate for its parent, though it may also define different LayoutParams for its own children.

All view groups include a width and height (layout_width and layout_height), and each view is required to define them. Many LayoutParams also include optional margins and borders.

 

You can specify width and height with exact measurements, though you probably won’t want to do this often. More often, you will use one of these constants to set the width or height:

  • wrap_content tells your view to size itself to the dimensions required by its content
  • fill_parent (renamed match_parent in API Level 8) tells your view to become as big as its parent view group will allow.

In general, specifying a layout width and height using absolute units such as pixels is not recommended. Instead, using relative measurements such as density-independent pixel units (dp), wrap_content, or fill_parent, is a better approach, because it helps ensure that your application will display properly across a variety of device screen sizes. The accepted measurement types are defined in the Available Resources document.

Layout Position


The geometry of a view is that of a rectangle. A view has a location, expressed as a pair of left and top coordinates, and two dimensions, expressed as a width and a height. The unit for location and dimensions is the pixel.

It is possible to retrieve the location of a view by invoking the methods getLeft() and getTop(). The former returns the left, or X, coordinate of the rectangle representing the view. The latter returns the top, or Y, coordinate of the rectangle representing the view. These methods both return the location of the view relative to its parent. For instance, when getLeft() returns 20, that means the view is located 20 pixels to the right of the left edge of its direct parent.

In addition, several convenience methods are offered to avoid unnecessary computations, namely getRight() and getBottom(). These methods return the coordinates of the right and bottom edges of the rectangle representing the view. For instance, calling getRight() is similar to the following computation: getLeft() + getWidth().

Size, Padding and Margins


The size of a view is expressed with a width and a height. A view actually possess two pairs of width and height values.

The first pair is known as measured width and measured height. These dimensions define how big a view wants to be within its parent. The measured dimensions can be obtained by calling getMeasuredWidth() and getMeasuredHeight().

The second pair is simply known as width and height, or sometimes drawing width and drawing height. These dimensions define the actual size of the view on screen, at drawing time and after layout. These values may, but do not have to, be different from the measured width and height. The width and height can be obtained by calling getWidth() and getHeight().

To measure its dimensions, a view takes into account its padding. The padding is expressed in pixels for the left, top, right and bottom parts of the view. Padding can be used to offset the content of the view by a specific amount of pixels. For instance, a left padding of 2 will push the view’s content by 2 pixels to the right of the left edge. Padding can be set using the setPadding(int, int, int, int) method and queried by calling getPaddingLeft(), getPaddingTop(), getPaddingRight() and getPaddingBottom().

Even though a view can define a padding, it does not provide any support for margins. However, view groups provide such a support. Refer to ViewGroup and ViewGroup.MarginLayoutParams for further information.

For more information about dimensions, see Dimension Values.

Common Layouts


Each subclass of the ViewGroup class provides a unique way to display the views you nest within it. Below are some of the more common layout types that are built into the Android platform.

Note: Although you can nest one or more layouts within another layout to acheive your UI design, you should strive to keep your layout hierarchy as shallow as possible. Your layout draws faster if it has fewer nested layouts (a wide view hierarchy is better than a deep view hierarchy).

Linear Layout

A layout that organizes its children into a single horizontal or vertical row. It creates a scrollbar if the length of the window exceeds the length of the screen.

Relative Layout

Enables you to specify the location of child objects relative to each other (child A to the left of child B) or to the parent (aligned to the top of the parent).

Web View

Displays web pages.

Building Layouts with an Adapter


When the content for your layout is dynamic or not pre-determined, you can use a layout that subclasses AdapterView to populate the layout with views at runtime. A subclass of the AdapterView class uses an Adapter to bind data to its layout. The Adapter behaves as a middle-man between the data source and the AdapterView layout—the Adapter retreives the data (from a source such as an array or a database query) and converts each entry into a view that can be added into the AdapterView layout.

Common layouts backed by an adapter include:

List View

Displays a scrolling single column list.

Grid View

Displays a scrolling grid of columns and rows.

Filling an adapter view with data

You can populate an AdapterView such as ListView or GridView by binding the AdapterView instance to an Adapter, which retrieves data from an external source and creates a View that represents each data entry.

Android provides several subclasses of Adapter that are useful for retrieving different kinds of data and building views for an AdapterView. The two most common adapters are:

ArrayAdapter
Use this adapter when your data source is an array. By default, ArrayAdapter creates a view for each array item by calling toString() on each item and placing the contents in a TextView.For example, if you have an array of strings you want to display in a ListView, initialize a new ArrayAdapter using a constructor to specify the layout for each string and the string array:

ArrayAdapter adapter = new ArrayAdapter<String>(this, 
        android.R.layout.simple_list_item_1, myStringArray);

The arguments for this constructor are:

  • Your app Context
  • The layout that contains a TextView for each string in the array
  • The string array

Then simply call setAdapter() on your ListView:

ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);

To customize the appearance of each item you can override the toString() method for the objects in your array. Or, to create a view for each item that’s something other than a TextView (for example, if you want an ImageView for each array item), extend the ArrayAdapter class and override getView() to return the type of view you want for each item.

SimpleCursorAdapter
Use this adapter when your data comes from a Cursor. When using SimpleCursorAdapter, you must specify a layout to use for each row in the Cursor and which columns in the Cursor should be inserted into which views of the layout. For example, if you want to create a list of people’s names and phone numbers, you can perform a query that returns a Cursor containing a row for each person and columns for the names and numbers. You then create a string array specifying which columns from the Cursor you want in the layout for each result and an integer array specifying the corresponding views that each column should be placed:

String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME, 
                        ContactsContract.CommonDataKinds.Phone.NUMBER};
int[] toViews = {R.id.display_name, R.id.phone_number};

When you instantiate the SimpleCursorAdapter, pass the layout to use for each result, the Cursor containing the results, and these two arrays:

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, 
        R.layout.person_name_and_number, cursor, fromColumns, toViews, 0);
ListView listView = getListView();
listView.setAdapter(adapter);

The SimpleCursorAdapter then creates a view for each row in the Cursor using the provided layout by inserting each fromColumns item into the corresponding toViews view.

.

If, during the course of your application’s life, you change the underlying data that is read by your adapter, you should call notifyDataSetChanged(). This will notify the attached view that the data has been changed and it should refresh itself.

Handling click events

You can respond to click events on each item in an AdapterView by implementing the AdapterView.OnItemClickListener interface. For example:

// Create a message handling object as an anonymous class.
private OnItemClickListener mMessageClickedHandler = new OnItemClickListener() {
    public void onItemClick(AdapterView parent, View v, int position, long id) {
        // Do something in response to the click
    }
};

listView.setOnItemClickListener(mMessageClickedHandler);
Enhanced by Zemanta

Recently I had a requirement where using Spring MVC we had to take inputs multiple rows of data from user. The form had many rows which user can edit and submit. Spring MVC provides very simple yet elegant way of collecting data from multiple rows from HTML form and store them in List of Beans in Java.

18% Price Drop: Samsung 51" Black Plasma 720P HDTV – PN51E450

Lets look at the requirement first. We have a screen where data for multiple Contacts is displayed. The Contact data is displayed in an HTML table. Each row in the table represents a single contact. Contact details consist of attributes such as Firstname, Lastname, Email and Phone number.

Related: Spring 3 MVC Tutorial Series (Must Read)

The Add Contact form would look like following:
spring-mvc-multi-row-form

Lets see the code behind this example.

Tools and Technologies used:

  1. Java 5 or above
  2. Eclipse 3.3 or above
  3. Spring MVC 3.0

Step 1: Create Project Structure

Open Eclipse and create a Dynamic Web Project.
eclipse-dynamic-web-project

Enter project name as SpringMVC_Multi_Row and press Finish.

Step 2: Copy Required JAR files

Once the Dynamic Web Project is created in Eclipse, copy the required JAR files under WEB-INF/lib folder. Following are the list of JAR files:
spring-mvc-multi-row-jar-files

 

Step 3: Adding Spring MVC support

Once the basic project setup is done, we will add Spring 3 MVC support. For that first modify default web.xml and add springs DispatcherServlet.

File: /WebContent/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>Spring3MVC-Multi-Row</display-name>
    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
</web-app>

Related: Tutorial: Learn Spring MVC Lifecycle

Now add spring-servlet.xml file under WEB-INF folder.

File: /WebContent/WEB-INF/spring-servlet.xml

<?xml  version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        
    <context:annotation-config />
    <context:component-scan base-package="net.viralpatel.spring3.controller" />  
    <bean id="jspViewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

Note that in above spring-servlet file, line 10, 11 defines context:annotation-config and component-scan tags. These tags let Spring MVC knows that the spring mvc annotations are used to map controllers and also the path from where the controller files needs to be loaded. All the files below package net.viralpatel.spring3.controller will be picked up and loaded by spring mvc.

Step 4: Add Spring Controller and Form classes

File: /src/net/viralpatel/spring3/form/Contact.java

package net.viralpatel.spring3.form;
public class Contact {
    private String firstname;
    private String lastname;
    private String email;
    private String phone;
    public Contact() {
    }
    public Contact(String firstname, String lastname, String email, String phone) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.email = email;
        this.phone = phone;
    }
    
    // Getter and Setter methods
}

File: /src/net/viralpatel/spring3/form/ContactForm.java

package net.viralpatel.spring3.form;
import java.util.List;
public class ContactForm {
    private List<Contact> contacts;
    public List<Contact> getContacts() {
        return contacts;
    }
    public void setContacts(List<Contact> contacts) {
        this.contacts = contacts;
    }
}

Note line 7 in above code how we have defined a List of bean Contact which will hold the multi-row data for each Contact.

File: /src/net/viralpatel/spring3/controller/ContactController.java

package net.viralpatel.spring3.controller;
import java.util.ArrayList;
import java.util.List;
import net.viralpatel.spring3.form.Contact;
import net.viralpatel.spring3.form.ContactForm;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class ContactController {
    
    private static List<Contact> contacts = new ArrayList<Contact>();
    static {
        contacts.add(new Contact("Barack", "Obama", "barack.o@whitehouse.com", "147-852-965"));
        contacts.add(new Contact("George", "Bush", "george.b@whitehouse.com", "785-985-652"));
        contacts.add(new Contact("Bill", "Clinton", "bill.c@whitehouse.com", "236-587-412"));
        contacts.add(new Contact("Ronald", "Reagan", "ronald.r@whitehouse.com", "369-852-452"));
    }
    
    @RequestMapping(value = "/get", method = RequestMethod.GET)
    public ModelAndView get() {
        
        ContactForm contactForm = new ContactForm();
        contactForm.setContacts(contacts);
        
        return new ModelAndView("add_contact" , "contactForm", contactForm);
    }
    
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public ModelAndView save(@ModelAttribute("contactForm") ContactForm contactForm) {
        System.out.println(contactForm);
        System.out.println(contactForm.getContacts());
        List<Contact> contacts = contactForm.getContacts();
        
        if(null != contacts && contacts.size() > 0) {
            ContactController.contacts = contacts;
            for (Contact contact : contacts) {
                System.out.printf("%s t %s n", contact.getFirstname(), contact.getLastname());
            }
        }
        
        return new ModelAndView("show_contact", "contactForm", contactForm);
    }
}

In above ContactController class, we have defile two methods: get() and save().

get() method: This method is used to display Contact form with pre-populated values. Note we added a list of contacts (Contacts are initialize in static block) in ContactForm bean object and set this inside a ModelAndView object. The add_contact.jsp is displayed which in turns display all contacts in tabular form to edit.

save() method: This method is used to fetch contact data from the form submitted and save it in the static array. Also it renders show_contact.jsp file to display contacts in tabular form.

Step 5: Add JSP View files

Add following files under WebContent/WEB-INF/jsp/ directory.

File: /WebContent/WEB-INF/jsp/add_contact.jsp

<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>Spring 3 MVC Multipe Row Submit - viralpatel.net</title>
</head>
<body>
<h2>Spring MVC Multiple Row Form Submit example</h2>
<form:form method="post" action="save.html" modelAttribute="contactForm">
    <table>
    <tr>
        <th>No.</th>
        <th>Name</th>
        <th>Lastname</th>
        <th>Email</th>
        <th>Phone</th>
    </tr>
    <c:forEach items="${contactForm.contacts}" var="contact" varStatus="status">
        <tr>
            <td align="center">${status.count}</td>
            <td><input name="contacts[${status.index}].firstname" value="${contact.firstname}"/></td>
            <td><input name="contacts[${status.index}].lastname" value="${contact.lastname}"/></td>
            <td><input name="contacts[${status.index}].email" value="${contact.email}"/></td>
            <td><input name="contacts[${status.index}].phone" value="${contact.phone}"/></td>
        </tr>
    </c:forEach>
</table
<br/>
<input type="submit" value="Save" />
    
</form:form>
</body>
</html>

In above JSP file, we display contact details in a table. Also each attribute is displayed in a textbox. Note that modelAttribute=”contactForm” is defined in <form:form /> tag. This tag defines the modelAttribute name for Spring mapping. On form submission, Spring will parse the values from request and fill the ContactForm bean and pass it to the controller.

Also note how we defined textboxes name. It is in form contacts[i].a. Thus Spring knows that we want to display the List item with index i and its attribute a.

contacts[${status.index}].firstname will generate each rows as follows:

contacts[0].firstname // mapped to first item in contacts list
contacts[1].firstname // mapped to second item in contacts list
contacts[2].firstname // mapped to third item in contacts list

Spring 3 MVC and path attribute and square bracket

One thing here is worth noting that we haven’t used Spring’s
tag to render textboxes. This is because Spring MVC 3 has a unique way of handling path attribute for
tag. If we define the textbox as follows:

<form:input path="contacts[${status.index}].firstname" />

Then instead of converting it to following HTML code:

<input name="contacts[0].firstname" />
<input name="contacts[1].firstname" />
<input name="contacts[2].firstname" />

It converts it into following:

<input name="contacts0.firstname" />
<input name="contacts1.firstname" />
<input name="contacts2.firstname" />

Note how it removed square brackets [ ] from name attribute. In previous versions of Spring (before 2.5) the square bracket were allowed in name attribute.

It seems w3c has later changed the HTML specification and removed [ ] from html input name.
Read the specification http://www.w3.org/TR/html4/types.html#type-name. It clearly says that:

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens (“-”), underscores (“_”), colons (“:”), and periods (“.”).

Thus, square brackets aren’t allowed in name attribute! And thus Spring 3 onwards this was implemented.

So far I haven’t got any workaround to use springs <form:input /> tag instead of plain html <input /> to render and fetch data from multiple rows.

File: /WebContent/WEB-INF/jsp/show_contact.jsp

<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>Spring 3 MVC Multipe Row Submit - viralpatel.net</title>
</head>
<body>
<h2>Show Contacts</h2>
<table width="50%">
    <tr>
        <th>Name</th>
        <th>Lastname</th>
        <th>Email</th>
        <th>Phone</th>
    </tr>
    <c:forEach items="${contactForm.contacts}" var="contact" varStatus="status">
        <tr>
            <td>${contact.firstname}</td>
            <td>${contact.lastname}</td>
            <td>${contact.email}</td>
            <td>${contact.phone}</td>
        </tr>
    </c:forEach>
</table
<br/>
<input type="button" value="Back" onclick="javascript:history.back()"/>
</body>
</html>

File: /WebContent/index.jsp

<jsp:forward page="get.html"></jsp:forward>

 

Final Project Structure

Once we have added all relevant source files and jar files, the project structure should look like following:
spring-multi-row-project-structure

 

Step 6: Execute it

Execute the web application Right click on project > Run As > Run on Server.

Add Contact page

Show Contact page
spring-multiple-row-list-show-page

Download Source Code

Spring-MVC-Multiple-Row-List-example.zip (2.9 MB)

Enhanced by Zemanta

Web sites have changed since the appearance of HTML5 and CSS3 and also after the latest jQuery releases. They now have interesting features which make them more dynamic and also easy to load and navigate because most of the graphics that were previously jpeg, gif or png files are now mostly done in code. Most of the sites in this article are making use of these new technologies and that can be seen easily when navigating. It’s a pleasure to see wonderful sites like for which people worked carefully and with a clear strategy.

mball.cz

mball.cz - Awesome New Website Designs To Inspire You

drivingfutures.com

drivingfutures.com - Awesome New Website Designs To Inspire You

iamyuna.com

iamyuna.com - Awesome New Website Designs To Inspire You

beautifulexplorer.com

beautifulexplorer.com - Awesome New Website Designs To Inspire You

pixfx.at

pixfx.at - Awesome New Website Designs To Inspire You

donq.com

donq.com - Awesome New Website Designs To Inspire You

teixido.co

teixido.co - Awesome New Website Designs To Inspire You

orangecinemaseries.fr

orangecinemaseries.fr - Awesome New Website Designs To Inspire You

hyperakt.com

hyperakt.com - Awesome New Website Designs To Inspire You

wingcheng.com

wingcheng.com - Awesome New Website Designs To Inspire You

pointlesscorp.com

pointlesscorp.com - Awesome New Website Designs To Inspire You

goslingo.com

goslingo.com - Awesome New Website Designs To Inspire You

factoria.it

factoria.it - Awesome New Website Designs To Inspire You

dodocase.com

dodocase.com - Awesome New Website Designs To Inspire You

wecreative.com.br

wecreative.com.br - Awesome New Website Designs To Inspire You

haardtline.de

haardtline.de - Awesome New Website Designs To Inspire You

evilstudio.com

evilstudio.com - Awesome New Website Designs To Inspire You

inflicted.nl

inflicted.nl - Awesome New Website Designs To Inspire You

davidhellmann.com

davidhellmann.com - Awesome New Website Designs To Inspire You

humaan.com.au

humaan.com.au - Awesome New Website Designs To Inspire You

vgweb.com.br

vgweb.com.br - Awesome New Website Designs To Inspire You

foreverheavy.com

foreverheavy.com - Awesome New Website Designs To Inspire You

moovents.com

moovents.com - Awesome New Website Designs To Inspire You

infinvision.com

infinvision.com - Awesome New Website Designs To Inspire You

macaronibros.com

macaronibros.com - Awesome New Website Designs To Inspire You

robedwards.org

robedwards.org - Awesome New Website Designs To Inspire You

zenithdelille.com

zenithdelille.com - Awesome New Website Designs To Inspire You

flowacademy.pl

flowacademy.pl - Awesome New Website Designs To Inspire You

pixelot.de

pixelot.de - Awesome New Website Designs To Inspire You

vertaaverkkoja.fi

vertaaverkkoja.fi - Awesome New Website Designs To Inspire You