Wednesday, February 2, 2011

Setting maximum length limit in UITextField in iPhone.

There is no direct method to set the maximum length of input an UITextField should allow. But we can restrict the user to input to a certain length of characters.
Suppose we want a uitextfield only to accept upto 10 characters. Any character (other than enter and delete) should not be allowed to input if the user has already
entered 10 characters. i.e, we want to set a maximum length verifier to the UITextField. In Objective C we can do it as follows.
    We can create our own delegate for the UITextField. In this delegate we can put our logic to verify the input. And also we need to set this delegate as the UITextfield 's
delegate.

Step1.
    Writing the delegate:
    In MaxLengthDelegate.h

    @interface MaxLengthDelegate : NSObject <UITextFieldDelegate>{
        @private
            int max_length; //
      }
      @end

    In MaxLengthDelegate.m implement the following method and also modify the init method to init this with the maximum length user wants.

        - (BOOL) textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)textEntered
        {
            //check for enter and delete keys. These should be allowed even after the length is equal to max_length.
            if (([textField.text length] && range.length == 1) || [textEntered isEqualToString:@"\n"]) {
                return YES;
            }
   
            //check the length and return NO if it exceeds the max_length.
            if ([textField.text length] >= max_length) {
                return NO;
            }
   
            return YES;
        }

        //Setting the default max_length to 10.
        - (id) init
        {
            self = [super init];
            if (self != nil) {
                max_length = 10;
            }
            return self;
        }

        //to init delegate with the length.
        - (id) init : (int) maxLength
        {
            self = [super init];
            if (self != nil) {
                max_length = maxLength;
            }
            return self;
        }

Steps 2:
    Set the delegate of the UITextField which length needs to be verified as the maxLengthDelegate. For example, if we want to restrict input length of the UITextField (txtField) to 5, we can do it as:

    MaxLengthDelegate  maxLenDel = [[MaxLengthDelegate alloc] init: 5];
    [txtField setDelegate: maxLenDel];

Thanks

Writing simple callback in java

Callback can be used when you want to invoke some methods on the basis of some property changes. Suppose you want to call a piece of code of
another class automatically when there is a change in property. Or you have a single property that is used by more than one classes to do some
work. So when the value of this property is changed you want to notify those classes so that they can do their work with this updated value.
This can be done by callback routing.
   
    Steps to write callback routine.
Step1.
    Write one interface with the method/methods need(s) to be invoked.
   
    eg.
   
    public interface ICallback {
        public void notifyChange();
    }
   
Step2.
    Now write your binder class that will notify the object which is binded with it.
   
    public class CallbackBinder {
        private ICallback iCallback;   
       
        public void bindCallback (ICallback callBack){
            this.iCallback = callBack;
        }
       
        //so whenever the property changes notify the class object.
        public void notifyCallBack(){
            iCallback.notifyChange();
        }
   
    }

Step3.
    We need to bind the class with the callbackBinder to receive the notification. To do so we have to implement the ICallback interface and also pass the class reference to the binder.
   
    public class TestClass implements ICallback {
       
        public TestClass () {
            new CallbackBinder ().bindCallback (this);
        }
       
        //you have to define the notify method and do the work as you want.
        public void notifyChange () {
           
        }   
    }
   
    The notityChange method will be fired when the callbackBinder execute the notifyCallBack method.
   
    We can also handle multiple classes objects with the same property. Suppose a single property has to bind with multiple classes objects and on changing the value of that property we need to call all the class objects. To accomplish this we can maintain a map which will contain the property as the key and the list of ICallback objects as value. We can make the CallbackBinder class as singleton to bind all the class objects to the same instance of the binder class.
        
    private Map<String, List<ICallback>> propertyCallbackMap = new HashMap<String, List<ICallback>>();

    when the property value is changed just get the object list and call notifyChange on them.

Thanks


For free computer engineering programming books you can visit:
Free Computer Books

Wednesday, January 26, 2011

Hiding columns in jTable using swing:


   Hiding column in jTable is not same as hiding a button or any jComponent. Column in jTable is of type TableColumn. TableCoulmn does not extend JComponent and so we cannot hide a column in jTable just by setting visibilty false,i.e., tableColumn.setVisible(false) will not work in case of jTable column. But we can hide a column in jTable by the following two easy way.

Method 1:
    We can set the width of the column to zero to make it visible false. And to make it visible again, we have to set the size again. We need to set the min,max and preferred size.


    To hide the column:
        jTable1.getColumnModel().getColumn(index).setMaxWidth(0);
        jTable1.getColumnModel().getColumn(index).setMinWidth(0);
        jTable1.getColumnModel().getColumn(index).setPreferredWidth(0);
   

   To make the column visible again:
      jTable1.getColumnModel().getColumn(index).setMaxWidth(WIDTH_TO_SET);
      jTable1.getColumnModel().getColumn(index).setMinWidth(WIDTH_TO_SET);
      jTable1.getColumnModel().getColumn(index).setPreferredWidth(WIDTH_TO_SET);
   

index: index of the column to hide.

Replace WIDTH_TO_SET with the size you want.

Method 2:
    TableColumnModel contains all the column information of the jTable. By removing the coulmn from table column model we can make it hidden, and to make it visible we need to add it again. But when we add a column to the TableColumnModel it appends the column to the existing ones. This means the coulmn will be added to the right side of the last coulmn of the table. So after adding column to the tableColumnModel we need to move the column to its previous index to make it look the same as it was before hidding the column. To accomplish this we have save the reference of the removed column and its index before hidding so that when we need to show the same column again we can add the same reference to the tableColumnModel and also move the column to its original position.


    Mehtod to remove column:
        /*save the column if we need to make it visible later.
          You can also make a custom class which will contains the tableColumn   object and also the original index. Maintain a list of the objects of this custom class. This list will contain all the column that are made hidden.
        */
        //to simply hide second column.  
        TableColumn col = jTable1.getColumnModel().getColumn(1);
        int index = 1;
        jTable1.getColumnModel().removeColumn(jTable1.getColumnModel().getColumn(1));   
To make the column visible.
        /* If you have written your own class for saving removed columns then just    get that coulmn object and index and add it accordingly.
        */
        //simply to make second column visible.

    //Get the column object for the list or map maintained for the removed columns.
        TableColumn col = getColumnObejct();
        jTable1.getColumnModel().addColumn(col); //add it to the righmost side.
       //move the column to the index 1.        
    jTable1.getColumnModel().moveColumn(jTable1.getColumnModel().getColumnCount()-1, 1);
  

For free computer engineering JAVA programming books you can visit:
Free Computer Books

Saturday, December 25, 2010

Customised UITableView for iphone.

This article is for creating custom UITableViewCell. We can have textfield, buttons inside our uitableview. We need just to customise  tableViewCell.
The example below will illustrate how to use tableview. Also it will show how to add and delete rows dynamically from the table.

1. Add a new Objective C class file (choose subclass of as "UITableViewCell") say CustomTableCell.
2. Add a new User interface class of type Empty XIB say say CustomTableCell.xib.
3.Open the say CustomTableCell.xib file in the interface builder. Open library and drag one "Table View Cell" to your CustomTableCell.xib. Now click on the "Table View Cell" and in the inspector window click on "Table view cell identity".
Change the class to "CustomTableCell".


4. Click on the File's owner icon. and in the inspector window click on "Object identity".
Change the class to "TableTestViewController" (your view controller in which this table cell will be used).


5. Double click on the CustomTableCell in the interface builder and add two textField to the table cell content view.
6. In your CustomTableCell.h
@interface CustomTableCell : UITableViewCell {
UITextField *firstColumn;
UITextField *secondColumn;
}

@property (nonatomic, retain) IBOutlet UITextField *firstColumn;
@property (nonatomic, retain) IBOutlet UITextField *secondColumn;

@end

7. In your CustomTableCell implementation class.

@synthesize firstColumn, secondColumn;

- (id) init {
self = [super init];
if (self != nil) {
// initializations go here.
firstColumn = [[UITextField alloc]init];
secondColumn = [[UITextField alloc]init];
}
return self;
}

8. Now open the CustomTableCell.xib and bind firstColumn and secondColumn to the UITextFields.
9. To add tableView in the viewcontroller :
Make your view controller as delegate for the table. Say your view controller is :TableTestViewController.
So in TableTestViewController.h includes these lines:

@interface TableTestViewController : UIViewController <UITableViewDelegate>{
CustomTableCell *tableCell;
UITableView *tableView;
}

@property (nonatomic, retain) IBOutlet CustomTableCell *tableCell;
@property (nonatomic, retain) IBOutlet UITableView *tableView;

Also import CustomTableCell. Bind this tableView to the table added to your view controller in the interface builder.

10. Bind the delegate and datasource of the table to the viewController using interface builder.


11. In your TestTableViewController implementation class (TestTableViewController.m) add the following line to the viewDidLoad method
[tableView setEditing:YES animated:YES];

12. Define TOTAL_NO_ROWS in the file. eg.,

int TOTAL_NO_OF_ROWS = 2;
Also add these methods to the class:

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = @"MyIdentifier";
CustomTableCell *cell = (CustomTableCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:@"CustomTableCell" owner:self options:nil];
cell = tableCell;
self.tableCell = nil;
}
// Configure the cell with the relevant data and style...
if(indexPath.row == TOTAL_NO_OF_ROWS){
cell.firstColumn.text = @"Add New";
[cell.firstColumn setBorderStyle:UITextBorderStyleNone];
[cell.secondColumn setBorderStyle:UITextBorderStyleNone];
cell.firstColumn.enabled = FALSE;
cell.secondColumn.enabled = FALSE;
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
}
return cell;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger rows = TOTAL_NO_OF_ROWS;
if (self.tableView.editing) {
rows ++;
}
TOTAL_NO_OF_ROWS = rows;
return rows+1;
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCellEditingStyle style = UITableViewCellEditingStyleNone;
//Last row will have the add new icon.
//All other row will have style for delete only.
if (indexPath.row < TOTAL_NO_OF_ROWS) {
style = UITableViewCellEditingStyleDelete;
}else {
style = UITableViewCellEditingStyleInsert;
}
return style;
}

//commit the edit style accordingly.
// in case of delete reduce the total no of rows.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleInsert) {
NSMutableArray *insertIndexPaths = [[NSMutableArray alloc] init];
NSIndexPath *newPath = [NSIndexPath indexPathForRow:TOTAL_NO_OF_ROWS inSection:0];
[insertIndexPaths addObject:newPath];
[self.tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationTop];
}else if (editingStyle == UITableViewCellEditingStyleDelete) {
TOTAL_NO_OF_ROWS = TOTAL_NO_OF_ROWS -2;
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
}
}


13. We are done. The ui should look like the below one:

Touching on the delete icon you can delete the row or you can add a new row by just touching on the add new icon.
Thanks





Wednesday, December 22, 2010

Decimal Textfield in iphone.

Decimal Textfield in iphone

There is no decimal point character in the iphone numberKeyPad. To take input for currency such as for rupees or dollar we need to
add the decimal point programmatically.

Simple steps for making decimal textfield for iphone.

1. We can make our own delegate which extends to the UITextFieldDelegate as:

DecimalTextField.h
   
#import <Foundation/Foundation.h>
#import "KeyboardHelper.h"

@interface DecimalTextFieldDelegate : NSObject<UITextFieldDelegate> {
   
}

@end


2. In the implementation of this interface define
- (BOOL) textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)textEntered.

we can manupulate and replace the text in the textfiled using this method. For example the following code will add a decimal point before the
second digit from the right of the input text.


DecimalTextFieldDelegate.m

#import "DecimalTextFieldDelegate.h"


@implementation DecimalTextFieldDelegate


//This method will add decimal before the second element from the right
-(NSString *) addDecimal : (NSString *)text{
   
    text = [text stringByReplacingOccurrencesOfString:@"." withString:@""];
    int i = [text intValue];
    NSString *test = [[NSNumber numberWithInt:i] stringValue];
    if ([test length] == 1) {
        test = [NSString stringWithFormat:@"%@%@", @"0", test];
    }
   
    NSString *lastTwo = [test substringFromIndex: [test length] -2];
    NSString *firstFew = [test length] >=3 ?[test substringToIndex:[test length] -2] : @"0";
   
    NSString *formatted = [NSString stringWithFormat:@"%@%@%@", firstFew, @".", lastTwo];
    return formatted;
}

- (BOOL) textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)textEntered
{
    //to handle enter key
    if ([textEntered isEqualToString:@"\n"]) {
        return YES;
    }
   
    //to handle backspace
    if ([textField.text length] && range.length == 1) {
        NSString *test = [[textField text] substringToIndex:[[textField text] length] -1];;
       
        textField.text = [self addDecimal:test];
        return NO;
    }
   
    if ([textField.text length] >=0 && [textEntered length] >0) {
        NSString *test = [NSString stringWithFormat:@"%@%@",[textField text],textEntered];
       
        textField.text = [self addDecimal:test];
       
        return NO;
    }
   
    return YES;
}
@end

3. Any uitextfield can be transformed to decimal textfield by setting its delegate to the DecimalTextFieldDelegate. This can be done as:
    UITextField *textField = [[UITextField alloc]init];
    DecimalTextFieldDelegate *delegate = [[DecimalTextFieldDelegate alloc]init];
    [textField setDelegate: atmDelegate];
   
  This will make the textField to show value in decimal.
    Input 123 in the textfield, it will be shown as 1.23.



By modifying the logic in
- (BOOL) textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)textEntered  we can format the string as we want.