Android ListViews and adapters

The ListView is an interface element that displays a list of items. The items in the list can have a custom layout consisting of other controls such as text or images. Managing a ListView is a bit more complex than you might think so we’ll walk through a relatively simple example here to see how all the parts fit together.

The app we’ll develop displays a Fragment on the left that contains an EditText into which the user can type some text, and a couple of buttons. The addItemButton adds an item to the ListView (displayed in a Fragment on the right) that contains the entered text along with the date and time at which the item was added. The clearListButton deletes all items from the list.

We’ve seen how to add Fragments to an Activity, so we’ll use the same technique here. First we create an XML file called enter_item.xml in the res–>layout folder and use Eclipse’s Graphical Layout editor to add the EditText and the two Buttons. Then we create a class to manage this layout, which looks like this:

package com.example.ex05listview;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;

public class AddItemFragment extends Fragment {
	AddItemListener activityCallback;

	public interface AddItemListener {
		public void onAddItemClick(ListItem item);
		public void onClearListClick();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		final View view = inflater.inflate(R.layout.enter_item, container, false);
		Button addItemButton = (Button) view.findViewById(R.id.addItemButton);
		addItemButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				EditText itemText = (EditText) view.findViewById(R.id.itemText);
				ListItem newItem = new ListItem(itemText.getText().toString());
				activityCallback.onAddItemClick(newItem);
			}
		});

		Button clearListButton = (Button) view.findViewById(R.id.clearListButton);
		clearListButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				activityCallback.onClearListClick();
			}
		});
		return view;
	}

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		try {
			activityCallback = (AddItemListener) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException(activity.toString() +
					" must implement AddItemListener");
		}
	}

}

This Fragment needs to send the new item to the ListView on the right and it does so via the MainActivity in order to keep the Fragments independent of each other. As before, we do this by defining an interface (line 16) which MainActivity must implement. In AddItemFragment’s onAttach() method, we test that the calling Activity implements the interface and store a reference to the Activity for future use.

In onCreateView() we inflate the layout and add event handlers to the two Buttons. The addItemButton handler retrieves the entered text from the EditText control and constructs a ListItem object. ListItem is as follows:

package com.example.ex05listview;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;

public class ListItem {
	private String dateAdded;
	private String message;

	public ListItem(String message)
	{
		this.setMessage(message);
		SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMM yyyy HH:mm:ss");
		dateFormat.setTimeZone(TimeZone.getTimeZone("Europe/London"));
		Calendar cal = Calendar.getInstance();
		setDateAdded(dateFormat.format(cal.getTime()));
	}

	String getDateAdded() {
		return dateAdded;
	}

	void setDateAdded(String dateAdded) {
		this.dateAdded = dateAdded;
	}

	String getMessage() {
		return message;
	}

	void setMessage(String message) {
		this.message = message;
	}
}

The constructor uses Java’s SimpleDateFormat and Calendar classes to get the current date and time and format it into a String (lines 15 to 18).

Back in AddItemFragment, we then send newItem to MainActivity (line 32). MainActivity just passes the ListItem along to ItemListFragment. Here’s the code for MainActivity:

package com.example.ex05listview;

import com.example.ex05listview.AddItemFragment.AddItemListener;

import android.os.Bundle;
import android.app.Activity;

public class MainActivity extends Activity
implements AddItemListener {
	ItemListFragment itemListFragment;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		itemListFragment = (ItemListFragment) getFragmentManager().findFragmentById(R.id.itemListFragment);
	}

	@Override
	public void onAddItemClick(ListItem item) {
		itemListFragment.addItem(item);
	}

	@Override
	public void onClearListClick() {
		itemListFragment.clearList();
	}
}

We’ll get to ItemListFragment in a minute. First, we add the event handler for clearListButton in AddItemFragment (line 37) which calls onClearListClick() in MainActivity, which again just passes this along to ItemListFragment.

To build the ItemListFragment, we create a new XML file in res–>layout, but all we need to do is set the initial layout to a ListView, with an ID of “@+id/list”. Here’s the complete XML file:

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</ListView>

All lines except the android:id should be created automatically in Eclipse. Here’s ItemListFragment, the Java class that manages the list fragment:

package com.example.ex05listview;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class ItemListFragment extends Fragment {
	ItemListAdapter adapter;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		adapter = new ItemListAdapter(getActivity());
		adapter.addItem(new ListItem("Test item"));
		View view = inflater.inflate(R.layout.list_fragment, container, false);
		ListView listView = (ListView) view.findViewById(R.id.list);
		listView.setAdapter(adapter);
		listView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View item, int position,
					long id) {
				TextView itemText = (TextView) item.findViewById(R.id.messageItem);
				Toast.makeText(getActivity(), itemText.getText().toString(),
						Toast.LENGTH_SHORT).show();
			}
		});
		return view;
	}

	public void addItem(ListItem item)
	{
		adapter.addItem(item);
	}

	public void clearList()
	{
		adapter.clearItems();
	}
}

On line 20, we create an ItemListAdapter. A list adapter is a class that manages the data behind a list. There are several pre-defined adapter classes, but it’s easy enough to write a custom one, so here’s ItemListAdapter:

package com.example.ex05listview;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class ItemListAdapter extends BaseAdapter {
	List<ListItem> itemList = new ArrayList<ListItem>();
	Context context;

	public ItemListAdapter(Context c) {
		context = c;
	}

	@Override
	public int getCount() {
		return itemList.size();
	}

	@Override
	public Object getItem(int position) {
		return itemList.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View arg1, ViewGroup parent) {
		LayoutInflater inflater = (LayoutInflater) context.getSystemService(
				Context.LAYOUT_INFLATER_SERVICE);
		View itemView = inflater.inflate(R.layout.list_item, parent, false);
		TextView dateText = (TextView)itemView.findViewById(R.id.dateTimeAdded);
		TextView message = (TextView)itemView.findViewById(R.id.messageItem);
		dateText.setText(itemList.get(position).getDateAdded());
		message.setText(itemList.get(position).getMessage());
		return itemView;
	}

	public void addItem(ListItem item)
	{
		itemList.add(item);
		notifyDataSetChanged();
	}

	public void clearItems() {
		itemList.clear();
		notifyDataSetChanged();
	}
}

We’ve extended BaseAdapter, which is a built-in Android abstract class containing four methods we must implement which we’ll get to in a minute.

The adapter must manage the data that is displayed in the ListView as well as provide the View object for each individual element in the list. Here, we’ve stored the data in a generic List<ListItem> (line 14), though in a real world application, we’d use a more permanent location for the data. In this app, the data must be entered from scratch every time the app is run.

To add an item to the list, we use addItem() (line 48). After the item is added to the itemList object, we must call notifyDataSetChanged() to update the ListView display on screen. Similarly, to clear the list, we use clearItems() (line 54).

The three methods on lines 22 to 34 just implement methods defined in the abstract base class and should be self-explanatory. (getItemId() returns an ID number for a list item; it’s up to us how we define this ID, so we’ve just taken it to be the position of the item in the list.)

The main work in the adapter is done in creating the View (line 37). As usual, we use a LayoutInflater to inflate the layout from its XML file (which just defines two TextViews, one of the date and one for the message). We need a ‘context’ to get the inflater, so if you refer back to line 20 in the code for ItemListFragment above, you’ll see we pass in the Activity that contains the Fragment so it’s used as the context in the adapter.

Once we’ve created the View, we need to set the values of its two TextViews which we do by retrieving the data from itemList.

Finally, back in ItemListFragment (line 25) we add an event handler for a click on a list item. This pops up a Toast notification (a little black rectangle that appears for a couple of seconds on the display) containing the text of the item clicked.

Obviously there are a lot of other tweaks we could add to this program, but it should give you enough information to include a ListView in an app.

Advertisements

Android Fragments

One limitation of Android devices is that they can display only a single Activity at a time. This was due initially to the fact that Android was used for small screen devices such as mobile phones. With the advent of larger screen devices such as tablets, there is more space in which to display the interface. However, such devices still allow only a single Activity to be displayed at a time.

To get around this problem, starting with Android version 3 the Fragment was introduced. A Fragment is a sub-process that can be embedded within an Activity, and a single Activity can have several Fragments running at a time. A Fragment can (but need not) have a visual interface which is created in much the same way that an Activity’s interface is created.

To illustrate this, we’ll create an app that displays the two interfaces we used in the previous examples on a single screen. Start as usual by creating a new Android project with a single blank Activity in Eclipse. Eclipse doesn’t have an “Add fragment” function, but it’s still quite easy to create one. The layout of a Fragment, like that of an Activity, is defined in an XML file, so right click on the res–>layout folder in Package Explorer and select New–>Android XML file. We’ll start with the first screen that displays the Get text button we used earlier. Call this XML file get_text_fragment.xml and select RelativeLayout as its Root Element. After it’s created, open it in the Graphical Layout and add a Button and two TextViews, just as we did earlier.

Do the same for the other screen, calling the file enter_text_fragment.xml and adding a TextView, EditText and a Button.

Next we need to create Java classes to represent the Fragments and handle their events. In the src–>growe.ex04fragments (or whatever you’ve called your package) folder, right click on the folder and select New–>Class. To represent the get_text_fragment, create a class called GetTextFragment. In the Superclass box, type Fragment then Ctrl+(space), then select the Fragment class in the android.app package. (The other Fragment class in the android.support.v4.app can be used if you need your app to run on older (pre version 3) versions of Android.)

This will generate the skeleton code for your class. At this stage, we need to override only the onCreateView() method, which is most easily done in Eclipse by putting the cursor inside the class and pressing Ctrl+(space) to get a list of methods you can override. Select onCreateView() and you’ll get the code for it.

The creation of a view from an XML file requires inflating the view using a LayoutInflater. You’ll see that this is one of the arguments in onCreateView(). To create the view, delete the existing code inside this method and insert the following, so your code looks like this:

package growe.ex04fragments;

import android.os.Bundle;
import android.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class GetTextFragment extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.get_text_fragment, container, false);
		return view;
	}
}

The inflate method looks up the get_text_fragment.xml file and creates a Java version of the layout.

Do the same for enter_text_fragment.xml by creating a class called EnterTextFragment which looks like this:

package growe.ex04fragments;

import android.os.Bundle;
import android.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class EnterTextFragment extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.enter_text_fragment, container, false);
		Button sendTextButton = (Button) view.findViewById(R.id.sendTextButton);
		sendTextButton.setEnabled(false);
		return view;
	}
}

We’ve added a couple of lines to disable the Send text button when it is first displayed. The idea is that clicking on Get text enables this button and allows the user to send some text.

Now we need to embed these Fragments in the MainActivity and get them displayed on screen. First, we need to let the MainActivity’s layout know about the Fragments. This is done in activity_main.xml by adding in a couple of <fragment> tags. This can be done in Eclipse’s Graphical Layout.

Open activity_main.xml in Graphical Layout and open the Layouts menu in the Palette box on the left. Drag a Fragment onto the screen to where you want it. This will open a dialog in which you choose the Fragment class you want, so select GetTextFragment for the first Fragment. This will display a placeholder with instructions to pick the preview layout. To do this, right click on the placeholder and select Fragment Layout –>get_text_fragment (or open the Choose Layout dialog and choose it there). The layout components should then become visible.

Do the same to add enter_text_fragment to the layout. You should now be able to run the program in your emulator and see the combined layout.

Event handling in Fragments

Now the fun begins. We need to connect a button press in GetTextFragment to EnterTextFragment, and then send the entered text back to GetTextFragment when the Enter text button is pressed.  We could do this by simply relying on the IDs generated in the R.java file for the various view objects, but that is very bad design, for the following reason.

One of the advantages of using Fragments is that they encapsulate units of functionality, so they can be plugged in to apps wherever they are needed. If we wrote a Fragment so that it communicated directly with another Fragment, then both Fragments would always have to be present in any given app. To avoid this, we need to ensure that the only inter-Fragment communication occurs via the Activity that contains them. Doing this requires a fair bit of code, but it’s worth it to preserve modularity (or so I’m told :-)).

First, let’s see how to communicate the Get text button click event to MainActivity. Here’s the modified GetTextFragment class:

package growe.ex04fragments;

import android.os.Bundle;
import android.app.Activity;
import android.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

public class GetTextFragment extends Fragment {

	GetTextListener activityCallback;
	View getTextView;

	public interface GetTextListener
	{
		public void onGetTextButtonPressed();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		getTextView = inflater.inflate(R.layout.get_text_fragment, container, false);
		Button getTextButton = (Button) getTextView.findViewById(R.id.getTextButton);
		getTextButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				onClickGetText(v);
			}
		});
		return getTextView;
	}

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		try {
			activityCallback = (GetTextListener) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException(activity.toString() +
					" must implement GetTextListener");
		}
	}

	public void onClickGetText(View view) {
		activityCallback.onGetTextButtonPressed();
	}

	public void setText(String text)
	{
		TextView displayed = (TextView) getTextView.findViewById(R.id.displayedText);
		displayed.setText(text);
	}
}

On lines 26 to 33 we’ve added an event handler for getTextButton clicks. We have to do it this way rather than by simply adding an ‘On Click’ handler to the button’s properties in the Eclipse Graphical Layout screen, since the latter adds the event handler to the containing Activity class rather than the Fragment class. If this code looks a bit complicated, don’t worry, as it’s always pretty much the same so you can just copy and paste it.

Ultimately, clicking getTextButton calls onClickGetText() on line 48. To see what this does, we have to back up a bit and see how the Activity communicates with Fragments it contains.

When the Activity starts up and loads the Fragment view from the XML file, it calls the onAttach() method of the Fragment class. We need to override onAttach() to provide the connection, if we want to call a method in the Activity when an event occurs in the Fragment.

We do this by defining an interface called GetTextListener on line 17. This interface specifies a method that the Activity must implement, so that it can be called in response to the button click event. So how does this all fit together?

When the Fragment is loaded, the Activity calls onAttach(), passing a reference to itself in as an argument. We attempt to save this reference on line 41 by casting it to GetTextListener. If this succeeds, this means that the Activity does implement this interface and all is well. If it fails, we throw an exception which stops the app.

Now that we have a reference to the parent Activity, we can use it on line 49 to call the onGetTextButtonPressed() method in that Activity. It is then the Activity’s responsibility to communicate with the EnterTextFragment to enable its Send text button.

To see how this works, here’s the modified MainActivity class:

package growe.ex04fragments;

import growe.ex04fragments.EnterTextFragment.EnterTextListener;
import growe.ex04fragments.GetTextFragment.GetTextListener;
import android.os.Bundle;
import android.app.Activity;

public class MainActivity extends Activity
implements GetTextListener, EnterTextListener
{

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	@Override
	public void onGetTextButtonPressed() {
		EnterTextFragment enterTextFragment =
				(EnterTextFragment) getFragmentManager().
				findFragmentById(R.id.enter_text_fragment);
		enterTextFragment.enableSendTextButton();
	}

	@Override
	public void enterTextButtonPressed() {
		EnterTextFragment enterTextFragment =
				(EnterTextFragment) getFragmentManager().
				findFragmentById(R.id.enter_text_fragment);
		GetTextFragment getTextFragment =
				(GetTextFragment) getFragmentManager().
				findFragmentById(R.id.get_text_fragment);
		getTextFragment.setText(enterTextFragment.getEnteredText());
	}

}

On line 9, we implement GetTextListener (and an interface for the other fragment, but we’ll get to that in a minute), and on line 19 we implement the onGetTextButtonPressed() method. Here, we retrieve the EnterTextFragment object and call a method (which we’ll see in a minute) in that Fragment to enable its Send text button.

Now for the revised version of EnterTextFragment:

package growe.ex04fragments;

import android.os.Bundle;
import android.app.Activity;
import android.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;

public class EnterTextFragment extends Fragment {
	View enterTextView;
	EnterTextListener activityCallback;

	public interface EnterTextListener {
		public void enterTextButtonPressed();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		enterTextView = inflater.inflate(R.layout.enter_text_fragment, container, false);
		Button sendTextButton = (Button) enterTextView.findViewById(R.id.sendTextButton);
		sendTextButton.setEnabled(false);
		sendTextButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				sendTextButtonClicked(v);
			}
		});
		return enterTextView;
	}

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		try {
			activityCallback = (EnterTextListener) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException(activity.toString() +
					" must implement EnterTextListener");
		}
	}

	public void enableSendTextButton()
	{
		Button sendTextButton = (Button) enterTextView.findViewById(R.id.sendTextButton);
		sendTextButton.setEnabled(true);
	}

	public void sendTextButtonClicked(View view)
	{
		Button sendTextButton = (Button) enterTextView.findViewById(R.id.sendTextButton);
		sendTextButton.setEnabled(false);
		activityCallback.enterTextButtonPressed();
	}

	public String getEnteredText()
	{
		EditText enteredText = (EditText) enterTextView.findViewById(R.id.enteredText);
		return enteredText.getText().toString();
	}
}

On line 47 you see the enableSendTextButton() method that is called from the Activity. Thus the event is generated in GetTextFragment which calls a method in MainActivity which in turn calls a method in EnterTextFragment. The two Fragments don’t communicate with each other directly.

To finish things off, the user enters some text in EnterTextFragment and then clicks the Send text button to send the text back to GetTextFragment. The process is much the same as the one we’ve just described, so we’ll go through it quickly.

In EnterTextFragment, we attach an event handler for the Send text button on lines 26 to 32. EnterTextFragment defines its own interface called EnterTextListener, which MainActivity must also implement. When EnterTextFragment is loaded, MainActivity is connected to it the same way (line 37), so when Send text is clicked, sendTextButtonClicked() on line 53 is called. We disable the Send text button, then call enterTextButtonPressed() in MainActivity.

If you go back to MainActivity’s code above, this method is on line 27. We need to retrieve the entered text from EnterTextFragment and send it to GetTextFragment, so we need references to both Fragments. On line 34 we call getEnteredText() from EnterTextFragment (line 60 in EnterTextFragment’s code) and pass the retrieved String to GetTextFragment’s setText() method (line 52 in GetTextFragment’s code above). Thus again, the two Fragments do not communicate directly.

This example, of course, is artificial; you’d never write an app that does something that simple in real life. But it does allow you to see how the mechanics of using Fragments work.

A more realistic example would change the layout depending on whether the device was viewed in portrait or landscape mode. We might display both fragments side by side in landscape, but only one Fragment at a time in portrait. More on that in another post.

Android: implicit intents

We’ve seen how to use an explicit intent to start a second Activity from within an existing Activity by giving the name of the second Activity’s class explicitly. It is also possible to start another Activity without naming it. The rationale behind this idea is that one or more activities might exist on a given device that can perform the required action. For example, if we want to view a web page, there could be several different browsers which can do this, and the user might like to select different ones for different pages. We can use an implicit intent to do this.

To use an implicit intent, an Activity that can handle a given type of request must contain an intent-filter that specifies the type(s) of actions that Activity can perform. The intent-filter can be specified in the Java code, but it’s more usual to include it in the AndroidManifest.xml file for the app. There are many predefined action types for an intent-filter, but to keep things local, we’ll show an example in which we define our own action type which is used by two alternative Activities within the same app.

The example app we’ll use is just a copy of the explicit intent app we used before with another Activity called OtherTextActivity added to it. The layout of OtherTextActivity is the same as that of GetTextActivity, so the user can enter some text and press a button to send the text back to StartActivity.

Before we look at the Java code for creating an implicit Intent, we need to define the intent-filters for  the Activities. Up to now, we’ve let Eclipse generate the AndroidManifest.xml file and haven’t altered it. To insert an intent-filter we do need to edit it. This can be done in Eclipse either by using the GUI in the Application tab or by directly writing the XML code. Let’s see how to use the Application editor to add it.

First, find the Activity (we’ll select GetTextActivity first) to which you want to add the intent-filter in the box at the lower left. Click on it and then click on Add… to get the dialog in which you can double-click on Intent filter. Now click on the new Intent filter, then click Add… again. We’ll need to add an action and a category to the intent-filter. Double-click on Action first, and you’ll see a Name field with a drop-down menu appear. If you open this menu, you’ll see a list of all the built-in action names you can give this intent-filter. However, we’re going to create our own custom action, so just enter GET_TEXT_ACTION in the Name box.

[As a side note, we cannot use a string resource to specify an action’s name. This is a bit of a pain, since it means we need to hard-code these strings both in the XML and in the Java code.]

Now add a category to the intent-filter and this time select android.intent.category.DEFAULT from the drop-down list. Have a look at the XML code file to see the code that has been added. You should see something like this:

        <activity
            android:name="com.example.ex03implicitintent.GetTextActivity"
            android:label="@string/title_activity_get_text" >
            <intent-filter>
                <action android:name="GET_TEXT_ACTION"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

Now repeat the process for OtherTextActivity. That completes the definition of the intent-filters. Now over to the Java code. We won’t need to change the code in either GetTextActivity or OtherTextActivity, but we do need to change how the Intent defined in StartActivity is created. We do this by changing the event handler for the getTextButton as follows:

	public void onClickGetText(View view) {
		Intent getTextIntent = new Intent();
		getTextIntent.setAction("GET_TEXT_ACTION");
		List<ResolveInfo> activities = getPackageManager().
				queryIntentActivities(getTextIntent, PackageManager.MATCH_DEFAULT_ONLY);
		boolean isIntentSafe = activities.size() > 0;
		if (isIntentSafe)
		{
			startActivityForResult(getTextIntent, GET_TEXT_ACTIVITY);
		}
	}

We create the Intent with an empty constructor. Then we set the action that the Activity to which this Intent is to be sent must support. Next, we retrieve a List of Activities that support the action requested in getTextIntent. The second argument in queryIntentActivities() says we’re looking only for Activities that have a DEFAULT category.

If there are any Activities that support the requested action, the size of this list will be greater than zero, so we test for that and then call startActivityForResult() only if there are some eligible Activities. If there is only one such Activity, it is started immediately. If there are more than one (as is the case here), Android will display a chooser dialog asking the user to select which Activity should be used.

One cautionary note here: using an implicit intent to start an Activity that returns data is fine, but if you’re doing this with Activities that you didn’t write, beware that often different Activities that support a given action might return different types of data (or none at all). In such a case, it’s better to use an explicit intent and start up an Activity whose behaviour you know, so you can handle the returned data properly.

Android: explicit intents

The Intent class is used in Android programs to communicate between various types of processes. We’ll consider the case where an Intent is used to start one Activity from within another Activity, and another Intent is used to send data back from the second Activity to the first.

Create a new project in Eclipse as described in our previous post. Add a main Activity called StartActivity which is displayed when the app starts. The layout of this Activity consists of:

  • a Button with ID getTextButton that has the caption “Get text”
  • a TextView with the text “You entered:”
  • another TextView, with ID enteredText, initially blank

When the button is pressed, a second Activity, called GetTextActivity, will start that will have the following layout:

  • a horizontal LinearLayout (we’ll get to these in a later post) which contains:
    • a TextView with the text “Enter your text:”
    • an EditText, with ID userText, into which the user can type some text
  • a Button with ID sendTextButton and caption “Send text”

All of this can be set up using Eclipse’s graphical UI editor, which will create the corresponding code in the various XML files automatically.

The idea is that the user presses the “Get text” button to show the second Activity, then types some text into the EditText box and presses the “Send text” button. This returns the app to the first Activity, which displays the entered text in the enteredText TextView.

In order to do this, we need to use one Intent to start GetTextActivity from within StartActivity and another Intent to send the entered text back from GetTextActivity to StartActivity.

Here’s the code for StartActivity:

package com.example.ex02explicitintent;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.widget.TextView;

public class StartActivity extends Activity {

	static final int GET_TEXT_ACTIVITY = 0;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_start);
	}

	public void onClickGetText(View view) {
		Intent getTextIntent = new Intent(getBaseContext(), GetTextActivity.class);
		startActivityForResult(getTextIntent, GET_TEXT_ACTIVITY);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode != RESULT_OK)
		{
			return;
		}
		if (requestCode == GET_TEXT_ACTIVITY)
		{
			String userText = data.getStringExtra(getString(R.string.userTextTag));
			TextView enteredText = (TextView) findViewById(R.id.enteredTextView);
			enteredText.setText(userText);
		}
	}
}

The onClickGetText() (lines 19-22) method is the event handler for getTextButton. It illustrates how to create an explicit Intent, which is an Intent that creates a specifically named Activity. (There are also implicit Intents). Here we want a GetTextActivity to start in response to the button press, so we name this class explicitly in the Intent constructor.

We then start the Activity by calling startActivityForResult(). The ‘ForResult’ in the method name means that we expect the Activity to return a result after it finishes running. If we just wanted to start an Activity with no return data, we can call startActivity().

The startActivityForResult() method takes the Intent as its first argument, and an int label (defined on line 11) as its second argument. We need a label because if we start more than one Activity that will return data, they all call the same method onActivityResult() when they return, so we need to tag each Activity so we know which one is returning the data. (OK, since we’re creating only one Activity here, technically we don’t need a tag, but in the more general case we will so it’s a good idea to get into the habit of adding the tag.)

Before we see how to handle the returned result, we need to look at the other Activity to see how it sends back its data. Here’s the code for GetTextActivity:

package com.example.ex02explicitintent;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.widget.EditText;

public class GetTextActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_get_text);
	}

	public void onClickSendText(View view) {
		EditText userEditText = (EditText)findViewById(R.id.userText);
		String userText = userEditText.getText().toString();
		Intent userIntent = new Intent();
		userIntent.putExtra(getString(R.string.userTextTag), userText);
		setResult(RESULT_OK, userIntent);
		finish();
	}
}

This Activity contains only the event handler for the sendText button. We retrieve the EditText control by using its ID and extract the text from it (lines 18-19). Then we create a new Intent. This time, we’re not starting a new Activity, so the Intent doesn’t have an Activity specified in its constructor. What we do want to do is send back userText to StartActivity. We can attach data to an Intent by adding Extras to it. Each Extra consists of a key (which is a String) and a corresponding value, which here is just userText. Note that we’ve defined the key as a string resource (by adding it to the strings.xml file) and retrieved it on line 21 using getString() which looks up a string using its ID. We do it this way since we’ll need to use the same key back in StartActivity to extract the Extra from the Intent.

After adding userText to the Intent, we use setResult() on line 22 to attach the Intent to the GetTextActivity. The first argument to setResult() is a result code to indicate the status of GetTextActivity when it finishes. This result code is also sent back to StartActivity and can be checked to determine what to do with the returned Intent.

Finally, we call finish() to shut down GetTextActivity and send the Intent back to StartActivity.

Returning to the code above for StartActivity, the onActivityResult() method is called when GetTextActivity finishes. The arguments in this method are:

  • requestCode: the tag that was attached to the Activity that has just finished
  • resultCode: the result code that was set in the Activity that has just finished
  • data: the Intent returned by the other Activity

On line 26, we check the resultCode to ensure that GetTextActivity finished properly. Then we check the requestCode to ensure that it really is GetTextActivity that is calling onActivityResult(). If so, then we extract the userText from the Intent, again using the string resource for the tag. Then we retrieve the enteredText TextView control and set its text to userText.

Android programming: a simple activity

To get started programming an Android application, I’m assuming you have the Eclipse IDE with Android Developer Tools (ADT) installed. You can get this package here. To test your apps, you’ll need to set up one or more Android emulators, which you can do using the Android Virtual Device Manager from within Eclipse (there should be an icon on the default toolbar, or you can get it from the Window menu).

You may find that the emulator takes ages (well, several minutes) to start up. If so, and if you have the right kind of Intel processor, you should consider installing the Intel Hardware Acceleration Execution Manager (HAXM). Once installed (assuming your system supports it), select the Intel Atom option for the CPU/ABI in the Android Virtual Device Manager when setting up your emulator. This cuts the startup time down to a few seconds.

Assuming you’ve got everything installed, let’s create an Android app. In Eclipse, click the ‘New’ icon and select Android–>Android Application Project, then Next. Enter the app, project and package names in the next dialog, then click ‘Next’ again. In the Configure Project dialog, we’ll start with the most basic app, so uncheck the ‘Create custom launcher icon’ and ‘Create activity’ boxes, then click Finish. Eclipse will now create a skeleton project.

For example, suppose we want to create a simply app that displays a button that toggles its text between ‘Off’ and ‘On’ when you click it. We’ll call the package growe.ex01onoff.

Activities

You won’t be able to run this project, since there’s no Java source code yet, so the first thing we need to do is add some. An Android app is built using one or more Activity objects, so we’ll add an Activity to our project. To do this, right click on the package in the Package Explorer and select ‘New…’, then pick Android–>Android Activity and Next. Then select ‘Blank activity’ and Next. In the Blank Activity dialog, give the activity a name such as OnOffActivity and accept the generated layout name and title. Click the Launcher Activity box since we want this activity to be launched when the app starts.

You can click Finish here, since clicking Next just gives you a Preview dialog where you can see the pending changes to the various files in your project that adding this activity will make.

You should now find that Eclipse has created a Java file called OnOffActivity.java, with the following code:

package growe.ex01onoff;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class OnOffActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_on_off);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.on_off, menu);
		return true;
	}

}

The onCreateOptionsMenu() method (not surprisingly) creates a menu, but we don’t want one in this simple app so you can safely comment out this code for now.

The onCreate() method is called when this Activity starts, but since an app can have several Activities, how does it know that we want this one to be the startup Activity? The answer is in the AndroidManifest.xml file, which contains the lines:

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="growe.ex01onoff.OnOffActivity"
            android:label="@string/title_activity_on_off" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

Within the activity tag, we see the name of the OnOffActivity and an intent-filter. The action of  android.intent.action.MAIN indicates that it is the entry point of the app. (We’ll worry about intents later.)

Resources

Going back to the Java code, the call to setContentView() draws the user interface. The argument of this call illustrates the way apps refer to resources that are defined elsewhere, usually in XML files. Every Android app creates a Java class called R. The source code for R can be found in the gen folder and, since it’s generated by Eclipse, it shouldn’t be edited since any changes will just be overwritten. Within the R class are defined other classes that contain int codes referring to the resources that are defined in the various XML files within the res folder. Within R, you’ll find a class called layout which contains an int named activity_on_off. If you look within the res folder, you’ll find a layout folder which contains the file activity_on_off.xml. This file contains the definitions of the user interface elements that are to be drawn on the screen when this layout is used. The file generated by Eclipse when an activity is created contains a single TextView which displays the text ‘Hello world!’.

We want the interface to display a button instead. We could do this by editing the XML file directly, but Eclipse has a graphical editor which allows interfaces to built visually. To do this, open the activity_on_off.xml file and click on the Graphical Layout tab at the bottom. Click on the TextView and delete it, then select a button from the Form Widgets menu on the left and drag it onto the window. You’ll notice that a Properties box on the right displays all the properties of this button that can be set. We want the button to start off displaying the caption ‘Off’. One way of doing this is just to write Off in the Text property, but there is a more general way of doing this using a String resource. 

Why should we bother with this more general way of defining strings? A major reason is that it makes apps easier to internationalize by writing strings in different languages. We can write a set of string resources for each language we want to support and then just load in the correct set of strings when we change languages. This works only if each string is given a resource name rather than hard coded.

To add a new String resource, open the res–>values–>strings.xml file. If you look at the XML code first, you’ll see several strings already defined. To add a new String, go to the Resources tab at the bottom, click the Add… button and then double-click String in the dialog. Give the resource a name like offText and a value of Off. While you’re at it, add another String resource called onText with a value of On, which we’ll use later. Make sure to save strings.xml before proceeding.

Now go back to activity_on_off.xml and select the button again. In the properties box click the … button for the Text property and you should see a list of all the string resources defined in strings.xml. Select offText, and the button’s caption should now be Off.

At this point you can run the app in your emulator and you should see the white screen with the Off button on it. Pressing the button has no effect, of course, because we haven’t added an event handler to the button yet.

Event handlers

Unlike many other IDEs, it seems that Eclipse doesn’t provide any shortcuts to adding event handlers to components, so the only option is just to write in the code by hand.

There are two ways of attaching an event handler to a button. The easiest is to find the On Click property of the button (listed in the View section in the properties box) and provide the name of a method that will handle the click event. This method must be placed in the Activity class that contains the button in its layout. If we specify the event handler as toggleOnOff, then we can modify the OnOffActivity class as follows:

package growe.ex01onoff;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.app.Activity;

public class OnOffActivity extends Activity {
	boolean on = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_on_off);
	}

	public void toggleOnOff(View view) {
		Button onOffButton = (Button) view;
		onOffButton.setText(on ? R.string.offText : R.string.onText);
		on = !on;
	}
}

The event handler must always have the signature shown. It must be public, void, and have a single argument of class View (which is the View that triggered the event; in this case, the button). Here, we’ve defined a boolean variable on which stores the state of the button and we set the text of the button according to the state of this variable, then toggle the variable.

The second way of attaching an event handler to a button is done entirely within the Activity class’s onCreate() method:

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_on_off);

		Button onOffButton = (Button) findViewById(R.id.onOffButton);
		onOffButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View view) {
				Button button = (Button) view;
				button.setText(on ? R.string.offText : R.string.onText);
				on = !on;
			}
		});
	}

First, we need to find the button, which we do using the findViewById() method on line 6. Each UI component is assigned an ID number in the R class, and this method retrieves a reference to the component using this ID. Next, we attach an OnClickListener to the button using setOnClickListener(). Within this listener, we override the onClick() method, which becomes the event handler, so it contains the same code as we had earlier.

Antlr 4 with C# and Visual Studio 2012

It’s been more than a year since I posted anything to Programming Pages, so I figure I should rectify that (been busy mainly with my alter-ego, Physics Pages).

Recently, I had another look at the parsing package Antlr and discovered that a whole new version has come out (Antlr 4), along with a book The Definitive Antlr 4 Reference, written by Antlr’s author, Terence Parr. However, as with Antlr 3, the book is written exclusively in Java, so a fair bit of detective work is needed to discover how to use it with C# in Visual Studio. The code required both to specify the lexer and parser, and to write the supporting C#, has pretty well completely changed from Antlr 3, so a fresh tutorial is needed.

Installation in Visual Studio

Support for Antlr4 exists for Visual Studio 2012 (and presumably 2010, although I no longer have this installed so I can’t test it), but not, it seems, for Visual Studio 2013. To get the files you need, visit the Antlr download page and get the ‘ANTLR 4 C#.dll’ zip file. Next, click on the ‘C# releases’ link, and from the page that loads, scroll down to ‘Visual Studio 2010 Extensions’ and click on the ‘ANTLR Language Support’ link, then ‘Download’ the Visual Studio plugin from that page, then install it, making sure you’ve selected the correct version of Visual Studio in the dialog.

To incorporate Antlr 4 into a VS project, create a new project in VS. In the project directory, create a folder named Reference and within the Reference folder create another folder called Antlr4. Unzip the entire contents of the ‘ANTLR 4 C#.dll’ zip file into the Antlr4 folder. You’ll need to do this for each project you create.

Then, in Solution Explorer, right-click on the project and select ‘Unload project’. Then right click on the project name (it’ll say ‘unavailable’ after it, but that’s OK) and select ‘Edit <Your project name>.csproj. Scroll to near the end of the file where you should find the line:

  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

Insert the following lines directly after this line:

  <PropertyGroup>
    <!-- Folder containing Antlr4BuildTasks.dll -->
    <Antlr4BuildTaskPath>$(ProjectDir)..\Reference\Antlr4</Antlr4BuildTaskPath>
    <!-- Path to the ANTLR Tool itself. -->
    <Antlr4ToolPath>$(ProjectDir)..\Reference\Antlr4\antlr4-csharp-4.0.1-SNAPSHOT-complete.jar</Antlr4ToolPath>
  </PropertyGroup>
  <Import Project="$(ProjectDir)..\Reference\Antlr4\Antlr4.targets" />

Then right-click on the project name and select ‘Reload project’.

Finally, you’ll need to add a reference to the Antlr4 runtime in your project to provide access to the API. Right-click on References and select the correct version of the runtime dll from the Antlr4 folder you created above. The version should match the version of .NET that you’re using in your project, so if you’re using .NET 4.5, load the file ‘Antlr4.Runtime.v4.5.dll’. Now your project should be all set.

One final note: you’ll need Java to be installed in order to run Antlr4! This is true even if you’re coding in C#, since Antlr4 is written in Java and calls it to generate the code for your lexer and parser.

Writing an Antlr 4 grammar

You should now be in a position to start work on the actual code. If you installed the VS extension above, you can add an Antlr4 grammar to your project by right-clicking on the project name and selecting Add –> New Item. In the dialog you should see 7 Antlr items; 3 of these are for Antlr 4 files, with the other 4 being for Antlr 3. Since we’ll be working with both a lexer and a parser, select ‘ANTLR 4 Combined Grammar’, change the name of the file to whatever you like, and click ‘Add’.

As an illustration, we’ll generate a grammar for the good old four-function calculator, so we’ll call the project Calculator. In Solution Explorer you should find a file called Calculator.g4; this is where you write your parser and lexer rules.  The initial code in this file looks like this:

grammar Calculator;

@parser::members
{
	protected const int EOF = Eof;
}

@lexer::members
{
	protected const int EOF = Eof;
	protected const int HIDDEN = Hidden;
}

/*
 * Parser Rules
 */

compileUnit
	:	EOF
	;

/*
 * Lexer Rules
 */

WS
	:	' ' -> channel(HIDDEN)
	;

Don’t worry about the stuff up to line 12. What we’re interested in are the parser and lexer rules. The syntax for these has changed significantly from Antlr 3, to the extent that any grammar files you may have written for the earlier version very probably won’t work in Antlr 4.  However, the new syntax is much closer to the more standard ways of representing these rules in other systems like lex and yacc (if you’ve never heard of these, don’t worry; we won’t be using them).

Here’s the grammar file as modified for our calculator:

grammar Calculator;

@parser::members
{
	protected const int EOF = Eof;
}

@lexer::members
{
	protected const int EOF = Eof;
	protected const int HIDDEN = Hidden;
}

/*
 * Parser Rules
 */

prog: expr+ ;

expr : expr op=('*'|'/') expr	# MulDiv
	 | expr op=('+'|'-') expr	# AddSub
	 | INT					# int
	 | '(' expr ')'			# parens
	 ;

/*
 * Lexer Rules
 */
INT : [0-9]+;
MUL : '*';
DIV : '/';
ADD : '+';
SUB : '-';
WS
	:	(' ' | '\r' | '\n') -> channel(HIDDEN)
	;

First, look at the lexer rules. The INT token is defined using the usual regular expression for one or more digits. The four arithmetic operations are given labels that we’ll use later. Finally, we’ve modified the WS (whitespace) label so it includes blanks, returns and newlines. The ‘-> channel(HIDDEN)’ just tells the lexer to ignore whitespace.

Now look at the parser rules. The first rule is ‘prog’, which is defined as one or more ‘expr’s. The ‘expr’ is defined a single INT, or a single expr enclosed in parentheses, or two exprs separated by one of the four arithmetic operators.

Note that each line in the expr declaration has a label preceded by a # symbol at the end. These are not comments; rather they are tags that are used in writing the code that tells the parser what to do when each of these expressions is found.

This is where the biggest difference between Antlr 3 and Antlr 4 occurs: in Antlr 4, there is no code in the target language (C# here) written in the grammar file. All such code is moved elsewhere in the program. This makes the grammar file language-independent, so once you’ve written it you could drop it in to another project and use it support a Java application, or any other language for which Antlr 4 is defined.

Using the grammar in a C# program

So how exactly do you use the grammar to interpret an input string? Before we can use the lexer and parser, we need to write the code that should be run when each type of expression is parsed from the input. To do this, we need to write a C# class called a visitor. Antlr 4 has provided a base class for your visitor class, and it is named CalculatorBaseVisitor<Result>.  It is a generic class, and ‘Result’ is the data type that is returned by the various methods inside the class. Your job is to override some or all of the methods in the base class so that they run the code you want in response to each bit of parsed input.

In our case, we want the calculator to return an int for each expression it calculates, so create a new class called (say) CalculatorVisitor and make it inherit CalculatorBaseVisitor<int>. Your skeleton class looks like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Calculator
{
  class CalculatorVisitor : CalculatorBaseVisitor<int>
  {
  }
}

To see what methods you need to override, it’s easiest to use VS’s Intellisense. Within the class type the keywords ‘public override’ after which Intellisense should pop up with a list of methods you can override. Look at the methods that start with ‘Visit’. Among these you should find a method for each label you assigned in the ‘expr’ definition in the grammar file above. Thus you should have VisitInt, VisitParens, VisitMulDiv and VisitAddSub. These are the methods you need to override. The other Visit methods you can ignore, as the versions provided in the base class will work fine.

Here’s the complete class. We’ll discuss the code in a minute:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Calculator
{
  class CalculatorVisitor : CalculatorBaseVisitor<int>
  {
    public override int VisitInt(CalculatorParser.IntContext context)
    {
      return int.Parse(context.INT().GetText());
    }

    public override int VisitAddSub(CalculatorParser.AddSubContext context)
    {
      int left = Visit(context.expr(0));
      int right = Visit(context.expr(1));
      if (context.op.Type == CalculatorParser.ADD)
      {
        return left + right;
      }
      else
      {
        return left - right;
      }
    }

    public override int VisitMulDiv(CalculatorParser.MulDivContext context)
    {
      int left = Visit(context.expr(0));
      int right = Visit(context.expr(1));
      if (context.op.Type == CalculatorParser.MUL)
      {
        return left * right;
      }
      else
      {
        return left / right;
      }
    }

    public override int VisitParens(CalculatorParser.ParensContext context)
    {
      return Visit(context.expr());
    }
  }
}

First, notice that the argument of each method (called ‘context’) is different in each case, and corresponds to the tag used to define the method. Each ‘context’ object contains information required to evaluate it, and this content can be determined by how you defined the various expr lines in the grammar file above. (BTW, you may need to rebuild the project to get VS’s Intellisense to work here.)

Take the VisitInt() method first. This is called when the object being parsed is a single integer, so what you want to return is the value of this integer. We can get this by calling the INT() method of the context object, and then GetText() from that. This returns the integer as a string, so we need to use int.Parse to convert it to an int.

Now look at the VisitParens() method at the bottom. Here, the contents of the parentheses could be an expr of arbitrary complexity, but we want to return whatever that expr evaluates to as the result. This is what the inherited Visit() method does: it takes an expr as an argument and calls the correct method depending on the type of the expr. The expr() method being called from the ‘context’ returns this expr (which will have a tag attached to it to say whether it’s an Int, or an AddSub, or whatever) and Visit will call the correct method to evaluate this expr.

Finally, VisitAddSub and VisitMulDiv work pretty much the same way. Both of these represent binary operators, so there are two subsidiary exprs to evaluate before the operator is applied. In each case, we evaluate the left and right operands by calling Visit(context.expr(0)) and Visit(context.expr(1)) respectively. Then we check which operator is in the ‘context’. Note that in the grammar file above we defined a parameter called ‘op’ as the operator. Also note that the labels we gave to the four arithmetic operators in the lexer rules show up as fields within the Calculator Parser class, so we can compare the Type of ‘op’ with these labels to find out which operator we’re dealing with. Once we know that, we can return the correct calculation.

At long last, we’re ready to look at the code that uses all this stuff. Here’s the Main() function:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Tree;

namespace Calculator
{
  class Program
  {
    static void Main(string[] args)
    {
      StreamReader inputStream = new StreamReader(Console.OpenStandardInput());
      AntlrInputStream input = new AntlrInputStream(inputStream.ReadToEnd());
      CalculatorLexer lexer = new CalculatorLexer(input);
      CommonTokenStream tokens = new CommonTokenStream(lexer);
      CalculatorParser parser = new CalculatorParser(tokens);
      IParseTree tree = parser.prog();
      Console.WriteLine(tree.ToStringTree(parser));
      CalculatorVisitor visitor = new CalculatorVisitor();
      Console.WriteLine(visitor.Visit(tree));
    }
  }
}

Note the ‘using’ statements at the top, required to access Antlr4.

We create a StreamReader from the console on line 17 so we can type in our expressions. Then on line 18 we pass the string read from the stream (via inputStream.ReadToEnd()) to an AntlrInputStream.

Important note: AntlrInputStream is supposed to accept a raw Stream object for its input, but I couldn’t get this to work. The program just hung up when attempting to read from the Stream directly. It seems this is a bug in Antlr  4 so may be fixed in a future release.

The lexer is then created with the AntlrInputStream, the tokens from the lexer are saved in a CommonTokenStream, which is then passed to the parser. The parser is then run by calling parser.prog(), which calls the ‘prog’ rule (defined in the grammar file above) that initializes the program. The output from the parser is saved in an IParseTree, which is then passed to a CalculatorVisitor to do the evaluations. Finally, the result of the parse + evaluation is printed.

To run the program, type one or more expressions in the console (you can separate them by newlines or blanks). When you’re done, type control-Z on a line by itself and the output from the program should then be displayed.

Inheritance in JavaScript

In the last post, we saw how to implement class-like objects in JavaScript, despite the language’s lack of actual class data types. The solution used closure to create private fields, which can be either data or functions. Once you’ve got classes up and running, it’s natural to ask if it’s possible to simulate some of the other OOP concepts in JavaScript. Probably the most important of these is inheritance.

After poking about a lot and failing to find a convincing implementation of inheritance, I chanced upon a rather concise post by Steffen Rusitschka. He offers two ways of implementing inheritance, but although his code is fairly easy to use, he really doesn’t explain how it works, and that’s far from obvious. I’ll try to provide a bit of an explanation here.

I’ll look only at the closure-based version, since it follows on nicely from my last post.

At the heart of the technique is this helper code:

(function(){
  CClass = function(){};
  CClass.create = function(myConstructor) {
    var k = this;
    c = function() {
      this._super = k;
      var pubs = myConstructor.apply(this, arguments), self = this;
      for (key in pubs) (function(fn, sfn) {
        self[key] = typeof fn != "function" || typeof sfn != "function" ? fn :
          function() { this._super = sfn; return fn.apply(this, arguments); };
      })(pubs[key], self[key]);
    };
    c.prototype = new this;
    c.prototype.constructor = c;
    c.extend = this.extend || this.create;
    return c;
  };
})();

To use this code, we must first create the data types and then create objects from them. As a test, we will use these data types:

var X = CClass.create(function () {
  return {
    x: 3,

    test: function () { return 2 * this.x; }
  };
});

var Y = X.extend(function () {
  return {
    y: 4,

    test: function () { return this._super() + this.x + this.y; }
  };
});

var xx = new X;
var yy = new Y;

The X class (we’ll call them classes even though JavaScript doesn’t have classes as such; it’s easier to write about that way) has a single data field and a simple function which returns twice the data field. The Y class inherits X, adds a second data field, and overrides the test() function. Note that Y’s test() calls a function called _super(), which calls the base class version of test(). (It’s called ‘_super’ rather than ‘super’, since ‘super’ is a reserved word in JavaScript, even though it doesn’t do anything (yet).)

Once we’ve created the two classes, we can create objects from them in the usual way, using the ‘new’ operator. Let’s try to trace through this code to see what it’s doing.

First, note that the helper code at the top is actually run (notice the parentheses on line 18 at the bottom, which cause the preceding function to be run). Thus we create CClass as an empty function on line 2, and then define the create() function in the remaining code.

Now we look at the declaration of the X class. This is done by calling CClass.create() with the given function as the argument, so this function becomes myConstructor in the helper code. Since CClass is calling create(), ‘this’ refers to CClass, which is an empty function. This is saved in the variable k.

Now a function named c is defined. We’ll look at what it does in a minute, but note that at the end, its prototype is defined as ‘new this’, so the prototype gets a copy of CClass; also the constructor is set to the function c itself. On line 15, an extend() function is defined as either ‘this.extend’ if it’s defined or, if not, ‘this.create’. On the first call to create(), extend() won’t be pre-defined, so on this pass, extend is set to create and becomes the same function as create().

Also, note that the variables k and myConstructor as used inside the c function so, by closure, the values they had when the function was created are saved and are available to the c function when it is used later on.

The result of defining the X class is then to assign to X the c function produced by CClass.create(). Before we move on to Y, let’s see what happens when we create a new object using X, as we do on line 35.

This code treats X like a constructor, so the c function we just created gets called, and its ‘this’ is the object being created. Looking back at the first code block, we see that on line 6, this new object has its _super() defined as k, which you recall was set as the CClass earlier, and which is still available because of closure. Thus here, _super() becomes the empty function CClass.

On line 7, myConstructor() is called using JavaScript’s built-in apply() method, which specifies the calling object as the first argument (which is ‘this’ here) and then passes any arguments as an array (this will be empty in our simple example here). Remember that myConstructor contains the function defined on lines 19 to 25, so the result of this is that pubs contains a new object defined using that function.

Also on line 7, a ‘self’ variable is declared, and set to ‘this’. Since we haven’t actually created any data fields in our new object yet, ‘self’ at present is empty. The idea is to copy the fields from pubs to self so that the object created by constructor call (which is not pubs, since that was created by calling a different function) has the same fields as pubs.

The for loop on line 7 does this. It loops over each key in the pubs object. The body of the loop is another of those self-calling functions. Looking at line 11, we see that the arguments passed to the function are pubs[key] and self[key]. Since self is empty, all these elements will be undefined at this point. This means that the condition on line 9 ‘typeof sfn != “function”‘ will be true for every key, with the result that self[key] gets ‘fn’ assigned to it for every key. Since fn is the first function argument, this effectively runs self[key] = pubs[key], and copies pubs into self as required.

Thus the c function is a sort of roundabout way of implementing a constructor. However, the fun starts when we implement inheritance. On line 27, we create a Y class that inherits X by calling X.extend(). As before, the argument to extend() is a function which acts as a constructor for Y. When we created X, remember that extend() got assigned to create(), so calling X.extend() really calls X.create(). The process is similar to before, except that ‘this’ on line 4 now refers to X rather than CClass. The c function assigned to Y contains the same code as that assigned to X, but the values of k and myConstructor are those in force when X.extend() was called, using closure.

The main differences happen on lines 13 to 15. The prototype is defined as ‘new this’, which means it gets a copy of X. Remember that the prototype of a constructor is what’s the __proto__ of an object created from that constructor points to, so new objects created from this constructor will have all the fields of X.

On line 15, this.extend does exist now so it gets assigned to c.extend.

Now let’s see what happens if we create a Y object, as on line 36. The ‘new’ operator creates a new object by first pointing this object’s __proto__ at the constructor’s prototype. Remember we set Y’s prototype to an X object, so this means that the new Y object yy will inherit the fields of X right at the start. That is, ‘this’ will effectively b an X object at the start of the construction process, so ‘self’ gets assigned to an X object on line 7.

How about pubs, also on line 7? It is initialized by calling myConstructor, which contains the function on lines 27 to 33. This code knows nothing about X, so pubs contains only those fields specified in the Y constructor. Here, we have 2 fields: y and an override of test().

The for loop on line 8 runs for these 2 fields (but not for x, since that’s not mentioned in the Y constructor). For the y field, self[‘y’] is undefined, so it gets assigned to pubs[‘y’] and gets the value 4. However, when we look at the ‘test’ key, self[‘test’] does exist since there was a test() defined in X. In this case both conditions on line 9 are false (both fn and sfn are functions) so self[key] gets assigned to the function on line 10. Because of closure, the values of sfn and fn are saved when this is done.

The result of this is that, when Y’s version of test() is called, this._super gets set to the saved value of sfn, which is X’s version of test(), and then fn (which is Y’s version of test()) gets called via the apply() method. That is, whenever a method in the derived class is called, the corresponding base class method (if any) is available through this._super(). This means, of course, that the function referred to by this._super() varies, depending on which function calls it.

In my experience over years of ‘normal’ OOP using Java and C#, I have used a super() method only a handful of times, so you probably won’t need to use it that much. However, this clever solution makes it available in JavaScript if you need it.

Closure and classes in JavaScript

Although JavaScript is often touted as a class-free language, something very close to classes can be simulated using JavaScript’s support for closure. We’ve looked at C#’s support for closure, but closure is actually even easier to implement in JavaScript.

Suppose we wanted to create a number of bank account objects. One way of doing this is to use a constructor function as we’ve done earlier. We might write something like this:

function OpenAccount(number, balance) {
  this.number = number;
  this.balance = balance;
}

OpenAccount.prototype.deposit = function (money) {
  this.balance += money;
  return this.balance;
}

OpenAccount.prototype.withdraw = function (cash) {
  this.balance -= cash;
  return this.balance;
}

var acct1 = new OpenAccount(1, 1000);

This allows us to create a new account as we’ve done on the last line, where we create an account with number 1 and initial balance of 1000.

While this works, and we can call the deposit and withdraw functions to change the balance, it’s also possible to change the balance directly by writing acct1.balance += 200, which gives us an extra £200 without bothering to use the deposit function. We can do this because the object fields balance and number are public.

In classical OOP, good design says that all data fields should be private, and we should be able to interact with them only by means of interface methods. It looks as though we can’t do this in JavaScript, since there is no ‘private’ keyword (and in fact, no ‘class’ keyword). However, we can do something that amounts to much the same thing using the idea of closure.

Suppose we define the following function:

function account(number, balance) {
  return {
    getNumber: function () {
      return number;
    },

    getBalance: function () {
      return balance;
    },

    deposit: function (money) {
      balance += money;
      return balance;
    },

    withdraw: function (cash) {
      balance -= cash;
      return balance;
    }
  }
}

This function accepts two arguments, just as OpenAccount did, but instead of initializing an object with these values, all it does is return an object containing 4 functions. If you’re used to the classical scoping rules of a language like C#, you might also think this code won’t work. Why? Because we incorporate the function’s parameters ‘balance’ and ‘number’ into the object that is returned. JavaScript’s scoping rules are the same as those of C# and Java, in that function arguments exist only as long as the function is running.

However, because JavaScript implements closure, any function created inside another function gets a copy of the outer function’s internal variables, and this copy exists even after the outer function’s life is over. That’s what closure is; the inner function ‘closes over’ the variables it receives from the outer function and gives these internal copies a separate life of their own.

The key point is that these copies of ‘balance’ and ‘number’ are not data fields of the object returned by the account() function, so there is no direct access to them from the outside. The only way they can be read or written is by means of one of the 4 functions provided. They have, essentially, become private data fields.

To get a feel for how this works, open up a browser (such as Chrome) that supports a console and copy the definition of account() into it. Now try creating an account using this function. Note that since account() returns an object, it’s not a constructor, so you don’t use the ‘new’ operator to create objects. You write simply

var acct1 = account(42, 1000);

First, you can check that the 4 functions work as expected. Try viewing the balance by typing acct1.getBalance(), depositing some money by typing acct1.deposit(500) and so on. You should see that the returned values are what you expect in each case.

Now try accessing the balance directly, without using one of the 4 functions, by typing acct1.balance. You’ll get ‘undefined’ as a result, because the balance isn’t directly accessible.

So where, exactly, are these two data fields ‘number’ and ‘balance’ being stored? To find out, examine the structure of acct1 by typing just acct1 into the console. You’ll see that it’s an Object, so open the Object and look at its insides.

You should see entries for the 4 functions and also the ubiquitous __proto__ object we’ve discussed earlier, but there’s no sign of ‘balance’ or ‘number’.

Open up one of the function entries, say the deposit() function. One of its constituents is <function scope>. Open that, and you’ll see an entry called Closure. Open that, and lo and behold, inside the Closure are our two data fields. So they are being stored after all; they’re just not visible to the outside world, which is just what we want for a proper class.

Those of you who have been following these posts might now notice a possible loophole in all this though. Since JavaScript allows us to add data fields to any object at any time, why can’t we just add a ‘balance’ field to acct1? Let’s try it… Type in acct1.balance = 5000 in an attempt to give our account a free £5000. If you now type just acct1.balance into the console, you’ll get 5000 back as a response, so it seems to have worked.

However, if you type acct1.getBalance(), you’ll find that you still have only the £1000 you started with, and you’ll also find that trying to increase your savings using acct1.deposit() will affect only the original £1000, ignoring the £5000 you tried to add fraudulently.

You can see what’s happened by examining the structure of acct1 in the console again. The new balance field has been added at the top level, but if you dig down into the Closure section of the functions, you’ll find that the original balance is still there, untouched, and it’s that balance that the functions are using.

So as long as your code relies on the interface methods to interact with the data, the acct1 object is secure. That means that if you’ve written your code using this method, any external attempt to hack into it by overriding the private data fields won’t work. Even trying to hack into the object by writing your own function won’t work. If you wrote a function like acct1.fiddle = function(cash) { this.balance += cash; } you’ll find that the fiddle function affects only the top-level balance and not the one in the closure. Leaving off the ‘this’ from ‘this.balance’ doesn’t work either, since there is no ‘balance’ object defined in the scope of the fiddle function.

Functions and methods in JavaScript

JavaScript allows the creation of global functions, as in the simple example

function multiply(x, y) {
  return x * y;
}

This function can be called from anywhere using syntax such as var product = multiply(4, 5) which assigns the value 20 to product.

However, all functions are also objects and, as such, a function can be attached to another object as a data field. Functions that are fields of other objects are usually called methods.

Suppose we define  an object like this:

var number = { value: 0 }

This creates a single object called number which has a single data field called value. We can attach a method to number either as part of its definition, as in this attempt to define a method that squares number’s value:

var number = {
  value: 0,
  square: function() {
    return value * value;
  }
}

number.value = 42;
number.square();

If we run this code (try it in Chrome’s console), you probably won’t get the result you’re expecting. The call to number.square() returns NaN (not a number) rather than the expected value of 42 * 42 = 1764. What went wrong? Analogous code in a language like C# or Java would work, since we’re (kind of) treating number like a class with a data field and a method, and as we know, a class’s methods all have access to the class’s data fields.

JavaScript, as you’ve probably guessed, doesn’t work quite that way. If we refer to an unadorned variable like value, it is assumed that this is a global variable, so the square() method above looks for a global value and, not finding it, returns the indeterminate result of NaN.

You can test this by defining a global value variable and giving it a distinctive value, as in var value = 12; If you now run the line number.square() you’ll get the result 144, so it’s clear where the square() method is getting its ‘value’ from.

To solve this problem, we need to realize that any method gets a ‘bonus’ parameter passed to it, which is the object that calls the function. This object is referred to inside the function by the keyword this, which you’re probably familiar with from C# or Java. However, although using this as a prefix in C# is optional, in JavaScript it’s compulsory if you want to refer to the object calling the method. Thus our revised definition of number looks like this:

var number = {
  value: 0,
  square: function() {
    return this.value * this.value;
  }
}

number.value = 42;
number.square();

Now if we run the last 2 lines again, we get the expected result of 1764.

In fact, global functions are also passed a this parameter, except this time it refers to the global object, and use of this here actually is optional. For example, we could define the global function

function doubleValue() {
  return 2 * this.value;
}
doubleValue();

Running this code gives the result 24, since this.value now refers to the global value. We could equally well have defined this function as

function doubleValue() {
  return 2 * value;
}
doubleValue();

We’d get the same result.

This behaviour makes sense for truly global functions, but we run into problems if we declare functions inside methods. A rather contrived example is a revised version of the square function above. Suppose we define a new method for number called newSquare:

number.newSquare = function () {
  var innerSquare = function () {
    return multiply(this.value, this.value);
  }
  return innerSquare();
}

number.newSquare();

If number.value is still 42 and the global value is 12, running this code produces the value 144. Now what’s wrong? Even though we’ve included the this prefix when referring to value, the global value is still being used instead of number.value.

The problem here is what is widely regarded as a mistake in the design of JavaScript. Whenever a function that is not a field of an object (that is, a method) is called, this is always bound to the global object. The function innerSquare is a utility function declared within a method, but is not a method itself, so its this is the global object, not the number object that calls newSquare.

This sort of code design is very common, so there is a standard workaround to avoid this problem. Inner functions such as innerSquare do have access to local variables inside their container method, so we can define a local variable (usually called that) and assign it to point to this. We can then use that whenever we want to access the object that called the method. We therefore rewrite newSquare as follows:

number.newSquare = function () {
  var that = this;
  var innerSquare = function () {
     return multiply(that.value, that.value);
  }
  return innerSquare();
}

number.newSquare();

This time we get the correct result of 1764.

Prototypes in JavaScript

JavaScript’s prototype system is often confusing for programmers coming to the language from an object-oriented background, as with C# or Java. Here I’ll try to dispel a bit of confusion by looking at how object prototypes work.

For what follows, it’s very useful if you enter the code into a console (such as can be found in the Google Chrome browser) and experiment with the various commands.

We can create an object by writing its fields literally, as in

var comic = {
  title: 'Spider-man',
  issue: 343
}

Type this into the console and then examine the comic object (by just typing ‘comic’ (without the quotes) on a line by itself and hitting return). Its type is given as Object, which isn’t surprising. Open up this node, and you’ll see that in addition to the two fields ‘issue’ and ‘title’, there is a third field called (in Chrome, though this won’t be true in all browsers) __proto__, whose type is given as Object. If you expand __proto__, you’ll see a list of fields that include the functions that are defined for all objects, such as toString, hasOwnProperty and so on.

The __proto__ object is the prototype that is attached to all objects by default. In its expansion, you may notice that it does not have its own __proto__ field. This is because the prototype of Object is the end of the prototype chain (more on this later). Thus it is more correct to say that all objects except Object’s prototype have their own prototype.

So what use is this prototype? Its importance arises from the fact that you can customize it by adding fields to it, or replacing it completely with an object of your own making.

We saw in the post on creating objects with a constructor that we can add methods to objects by adding a method to the constructor’s prototype. Let’s have a closer look at what’s going on here.

First, we need to make one thing clear. It is true that all objects (including functions) have the prototype we’ve been referring to by the name __proto__. However, functions (and only functions) also have a separate ‘prototype’ property, where in this case, the word ‘prototype’ is spelled out in full and not abbreviated or enclosed in underscores. Please understand that __proto__ and ‘prototype’ are not the same; only __proto__ is the true prototype of an object or a function. So what’s the ‘prototype’ property of a function used for?

When we use the ‘new’ operator to create a new object from a constructor, the new operator creates the new object and then links the object’s __proto__ to the constructor’s ‘prototype’. Note that this is a reference link from the object to the constructor, and not a copy of the constructor’s prototype to the object’s __proto__. This means that any changes to the constructor’s prototype are reflected in the __proto__ of all objects created from it. More on this below.

For example, suppose we define the Book constructor as in the previous post (we’ve made a slight change in that the name of the constructor has been moved to the function definition rather than being a separate var, but the effect is the same):

function Book(author, title, price) {
  this.author = author;
  this.title = title;
  this.price = price;
};

var book1 = new Book("Asimov", "Foundation", 3.55);

Now examine ‘book1’ in the console. You’ll find that it contains the three data fields defined in the constructor and also __proto__. Expand __proto__, and you’ll see that it contains the constructor, along with another __proto__, the latter of which is the base Object prototype. If you expand the constructor, you’ll see that it contains its own __proto__ and also a ‘prototype’ of type Book. It’s this ‘prototype’ that is used to create new objects.

If we add a method to the constructor’s ‘prototype’ like this:

Book.prototype.description = function () {
  return this.author + ': <i>' + this.title + '</i>  £' + this.price;
}

we can examine the __proto__ of ‘book1’ again. Now we’ll find that the ‘description’ function has been added:

> book1
  Book
    author: "Asimov"
    price: 3.55
    title: "Foundation"
    __proto__: Object
      constructor: function (author, title, price) {
      description: function () {
      __proto__: Object

If we expand ‘description’, we find that it, too, has a __proto__ and a ‘prototype’, since it’s a function. However, its ‘prototype’ isn’t used for anything, since ‘description’ isn’t a constructor.

A neat trick is to use prototypes to create a new object that inherits its prototype from an existing object. To do this, we can add a new method to Object (so that it’s available to all our code). This is the ‘beget’ method, and is due to Douglas Crockford:

if (typeof Object.beget !== 'function') {
  Object.beget = function (copy) {
    var F = function () { };
    F.prototype = copy;
    return new F();
  };
}

var book3 = Object.beget(book1);

The initial ‘if’ checks if ‘beget’ has already been defined (if it hasn’t, the typeof will return ‘undefined’). We then define Object.beget as a function which takes a single argument copy. Inside beget(), we create an empty function called F, and assign this function’s ‘prototype’ (not __proto__) to be the object copy that we want to copy. F is treated as a constructor, and the ‘new’ operator is used to create a new object from F, which is then returned. Recall that using ‘new’ creates a new object whose __proto__ is a copy of the constructor’s ‘prototype’, so the effect is to generate a new object whose __proto__ is copy.

The book3 object inherits all the fields of book1 and is shown as being of type F. Expanding F, we find that its only field is __proto__, which is of type Book, and if we expand that, we get the same fields as we had for book1.

If we now access book3.title, we’ll get ‘Spider-man’ which of course was copied from book1. What’s important to note, though, is that the ‘title’ field isn’t in the top layer of fields for book3; it’s one layer down, in the Book prototype. This illustrates that JavaScript will look for a field iteratively from the top down, so if it doesn’t find the field you want at the top layer, it will look at the next layer, and then the next, and so on, until it either finds the field or hits the Object.__proto__ at the bottom. If it doesn’t find it there, it will return ‘undefined’.

The prototype chain includes only the __proto__ fields; the ‘prototype’ properties have nothing to do with this process. They are used only in the creation of new objects in a constructor.

What happens if we try altering the data fields in these objects? For example, suppose we try writing book3.author = ‘Simak’. We find that the ‘author’ field of book3 is indeed now Simak, but has this assignment affected anything on the prototype chain? We can examine book3’s structure once again to find out.

We find that, rather than altering the ‘author’ field in the Book __proto__, book3 has a new author field at the top level. That is, we now have

> book3
 F
  author: "Simak"
  __proto__: Book
    author: "Asimov"
    price: 3.55
    title: "Foundation"
    __proto__: Book

Assigning a new value to an existing field in a __proto__ doesn’t overwrite the existing value; it adds a new value at the layer above the __proto__.  JavaScript ‘knows’ which author to use, since when we request the author field, it starts at the top in its search, so the first author found will be Simak. If we remove that field with the statement delete book3.author, we find that the top layer author is removed, and the author property reverts to that stored in the __proto__, so it becomes ‘Asimov’ again.

What happens if we do change a property in the __proto__? Suppose we start with book1 and book3 as above (without the episode where we introduced ‘Simak’), so both books have ‘Asimov’ as their author. We now try writing book3.__proto__.author = “Delaney”. Now we find that the authors of both book1 and book3 have changed to Delaney, since we changed the underlying __proto__ on which both these books are defined. (By the way, fiddling with __proto__ directly isn’t terribly good programming practice, not least because not all browsers support it. We did it here just to illustrate a point.)

We can modify a constructor’s ‘prototype’ after the constructor has been used to create objects and these modifications will be available to the existing objects. This is because the __proto__ in an object is a pointer back to the constructor’s prototype that was used to create it. For example, we could add a method to Book by writing Book.prototype.getPrice = function() { return this.price; }. Having done that, we can now write book1.getPrice() to retrieve book1’s price of 3.55.

[Beware of a gotcha here, though. Since __proto__ is a reference to the constructor’s ‘prototype’, if you redefine the constructor’s prototype to point to a totally new object, the __proto__ reference won’t follow this change; it will still point to the old object. That is, it’s OK to modify fields and methods of the ‘prototype’ object originally associated with the constructor, but it’s not OK to replace that ‘prototype’ object.]