Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

06 July 2011

Java Swing basics

In Java Swing system, below are a few basic concepts you need to understand:
  1. Everything appears on screen is basically a component. JComponent is the Swing superclass of all things that draw on screen. For example, JLabel is a built-in JComponent that displays little text string. What you usually do is to create components objects and install it onto screen or their container.
  2. Frames (JFrame) are the outermost components. A JFrame represents a single window. Each JFrame component has a "content pane" JComponent that contains all components in the frame. You can use frame.getContentPane() to get the content pane. Content pane uses a Layout Manager to size and position its components. Frame has a convenience add() and setLayout() that go to its content pane.
  3. Components are placed inside other components which form a nesting hierarchy from outer to inner components. And each container is behind the components it contains. Layout Manager sizes and places those components according to some 'policies' or 'intents' of the layout. Don't call setSize() yourself, the layout manager controls that! Instead, do call setMinimumSize(), setMaximumSize() or setPreferredSize(), to register a preference before the layout manager lays everything out (before calling pack() / setVisible()).
  4. Three basic layout manager: FlowLayout, BoxLayout, BorderLayout. Flow layout arranges components left-right, top-down like text. Box layout aligns components in a line, either vertically or horizontally. Border layout puts main content in the center and decorate with 4 things around the outsize -- north, south, east, west.
  5. Swing thread, or Event-dispatch thread, Composite pattern and Observer/Observable patterns basically form the underlying architecture of Swing GUI system.
  6. A common technique in Java GUI code is to use an anonymous inner class to create a 'listener' class object and register it using addXXXListener() method to a Observable, e.g a button, on the fly.

05 July 2011

Java String comparison

A common mistake you might make when doing Java string comparison is like this:

String s = "abs";
String t = "cde";

// test for pointer equality, in other words,
// test if s and t are the same object
if (s == t)


What you really want to do might be this:

if (s.equals(t)) // compare characters in two strings


However in python, s==t is actually what you want. When you know too many programming languages, you can easily mess up the syntax and semantics of them accidentally. Be careful.

06 May 2011

Python datetime object

A little note about datetime object: date, datetime, time objects all support a strftime(format) method. Check its document here. And you can see some concrete code examples (about the time format).

Google App Engine Blobstore API experience

I have been building a small website in the past few days using Google App Engine. During this small project, the most intriguing part is hacking Blobstore API. Luckily, I conquered it again and found a few things:

  1. To create your own blob in blobstore, you'd better follow this example
  2. If you follow that example exactly, you will create a blob without filename. To set the filename when creating a blob, I found this discussion; the original google api document isn't very helpful on that. To get more insights about that API, check the source code here.

30 March 2011

[Technote] Eclipse shortcut keys

To accelerate your programming speed on Eclipse, it's essential that you master the shortcut keys in Eclipse. Here I list a few shortcuts I found particularly useful:

Navigation shortcuts

CTRL+L - Jump to a line with line number x.
CTRL+Q - Go to the last edit location.
ALT+Left/Right - Same as CTRL+Q.
F3 - Go to the definition of a variable, method or class.
CTRL+O - Go to the declaration of a variable, method, or class.
CTRL+ALT+H - Show call hierarchy of a method.

File navigation shortcuts

CTRL+E - open a searchable list of all the open editors for you.
CTRL+SHIFT+T - Open a file by summon a file search box.

Editing shortcuts

CTRL+SHIFT+O - Doing all the imports automatically for you!
CTRL+I - Correcting indentation.
CTRL+/ - To comment out a line or lines (by selecting a group lines).
CTRL+D - To delete a line.
CTRL+SPACE (SHIFT+A in my IDE setting) - Autocomplete codes.
CTRL+1 - Suggest quick fixes.
ALT+SHIFT+R - Doing rename and refactoring for you.

Search shortcuts

CTRL+J - Incremental search.
CTRL+F - Single search.

Other shortcuts


CTRL+SHIFT+F - List all the shortcut keys and their mappings for you.

I will add more to this list once I find out other useful shortcuts.

27 March 2011

[Technote] Saving states from Android Activities

When you start to develop applications on Android devices, managing Activity states definitely is the first major thing to master in order to create reliable, robust Android apps. Here I will simply go through what I have found during developing Android apps myself:

First, you have to think carefully what states are necessary to be retained when Android Activity is destroyed. Usually, the less states you save, the better (because that reduces your Activity start-up time as well as destroying time). For instance, you might not need to save the 'look' of View, because it can always be redrawn/recomputed every time when an Activity comes to live; instead, saving some states necessary for Android to recompute that look, i.e., the current position of the cursor on screen.

Second, you can then think about HOW to save states after determining what to save. Generally, there are three ways to do it (not including saving data on Android internal filesystem or SD card):
  • Using Bundle to save primitive typed (check for Bundle API), temporary data.
  • Using SharedPreferences to save primitive typed, persistent data.
  • Using onRetainNonConfigurationInstance to save temporary object instances.
I personally find the last bullet very useful because the data we want to save cannot always be primitive typed! For more details about the differences and usages of the three approaches, check out here.

To retrieve data you saved, onCreate is a good place for your activity to reload states. According to my experience, onCreate is probably and mostly what you really want, not onResume or onStart otherwise.

A side note for the above: the easiest and best way to test if your management of Activity's life cycle is correct, is to change the orientation of the screen. It should not crash and the behavior should be the same as before orientation.

Last, sometimes what we really want is to have some simple communication mechanism between activities (i.e., the calling activity and the callee activity) instead of saving states, how to achieve that? In the caller activity, call the callee with startActivityForResult, and also implement the onActivityResult method. Then, in the callee, remember to call setResult to set the result to be returned, before the activity is finished.

17 March 2011

[Techonote] Java container anomaly

You can assign a pointer of type sub to a pointer of type super (this is simply a is-a relationship). However, you cannot assign a pointer type container(sub) to a pointer of type container(super) (e.g. List<String> IS NOT a List<Object>).

15 March 2011

[Technote] Caution for Java auto-unboxing

Auto unboxing does not work with == or !=.

For example:

Two List<Integer> a and b, a.get(0) == b.get(0) -- does not unbox. Instead, it does an == pointer comparison between the two Integer objects.

To get what you want, you will do the following:

Use a.get(0).intValue() == b.get(0).intValue() to force the conversion to int. Or you could write a.get(0).equals(b.get(0)) which works for String, Integer, etc.

23 February 2011

[Technotes] Android UI - Dialogs

First of all, what is a dialog?

"A dialog is usually a small window that appears in front of the current Activity. The underlying Activity loses focus and the dialog accepts all user interaction." - Android Dev Guide

Android UI API has some native Dialog objects for you to use. For most general purposes, AlertDialog is sufficient.

Read this page yourself before creating dialogs boxes in your Android application. The sections I think is useful for learning and application development is the following:

22 February 2011

[Technotes] Java Inner classes

First thing first, there is some terminology that needs to be explained.

In Java, you can define a class inside another class; such a class is called nested class. Nested classes can be divided into two categories: static or non-static. Static nested classes are simply called static nested classes. Non-static nested classes are called inner classes.

As for nested classes' privileges, inner classes have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class, instead, it can only access to static methods and members of the enclosing (parent) class.

To make the story even more complex, there are 2 other flavors of 'inner classes': local classes and anonymous classes (also called anonymous inner classes). You get to see lots of these two special kinds of inner classes in GUI codes. So you must understand and master them to be able to do GUI programming in Java. To see some concrete examples of these two classes, check out here and there.

In addition, you'd better read the following three web pages carefully before using inner or nested classes:

http://bit.ly/fPoJad - Nested classes introduction
http://bit.ly/dQzVvD - Inner class code example

Finally, to instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

18 February 2011

[Technotes] invalidate() method

In android system, the class View (android.view.View) is an important interface for rendering UI objects. Inside it, a method called invalidate() plays a key role.

The function of invalidate is simple, it marks a region on the view to be 'dirty', which tells the android system that region must be redrawn soon in the near future. The region can be the whole View or just a designated region passed to invalidate. And obviously, invalidating only a small portion of the view can have some performance advantages for the UI system. Therefore, make sure you use invalidate() wisely!

Also, an important point: never call any drawing functions except in the onDraw( ) method (a method of class View). Instead, you use the invalidate( ) method to mark rectangles as dirty. The window manager will combine all the dirty rectangles at some point in the future and call onDraw( ) again for you. The dirty rectangles become the clip region, so screen updates are optimized to only those areas that change.

14 February 2011

06 February 2011

[Tech notes] How to delete objects in Java?

There is no delete or free keyword in Java. The only thing that can collect the unreferenced memory chunk is garbage collector (GC). To take advantage of that, the best practice is to 'null' out your object reference whenever you want the GC to free that object:


MyObject a = new MyObject();

... /* Do something with object a */

a = null; /* Tell GC to free the memory referenced by a! */

05 February 2011

[Tech notes] Android UI basics overview

Some overviews of Android UI programming:
Key classes of UI system: 

04 February 2011

[Tech notes] Android UI basics

In an Android application, the user interface is built using View and ViewGroup objects. There are many types of views and view groups, each of which is a descendant of the View class.

View objects are the basic units of user interface expression on the Android platform. The View class serves as the base for subclasses called "widgets," which offer fully implemented UI objects, like text fields and buttons.

The ViewGroup class serves as the base for subclasses called "layouts," which offer different kinds of layout architecture, like linear, tabular and relative.

On the Android platform, you define an Activity's UI using a hierarchy of View and ViewGroup nodes (as shown here). In order to attach the view hierarchy tree to the screen for rendering, your Activity must call the setContentView() method and pass a reference to the root node object. The Android system receives this reference and uses it to invalidate, measure, and draw the tree. The root node of the hierarchy requests that its child nodes draw themselves — in turn, each view group node is responsible for calling upon each of its own child views to draw themselves.

Android parses the elements of your layout in-order (from the top of the hierarchy tree), instantiating the Views and adding them to their parent(s). Because these are drawn in-order, if there are elements that overlap positions, the last one to be drawn will lie on top of others previously drawn to that space.

01 February 2011

[Tech notes] Android API levels

The following table specifies the API Level supported by each version of the Android platform:

Platform VersionAPI Level
Android 2.39
Android 2.28
Android 2.17
Android 2.0.16
Android 2.05
Android 1.64
Android 1.53
Android 1.12
Android 1.01

The API Level identifier serves a key role in ensuring the best possible experience for users and application developers:
  • It lets the Android platform describe the maximum framework API revision that it supports
  • It lets applications describe the framework API revision that they require
  • It lets the system negotiate the installation of applications on the user's device, such that version-incompatible applications are not installed.

Applications can use a manifest element provided by the framework API — uses-sdk — to describe the minimum and maximum API Levels under which they are able to run, as well as the preferred API Level that they are designed to support.

Development Considerations

Application forward compatibility

Android applications are generally forward-compatible with new versions of the Android platform.

Because almost all changes to the framework API are additive, an Android application developed using any given version of the API (as specified by its API Level) is forward-compatible with later versions of the Android platform and higher API levels.

Application backward compatibility

Android applications are not necessarily backward compatible with versions of the Android platform older than the version against which they were compiled.

Reference

31 January 2011

Virtual function

In object-oriented programming, a virtual function or virtual method is a function or method whose behaviour can be overridden within an inheriting class by a function with the same signature. This concept is a very important part of the polymorphism portion of OOP.

The purpose of having a virtual function is as follows:

In OOP when a derived class inherits a base class, an object of the derived class may be referred to (or cast) as either being the base class type or the derived class type. If there are base class methods overridden by the derived class, the method call behaviour is ambiguous.

The distinction between virtual and non-virtual resolves this ambiguity. If the function in question is designated "virtual" in the base class then the derived class's function would be called (if it exists). If it is not virtual, the base class's function would be called.

Virtual functions overcome the problems with the type-field solution by allowing the programmer to declare functions in a base class that can be redefined in each derived class.

Programming language supports for virtual function:

C++: virtual methods are declared by using the virtual keyword followed by the function name and the parenthesis ().

Java: In Java, all non-static methods are by default "virtual functions." Only methods marked with the keyword final, which cannot be overridden, along with private methods, which are not inherited, are non-virtual. To override a method, use an annotation '@Override' (could be omitted) followed by function definition.

Python: In Python all class functions (methods) are virtual. And no special keywords needed to make overriding or virtualization happen. It just works automatically!

Reference: wiki

05 January 2011

Python raw_input() vs input()

# raw_input() reads every input as a string
# then it's up to you to process the string

str1 = raw_input("Enter anything:")
print "raw_input =", str1

# input() actually uses raw_input() and then tries to
# convert the input data to a number using eval()
# hence you could enter a math expression
# gives an error if input is not numeric eg. $34.95

x = input("Enter a number:")
print "input =", x


The code example above is from this link. One other thing to note here is that there is no raw_input in Python 3 anymore, only input() function available.

15 December 2010

Algorithm optimization notes

Today I was working on optimizing an alpha-beta gaming algorithm, and I found a few things along the way:
  • Object creation can be time consuming and dragging down your algorithm performance. So, think twice when object creation can be avoided.
  • When you are implementing an algorithm, the first thing is to make it work correctly, the second thing is to spot the heavy-weight routine or code sections that requires dense computation.
  • Think twice about the use of data structure. Often times it is the wrong data structure you use that slows down the program execution.

07 December 2010

Deep copy vs. Shallow copy vs. Lazy copy

There are basically three strategies for copying objects; each has its own advantages and disadvantages.

Shallow Copy

Shallow copy is basically passing references, not actually copying data inside objects. That is why shallow copy is otherwise known as address copy. The main advantage of shallow copy is it is very fast and does not depend on the size of data; however, if the language does not support automatic garbage collection, a shallow copy could lead to a memory leak if not cautious enough. In addition, two object references refer to the same data block on memory after shallow copy.

Deep Copy 

This is the opposite of shallow copy. The data from one object is actually copy over to another object. Therefore, two object bare the same data after deep copy and yet there are still different objects! The disadvantage of this strategy is it is slow and expensive; however, deep-copied objects do not depend on each other and are independently modifiable.

Lazy Copy

A lazy copy is a combination of both strategies above. When initially copying an object, a shallow copy is used. A counter is also used to track how many objects share the data. When the program wants to modify an object, it can determine if the data is shared and can do a deep copy if necessary. This is also very similar to 'copy-on-write' technique used in most OSes.

So, how are copy actually implemented in programming languages?

In Java:  

Using clone method of a class.

In Python: 

the library's copy module provides shallow copy and deep copy of objects through the copy() and deepcopy() functions, respectively. Programmers may define special methods __copy__() and __deepcopy__() in an object to provide custom copying implementation.