• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008,2009  OMRON SOFTWARE Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package jp.co.omronsoft.openwnn;
18 
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.app.Dialog;
22 import android.content.DialogInterface;
23 import android.content.Intent;
24 import android.graphics.Color;
25 import android.os.Bundle;
26 import android.text.TextUtils;
27 import android.util.Log;
28 import android.view.Display;
29 import android.view.Menu;
30 import android.view.MenuItem;
31 import android.view.MotionEvent;
32 import android.view.KeyEvent;
33 import android.view.View;
34 import android.view.ViewGroup;
35 import android.view.Window;
36 import android.view.WindowManager;
37 import android.view.View.OnFocusChangeListener;
38 import android.view.View.OnTouchListener;
39 import android.widget.TableLayout;
40 import android.widget.TableRow;
41 import android.widget.TextView;
42 import android.widget.Toast;
43 import android.widget.Button;
44 
45 import java.util.ArrayList;
46 import java.util.Arrays;
47 import java.util.Comparator;
48 
49 
50 /**
51  * The abstract class for user dictionary tool.
52  *
53  * @author Copyright (C) 2009, OMRON SOFTWARE CO., LTD.  All Rights Reserved.
54  */
55 public abstract class UserDictionaryToolsList extends Activity
56     implements View.OnClickListener, OnTouchListener, OnFocusChangeListener {
57 
58     /** The class name of the user dictionary tool */
59     protected String  mListViewName;
60     /** The class name of the user dictionary editor */
61     protected String  mEditViewName;
62     /** The package name of the user dictionary editor */
63     protected String  mPackageName;
64 
65     /** ID of the menu item (add) */
66     private final int MENU_ITEM_ADD = 0;
67     /** ID of the menu item (edit) */
68     private final int MENU_ITEM_EDIT = 1;
69     /** ID of the menu item (delete) */
70     private final int MENU_ITEM_DELETE = 2;
71     /** ID of the menu item (initialize) */
72     private final int MENU_ITEM_INIT = 3;
73 
74     /** ID of the dialog control (confirm deletion) */
75     private final int DIALOG_CONTROL_DELETE_CONFIRM = 0;
76     /** ID of the dialog control (confirm initialize) */
77     private final int DIALOG_CONTROL_INIT_CONFIRM = 1;
78 
79     /** The size of font*/
80     private final int WORD_TEXT_SIZE = 16;
81 
82     /** The color of background (unfocused item) */
83     private final int UNFOCUS_BACKGROUND_COLOR = 0xFF242424;
84     /** The color of background (focused item) */
85     private final int FOCUS_BACKGROUND_COLOR = 0xFFFF8500;
86 
87     /** The minimum count of registered words */
88     private final int MIN_WORD_COUNT = 0;
89     /** The maximum count of registered words */
90     private final int MAX_WORD_COUNT = 100;
91     /** Maximum word count to display */
92     private final int MAX_LIST_WORD_COUNT = 100;
93 
94     /** The threshold time of the double tapping */
95     private final int DOUBLE_TAP_TIME = 300;
96 
97     /** Widgets which constitute this screen of activity */
98     private Menu mMenu;
99     /** Table layout for the lists */
100     private TableLayout mTableLayout;
101     /** Focusing view */
102     private static View sFocusingView = null;
103     /** Focusing pair view */
104     private static View sFocusingPairView = null;
105 
106     /** Objects which control state transitions */
107     private Intent mIntent;
108 
109     /** The number of the registered words */
110     private int mWordCount = 0;
111 
112     /** The state of "Add" menu item */
113     private boolean mAddMenuEnabled;
114     /** The state of "Edit" menu item */
115     private boolean mEditMenuEnabled;
116     /** The state of "Delete" menu item */
117     private boolean mDeleteMenuEnabled;
118     /** The state of "Initialize" menu item */
119     private boolean mInitMenuEnabled;
120 
121     /** {@code true} if the menu option is initialized */
122     private boolean mInitializedMenu = false;
123     /** {@code true} if one of word is selected */
124     private boolean mSelectedWords;
125     /** The viewID which is selected */
126     private int mSelectedViewID = -1;
127     /** The viewID which was selected previously */
128     private static int sBeforeSelectedViewID = -1;
129     /** The time of previous action */
130     private static long sJustBeforeActionTime = -1;
131 
132     /** List of the words in the user dictionary */
133     private ArrayList<WnnWord> mWordList = null;
134 
135     /** Work area for sorting the word list */
136     private WnnWord[] mSortData;
137 
138     /** Whether the view is initialized */
139     private boolean mInit = false;
140 
141     /** Page left button */
142     private Button mLeftButton = null;
143 
144     /** Page right button */
145     private Button mRightButton = null;
146 
147     /**
148      * Send the specified event to IME
149      *
150      * @param ev    The event object
151      * @return      {@code true} if this event is processed
152      */
sendEventToIME(OpenWnnEvent ev)153     protected abstract boolean sendEventToIME(OpenWnnEvent ev);
154     /** Get the comparator for sorting the list */
getComparator()155     protected abstract Comparator<WnnWord> getComparator();
156 
157     /**
158      * Create the header
159      */
headerCreate()160     protected abstract void  headerCreate();
161 
162     /** @see android.app.Activity#onCreate */
onCreate(Bundle savedInstanceState)163     @Override protected void onCreate(Bundle savedInstanceState) {
164 
165 
166         super.onCreate(savedInstanceState);
167 
168         /* create XML layout */
169         requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
170         setContentView(R.layout.user_dictionary_tools_list);
171         mTableLayout = (TableLayout)findViewById(R.id.user_dictionary_tools_table);
172 
173         Button b = (Button)findViewById(R.id.user_dictionary_left_button);
174         b.setOnClickListener(new View.OnClickListener() {
175                 public void onClick(View v) {
176                     int pos = mWordCount - MAX_LIST_WORD_COUNT;
177                     if (0 <= pos) {
178                         mWordCount = pos;
179                         updateWordList();
180                         mTableLayout.findViewById(1).requestFocus();
181                     }
182                 }
183             });
184         mLeftButton = b;
185 
186         b = (Button)findViewById(R.id.user_dictionary_right_button);
187         b.setOnClickListener(new View.OnClickListener() {
188                 public void onClick(View v) {
189                     int pos = mWordCount + MAX_LIST_WORD_COUNT;
190                     if (pos < mWordList.size()) {
191                         mWordCount = pos;
192                         updateWordList();
193                         mTableLayout.findViewById(1).requestFocus();
194                     }
195                 }
196             });
197         mRightButton = b;
198 
199     }
200 
201     /** @see android.app.Activity#onStart */
onStart()202     @Override protected void onStart() {
203         super.onStart();
204         sBeforeSelectedViewID = -1;
205         sJustBeforeActionTime = -1;
206         mWordList = getWords();
207 
208         headerCreate();
209         final TextView leftText = (TextView) findViewById(R.id.user_dictionary_tools_list_title_words_count);
210         leftText.setText(mWordList.size() + "/" + MAX_WORD_COUNT);
211 
212         updateWordList();
213     }
214 
215     /**
216      * Set parameters of table
217      *
218      * @param  w        The width of the table
219      * @param  h        The height of the table
220      * @return          The information of the layout
221      */
tableCreateParam(int w, int h)222     private TableLayout.LayoutParams tableCreateParam(int w, int h) {
223         return new TableLayout.LayoutParams(w, h);
224     }
225 
226     /** @see android.app.Activity#onCreateOptionsMenu */
onCreateOptionsMenu(Menu menu)227     @Override public boolean onCreateOptionsMenu(Menu menu) {
228 
229 
230         /* initialize the menu */
231         menu.clear();
232         /* set the menu item enable/disable */
233         setOptionsMenuEnabled();
234         /* [menu] add a word */
235         menu.add(0, MENU_ITEM_ADD, 0, R.string.user_dictionary_add)
236             .setIcon(android.R.drawable.ic_menu_add)
237             .setEnabled(mAddMenuEnabled);
238         /* [menu] edit a word */
239         menu.add(0, MENU_ITEM_EDIT, 0, R.string.user_dictionary_edit)
240             .setIcon(android.R.drawable.ic_menu_edit)
241             .setEnabled(mEditMenuEnabled);
242         /* [menu] delete a word */
243         menu.add(0, MENU_ITEM_DELETE, 0, R.string.user_dictionary_delete)
244             .setIcon(android.R.drawable.ic_menu_delete)
245             .setEnabled(mDeleteMenuEnabled);
246         /* [menu] clear the dictionary */
247         menu.add(1, MENU_ITEM_INIT, 0, R.string.user_dictionary_init)
248             .setIcon(android.R.drawable.ic_menu_delete)
249             .setEnabled(mInitMenuEnabled);
250 
251         mMenu = menu;
252         mInitializedMenu = true;
253 
254 
255         return super.onCreateOptionsMenu(menu);
256     }
257 
258     /**
259      * Change state of the option menus according to a current state of the list widget
260      */
setOptionsMenuEnabled()261     private void setOptionsMenuEnabled() {
262 
263 
264         /* [menu] add a word */
265         if (mWordList.size() >= MAX_WORD_COUNT) {
266             /* disable if the number of registered word exceeds MAX_WORD_COUNT */
267             mAddMenuEnabled = false;
268         } else {
269             mAddMenuEnabled = true;
270         }
271 
272         /* [menu] edit a word/delete a word */
273         if (mWordList.size() <= MIN_WORD_COUNT) {
274             /* disable if no word is registered or no word is selected */
275             mEditMenuEnabled = false;
276             mDeleteMenuEnabled = false;
277         } else {
278             mEditMenuEnabled = true;
279             if (mSelectedWords) {
280                 mDeleteMenuEnabled = true;
281             } else {
282                 mDeleteMenuEnabled = false;
283             }
284         }
285 
286         /* [menu] clear the dictionary (always enabled) */
287         mInitMenuEnabled = true;
288 
289     }
290 
291     /** @see android.app.Activity#onOptionsItemSelected */
onOptionsItemSelected(MenuItem item)292     @Override public boolean onOptionsItemSelected(MenuItem item) {
293 
294         boolean ret;
295         switch (item.getItemId()) {
296         case MENU_ITEM_ADD:
297             /* add a word */
298             wordAdd();
299             ret = true;
300             break;
301 
302         case MENU_ITEM_EDIT:
303             /* edit the word (show dialog) */
304             wordEdit(sFocusingView, sFocusingPairView);
305             ret = true;
306             break;
307 
308         case MENU_ITEM_DELETE:
309             /* delete the word (show dialog) */
310             showDialog(DIALOG_CONTROL_DELETE_CONFIRM);
311             ret = true;
312             break;
313 
314         case MENU_ITEM_INIT:
315             /* clear the dictionary (show dialog) */
316             showDialog(DIALOG_CONTROL_INIT_CONFIRM);
317             ret = true;
318             break;
319 
320         default:
321             ret = false;
322         }
323 
324         return ret;
325     }
326 
327     /** @see android.app.Activity#onKeyUp */
onKeyUp(int keyCode, KeyEvent event)328     @Override public boolean onKeyUp(int keyCode, KeyEvent event) {
329         /* open the menu if KEYCODE_DPAD_CENTER is pressed */
330         if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
331             openOptionsMenu();
332             return true;
333         }
334         return false;
335     }
336 
337     /** @see android.app.Activity#onCreateDialog */
onCreateDialog(int id)338     @Override protected Dialog onCreateDialog(int id) {
339         switch (id) {
340         case DIALOG_CONTROL_DELETE_CONFIRM:
341             return new AlertDialog.Builder(UserDictionaryToolsList.this)
342                 .setMessage(R.string.user_dictionary_delete_confirm)
343                 .setNegativeButton(android.R.string.cancel, null)
344                 .setPositiveButton(android.R.string.ok, mDialogDeleteWords)
345                 .setCancelable(true)
346                 .create();
347 
348         case DIALOG_CONTROL_INIT_CONFIRM:
349             return new AlertDialog.Builder(UserDictionaryToolsList.this)
350                 .setMessage(R.string.dialog_clear_user_dictionary_message)
351                 .setNegativeButton(android.R.string.cancel, null)
352                 .setPositiveButton(android.R.string.ok, mDialogInitWords)
353                 .setCancelable(true)
354                 .create();
355 
356         default:
357             Log.e("OpenWnn", "onCreateDialog : Invaled Get DialogID. ID=" + id);
358             break;
359         }
360 
361 
362         return super.onCreateDialog(id);
363     }
364 
365     /**
366      * Process the event when the button on the "Delete word" dialog is pushed
367      *
368      * @param  dialog    The information of the dialog
369      * @param  button    The button that is pushed
370      */
371     private DialogInterface.OnClickListener mDialogDeleteWords =
372         new DialogInterface.OnClickListener() {
373             public void onClick(DialogInterface dialog, int button) {
374 
375                 CharSequence focusString = ((TextView)sFocusingView).getText();
376                 CharSequence focusPairString = ((TextView)sFocusingPairView).getText();
377                 WnnWord wnnWordSearch = new WnnWord();
378 
379                 if (mSelectedViewID > MAX_WORD_COUNT) {
380                     wnnWordSearch.stroke = focusPairString.toString();
381                     wnnWordSearch.candidate = focusString.toString();
382                 } else {
383                     wnnWordSearch.stroke = focusString.toString();
384                     wnnWordSearch.candidate = focusPairString.toString();
385                 }
386                 boolean deleted = deleteWord(wnnWordSearch);
387                 if (deleted) {
388                     Toast.makeText(getApplicationContext(),
389                                    R.string.user_dictionary_delete_complete,
390                                    Toast.LENGTH_LONG).show();
391                 } else {
392                     Toast.makeText(getApplicationContext(),
393                                    R.string.user_dictionary_delete_fail,
394                                    Toast.LENGTH_LONG).show();
395                     return;
396                 }
397 
398                 mWordList = getWords();
399                 int size = mWordList.size();
400                 if (size <= mWordCount) {
401                     int newPos = (mWordCount - MAX_LIST_WORD_COUNT);
402                     mWordCount = (0 <= newPos) ? newPos : 0;
403                 }
404                 updateWordList();
405 
406                 TextView leftText = (TextView) findViewById(R.id.user_dictionary_tools_list_title_words_count);
407                 leftText.setText(size + "/" + MAX_WORD_COUNT);
408 
409                 if (mInitializedMenu) {
410                     onCreateOptionsMenu(mMenu);
411                 }
412             }
413         };
414 
415     /**
416      * Process the event when the button on the "Initialize" dialog is pushed
417      *
418      * @param  dialog    The information of the dialog
419      * @param  button    The button that is pushed
420      */
421     private DialogInterface.OnClickListener mDialogInitWords =
422         new DialogInterface.OnClickListener() {
423             public void onClick(DialogInterface dialog, int button) {
424 
425                 /* clear the user dictionary */
426                 OpenWnnEvent ev = new OpenWnnEvent(OpenWnnEvent.INITIALIZE_USER_DICTIONARY, new WnnWord());
427 
428                 sendEventToIME(ev);
429                 /* show the message */
430                 Toast.makeText(getApplicationContext(), R.string.dialog_clear_user_dictionary_done,
431                                Toast.LENGTH_LONG).show();
432                 mWordList = new ArrayList<WnnWord>();
433                 mWordCount = 0;
434                 updateWordList();
435                 TextView leftText = (TextView) findViewById(R.id.user_dictionary_tools_list_title_words_count);
436                 leftText.setText(mWordList.size() + "/" + MAX_WORD_COUNT);
437 
438                 if (mInitializedMenu) {
439                     onCreateOptionsMenu(mMenu);
440                 }
441             }
442         };
443 
444 
445     /** @see android.view.View.OnClickListener#onClick */
onClick(View arg0)446     public void onClick(View arg0) {
447     }
448 
449     /** @see android.view.View.OnTouchListener#onTouch */
onTouch(View v, MotionEvent e)450     public boolean onTouch(View v, MotionEvent e) {
451 
452 
453         mSelectedViewID = ((TextView)v).getId();
454         switch (e.getAction()) {
455         case MotionEvent.ACTION_DOWN:
456             /* double tap handling */
457             if (sBeforeSelectedViewID != ((TextView)v).getId()) {
458                 /* save the view id if the id is not same as previously selected one */
459                 sBeforeSelectedViewID = ((TextView)v).getId();
460             } else {
461                 if ((e.getDownTime() - sJustBeforeActionTime) < DOUBLE_TAP_TIME) {
462                     /* edit the word if double tapped */
463                     sFocusingView = v;
464                     sFocusingPairView = ((UserDictionaryToolsListFocus)v).getPairView();
465                     wordEdit(sFocusingView, sFocusingPairView);
466                 }
467             }
468             /* save the action time */
469             sJustBeforeActionTime = e.getDownTime();
470             break;
471         }
472 
473         return false;
474     }
475 
476     /** @see android.view.View.OnFocusChangeListener#onFocusChange */
onFocusChange(View v, boolean hasFocus)477     public void onFocusChange(View v, boolean hasFocus) {
478 
479         mSelectedViewID = ((TextView)v).getId();
480         sFocusingView = v;
481         sFocusingPairView = ((UserDictionaryToolsListFocus)v).getPairView();
482         if (hasFocus) {
483             ((TextView)v).setTextColor(Color.BLACK);
484             v.setBackgroundColor(FOCUS_BACKGROUND_COLOR);
485             ((TextView)sFocusingPairView).setTextColor(Color.BLACK);
486             sFocusingPairView.setBackgroundColor(FOCUS_BACKGROUND_COLOR);
487             mSelectedWords = true;
488         } else {
489             mSelectedWords = false;
490             ((TextView)v).setTextColor(Color.LTGRAY);
491             v.setBackgroundColor(UNFOCUS_BACKGROUND_COLOR);
492             ((TextView)sFocusingPairView).setTextColor(Color.LTGRAY);
493             sFocusingPairView.setBackgroundColor(UNFOCUS_BACKGROUND_COLOR);
494         }
495         if (mInitializedMenu) {
496             onCreateOptionsMenu(mMenu);
497         }
498     }
499 
500     /**
501      * Add the word
502      */
wordAdd()503     public void wordAdd() {
504         /** change to the edit window */
505         screenTransition(Intent.ACTION_INSERT, mEditViewName);
506     }
507 
508     /**
509      * Edit the specified word
510      *
511      * @param  focusView       The information of view
512      * @param  focusPairView   The information of pair of view
513      */
wordEdit(View focusView, View focusPairView)514     public void wordEdit(View focusView, View focusPairView) {
515         if (mSelectedViewID > MAX_WORD_COUNT) {
516             createUserDictionaryToolsEdit(focusPairView, focusView);
517         } else {
518             createUserDictionaryToolsEdit(focusView, focusPairView);
519         }
520         screenTransition(Intent.ACTION_EDIT, mEditViewName);
521     }
522 
523     /**
524      * The internal process of editing the specified word
525      *
526      * @param  focusView        The information of view
527      * @param  focusPairView    The information of pair of view
528      */
createUserDictionaryToolsEdit(View focusView, View focusPairView)529     protected abstract UserDictionaryToolsEdit createUserDictionaryToolsEdit(View focusView, View focusPairView);
530 
531     /**
532      * Delete the specified word
533      *
534      * @param  searchword   The information of searching
535      * @return          {@code true} if success; {@code false} if fail.
536      */
deleteWord(WnnWord searchword)537     public boolean deleteWord(WnnWord searchword) {
538         OpenWnnEvent event = new OpenWnnEvent(OpenWnnEvent.LIST_WORDS_IN_USER_DICTIONARY,
539                                               WnnEngine.DICTIONARY_TYPE_USER,
540                                               searchword);
541 
542         boolean deleted = false;
543         sendEventToIME(event);
544         for( int i=0; i < MAX_WORD_COUNT; i++) {
545             WnnWord getword = new WnnWord();
546             event = new OpenWnnEvent(OpenWnnEvent.GET_WORD,
547                                      getword);
548             sendEventToIME(event);
549             getword = event.word;
550             int len = getword.candidate.length();
551             if (len == 0) {
552                 break;
553             }
554             if (searchword.candidate.equals(getword.candidate)) {
555                 WnnWord delword = new WnnWord();
556                 delword.stroke = searchword.stroke;
557                 delword.candidate = searchword.candidate;
558                 delword.id = i;
559                 event = new OpenWnnEvent(OpenWnnEvent.DELETE_WORD,
560                                          delword);
561                 deleted = sendEventToIME(event);
562                 break;
563             }
564         }
565 
566         if (mInitializedMenu) {
567             onCreateOptionsMenu(mMenu);
568         }
569 
570         return deleted;
571     }
572 
573 
574     /**
575      * Processing the transition of screen
576      *
577      * @param  action       The string of action
578      * @param  classname    The class name
579      */
screenTransition(String action, String classname)580     private void screenTransition(String action, String classname) {
581 
582         if (action.equals("")) {
583             mIntent = new Intent();
584         } else {
585             mIntent = new Intent(action);
586         }
587         mIntent.setClassName(mPackageName, classname);
588         startActivity(mIntent);
589         finish();
590     }
591 
592     /**
593      * Get the list of words in the user dictionary.
594      * @return The list of words
595      */
getWords()596     private ArrayList<WnnWord> getWords() {
597         WnnWord word = new WnnWord();
598         OpenWnnEvent event = new OpenWnnEvent(OpenWnnEvent.LIST_WORDS_IN_USER_DICTIONARY,
599                                               WnnEngine.DICTIONARY_TYPE_USER,
600                                               word);
601         sendEventToIME(event);
602 
603         ArrayList<WnnWord> list = new ArrayList<WnnWord>();
604         for (int i = 0; i < MAX_WORD_COUNT; i++) {
605             event = new OpenWnnEvent(OpenWnnEvent.GET_WORD, word);
606             if (!sendEventToIME(event)) {
607                 break;
608             }
609             list.add(event.word);
610         }
611 
612         compareTo(list);
613 
614         return list;
615     }
616 
617     /**
618      * Sort the list of words
619      * @param array The array list of the words
620      */
compareTo(ArrayList<WnnWord> array)621     protected void compareTo(ArrayList<WnnWord> array) {
622         mSortData = new WnnWord[array.size()];
623         array.toArray(mSortData);
624         Arrays.sort(mSortData, getComparator());
625     }
626 
627 
628     /**
629      * Update the word list.
630      */
updateWordList()631     private void updateWordList() {
632         if (!mInit) {
633             mInit = true;
634             mSelectedViewID = 1;
635 
636             Window window = getWindow();
637             WindowManager windowManager = window.getWindowManager();
638             Display display = windowManager.getDefaultDisplay();
639             int system_width = display.getWidth();
640 
641             for (int i = 1; i <= MAX_LIST_WORD_COUNT; i++) {
642                 TableRow row = new TableRow(this);
643                 UserDictionaryToolsListFocus stroke = new UserDictionaryToolsListFocus(this);
644                 stroke.setId(i);
645                 stroke.setWidth(system_width/2);
646                 stroke.setTextSize(WORD_TEXT_SIZE);
647                 stroke.setTextColor(Color.LTGRAY);
648                 stroke.setBackgroundColor(UNFOCUS_BACKGROUND_COLOR);
649                 stroke.setSingleLine();
650                 stroke.setPadding(1,0,1,1);
651                 stroke.setEllipsize(TextUtils.TruncateAt.END);
652                 stroke.setClickable(true);
653                 stroke.setFocusable(true);
654                 stroke.setFocusableInTouchMode(true);
655                 stroke.setOnTouchListener(this);
656                 stroke.setOnFocusChangeListener(this);
657 
658                 UserDictionaryToolsListFocus candidate = new UserDictionaryToolsListFocus(this);
659                 candidate.setId(i+MAX_WORD_COUNT);
660                 candidate.setWidth(system_width/2);
661                 candidate.setTextSize(WORD_TEXT_SIZE);
662                 candidate.setTextColor(Color.LTGRAY);
663                 candidate.setBackgroundColor(UNFOCUS_BACKGROUND_COLOR);
664                 candidate.setSingleLine();
665                 candidate.setPadding(1,0,1,1);
666                 candidate.setEllipsize(TextUtils.TruncateAt.END);
667                 candidate.setClickable(true);
668                 candidate.setFocusable(true);
669                 candidate.setFocusableInTouchMode(true);
670                 candidate.setOnTouchListener(this);
671                 candidate.setOnFocusChangeListener(this);
672 
673                 stroke.setPairView(candidate);
674                 candidate.setPairView(stroke);
675 
676                 row.addView(stroke);
677                 row.addView(candidate);
678                 mTableLayout.addView(row, tableCreateParam(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
679             }
680         }
681 
682         int size = mWordList.size();
683         int start = mWordCount;
684 
685         TextView t = (TextView)findViewById(R.id.user_dictionary_position_indicator);
686         if (size <= MAX_LIST_WORD_COUNT) {
687             ((View)mLeftButton.getParent()).setVisibility(View.GONE);
688         } else {
689             ((View)mLeftButton.getParent()).setVisibility(View.VISIBLE);
690             int last = (start + MAX_LIST_WORD_COUNT);
691             t.setText((start + 1) + " - " + Math.min(last, size));
692 
693             mLeftButton.setEnabled(start != 0);
694             mRightButton.setEnabled(last < size);
695         }
696 
697         int selectedId = mSelectedViewID - ((MAX_WORD_COUNT < mSelectedViewID) ? MAX_WORD_COUNT : 0);
698 
699         for (int i = 0; i < MAX_LIST_WORD_COUNT; i++) {
700             if ((size - 1) < (start + i)) {
701                 if ((0 < i) && (selectedId == (i + 1))) {
702                     mTableLayout.findViewById(i).requestFocus();
703                 }
704 
705                 ((View)(mTableLayout.findViewById(i + 1)).getParent()).setVisibility(View.GONE);
706                 continue;
707             }
708 
709             WnnWord wnnWordGet;
710             wnnWordGet = mSortData[start + i];
711             int len_stroke = wnnWordGet.stroke.length();
712             int len_candidate = wnnWordGet.candidate.length();
713             if (len_stroke == 0 || len_candidate == 0) {
714                 break;
715             }
716 
717             if (selectedId == i + 1) {
718                 mTableLayout.findViewById(i + 1).requestFocus();
719             }
720 
721             TextView text = (TextView)mTableLayout.findViewById(i + 1);
722             text.setText(wnnWordGet.stroke);
723             text = (TextView)mTableLayout.findViewById(i + 1 + MAX_WORD_COUNT);
724             text.setText(wnnWordGet.candidate);
725             ((View)text.getParent()).setVisibility(View.VISIBLE);
726         }
727         mTableLayout.requestLayout();
728     }
729 }
730