<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CTAPbIu_MABP&#039;s BLOG &#187; JAVA</title>
	<atom:link href="http://mabp.kiev.ua/category/programming/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://mabp.kiev.ua</link>
	<description>энтузиазм = 1/опыт © Старый Мавр</description>
	<lastBuildDate>Thu, 26 Jan 2012 10:34:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>Android SDK 2.2</title>
		<link>http://mabp.kiev.ua/2010/10/08/android-sdk-2-2/</link>
		<comments>http://mabp.kiev.ua/2010/10/08/android-sdk-2-2/#comments</comments>
		<pubDate>Fri, 08 Oct 2010 13:21:37 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[android]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1269</guid>
		<description><![CDATA[Последний раз я работал с Android еще когда версия SDK была 1,6. А теперь вот решил обновить впечатления и хочу вам сказать что все очень понравилось :) Я пока не успел ничего написать, ни запустить старый проект, но уже есть комментарий. Для использования нового профиля телефона надо, что бы путь к нему содержал только латинские [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://mabp.kiev.ua/2009/09/16/androids-modal-dialogs-example/">Последний раз</a> я работал с <a href="http://mabp.kiev.ua/tag/android/">Android</a> еще когда версия SDK была 1,6. А теперь вот решил обновить впечатления и хочу вам сказать что все очень понравилось :)</p>
<span id="more-1269"></span>
<p>Я пока не успел ничего написать, ни запустить старый проект, но уже есть комментарий. Для использования нового профиля телефона надо, что бы путь к нему содержал  только латинские буквы. По умолчанию профили телефонов создаются в папке пользователя, так что если вас зовут "Администратор" то создавать профиль нужно такой командой</p>
<pre><code class="bat">
android create avd -n my_profile_name -t 1 -p f:\path\to\profiles 
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2010/10/08/android-sdk-2-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>О пользе чтения мануалов</title>
		<link>http://mabp.kiev.ua/2009/12/17/about-benefits-of-reading-manuals/</link>
		<comments>http://mabp.kiev.ua/2009/12/17/about-benefits-of-reading-manuals/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 19:34:54 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[Голоса в голове]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Разное]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1165</guid>
		<description><![CDATA[Читал сегодня форум, там человека раз 5 отослали в мануал, он так и не сходил, ему сказали ЧТО нужно сделать, после чего он спросил КАК. В общем редкостный лентяй, в других случаях я бы сказал дебил, но этот вроде адекватен, хотя... После прочтения этого треда я вспомнил как я только начинал свое знакомство с JAVA. [...]]]></description>
			<content:encoded><![CDATA[<p>Читал сегодня <a href="http://pyha.ru/forum/" rel="nofollow external">форум</a>, там человека раз 5 отослали в мануал, он так и не сходил, ему сказали ЧТО нужно сделать, после чего он спросил КАК. В общем редкостный лентяй, в других случаях я бы сказал дебил, но этот вроде адекватен, хотя...</p>
<span id="more-1165"></span>
<p>После прочтения этого треда я вспомнил как я только начинал свое знакомство с <a href="http://mabp.kiev.ua/category/programming/java/">JAVA</a>. Решив что я круто знаю один язык программирования, <a href="http://mabp.kiev.ua/category/programming/php/">PHP</a>, и мне ничего не стоит писать на другом с таким же синтаксисом, и еще лучшим ООП и тд и тп возомнил себя мега гуру.</p>
<p>Первых 5 страниц мана было читать впадло, потому что там пишут для дебилов типа скачайте СДК, поставьте, проверьте работает ли, откройте редактрор... в лучшем случаи, в худшем начинают со словаря понятий или экскурса в те времена когда автор писал на fortran 86, в общем неимоверно скучно...</p>
<p>Я зашел в IRC на #java и спросил там "чуваки я умею писать на C++ мне нужен к(в)икстарт для java, покажите как написать минимальный хеловорд". Естественно вместо C++ я знал PHP и специально, наврал чтоб мне не парили моск тем что PHP не язык, а я должен читать про фортран.
<p>и знаете что мне ответили чуваки на канале?! Вы не поверите, они сказали :</p>

<pre><code class="java">
public class HelloWord {
    public static void main(String[] args) {
        System.out.print("hello word");
    }
}
</code></pre>

<p>Счастье длилось ровно секунду, потому что я по прежнему не знал что делать, ни как скомпилить, ни как заранить, ни даже как создать новый проект в IDE (какие опции выбрать).</p>
<p>Мне чужое знание, каким-то магическим образом, не передалось, и пришлось читать ман с первой страницы. И вам не передастся. Ничего страшного не случится, если и вы почитаете с самого начала, только время сэкономите и свое и чужое.</p>
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/12/17/about-benefits-of-reading-manuals/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>JComboBox Demo</title>
		<link>http://mabp.kiev.ua/2009/12/04/jcombobox-demo/</link>
		<comments>http://mabp.kiev.ua/2009/12/04/jcombobox-demo/#comments</comments>
		<pubDate>Fri, 04 Dec 2009 18:00:10 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[autocomplete]]></category>
		<category><![CDATA[combobox]]></category>
		<category><![CDATA[swing]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1142</guid>
		<description><![CDATA[Пока я сижу без реального проекта вдохновение брать неоткуда :( Поэтому постить тут буду что есть, а есть первый толковый вопрос по Java с форума Задание было дизейблить кнопку если в комбике ничего не введено Swing конечно не jQuery но на нем тоже можно делать UI package ua.kiev.mabp; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import [...]]]></description>
			<content:encoded><![CDATA[<p>Пока я сижу без реального проекта вдохновение брать неоткуда :( Поэтому постить тут буду что есть, а есть первый толковый вопрос по <a href="http://mabp.kiev.ua/category/programming/java/">Java</a> с <a href="http://pyha.ru/forum/" rel="nofollow external">форума</a></p>
<p>Задание было дизейблить кнопку если в комбике ничего не введено Swing конечно не jQuery но на нем тоже можно делать UI</p>

<span id="more-1142"></span>
<pre><code class="java">
package ua.kiev.mabp;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;

/**
 * Created by IntelliJ IDEA.
 * User: CTAPbIu_MABP
 * Date: 30.11.2009
 * Time: 18:48:00
 */

public class ComboBoxEventDemo extends JFrame {

    public ComboBoxEventDemo(String name) {
        super(name);
    }

    public void addComponentsToPane(final Container pane) {

        String comboPrefix = "ComboBox Item #";
        int numItems = 15;
        Vector&lt;String&gt; vector = new Vector&lt;String&gt;(numItems);
        for (int i = 0; i &lt; numItems; i++) {
            vector.addElement(comboPrefix + i);
        }

        final JComboBox searchCombo = new JComboBox(vector);
        searchCombo.setEditable(true);
        final JButton okButton = new JButton("OK");

        searchCombo.getEditor().getEditorComponent().addKeyListener(new KeyListener() {
            public void keyTyped(KeyEvent e) {
                System.out.print("keyTyped");
            }

            public void keyPressed(KeyEvent e) {
                System.out.print("keyPressed");
            }

            public void keyReleased(KeyEvent e) {
                System.out.print("keyReleased");
                try {
                    String s = (String) searchCombo.getSelectedItem();
                    okButton.setEnabled(s != null &#038;& !s.isEmpty());
                }
                catch (NullPointerException npe) {
                    okButton.setEnabled(false);
                }
            }
        });

        add(searchCombo);
        add(okButton);

        pane.setLayout(new GridBagLayout());
        setPreferredSize(new Dimension(450, 450));
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                FocusEventDemo frame = new ComboBoxEventDemo("JComboBox Demo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.addComponentsToPane(frame.getContentPane());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}
</code></pre>

<p>Я прекрасно понимаю что это гавно никому не надо не мне ни вам, хотя кто знает может кому-то когда-то пригодится, а пишу я это для того чтоб вы не забывали что я еще есть и жив, зашли на мой сайт оставить камент типа "ну и дерьмо же ты постишь, чувак, совсем хуевый стал, отпишусь ка я от твоего RSS" и тем самым накрутили бы мне счетчик посещаймости :D</p>
<p>Ладно заспойлю вам кое-что, может не отпишитесь от моего RSS. В ближайшее время будет статья о векторной графике с красивым примером.</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/12/04/jcombobox-demo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Non-triming space</title>
		<link>http://mabp.kiev.ua/2009/12/01/non-triming-space/</link>
		<comments>http://mabp.kiev.ua/2009/12/01/non-triming-space/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 17:16:30 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[regex]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1143</guid>
		<description><![CDATA[Когда Женя показал мне свою заметку о неубиваймом пробеле я подумал это недостатки php и сказал, что в Java такой фигни нет и не будет. Оказалось показалось, Java тоже грешит этой фигней. package ua.kiev.mabp; /** * Created by IntelliJ IDEA. * User: CTAPbIu_MABP * Date: 01.12.2009 * Time: 18:48:00 */ public class TrimDemo { public [...]]]></description>
			<content:encoded><![CDATA[<p>Когда Женя показал мне свою <a href="http://vedeney.org.ua/php/trim-function-doesnt-clean-out-ascii-code-160/" rel="nofollow external">заметку</a> о неубиваймом пробеле я подумал это недостатки php и сказал, что в <a href="http://mabp.kiev.ua/category/programming/java/">Java</a> такой фигни нет и не будет. Оказалось показалось, <a href="http://mabp.kiev.ua/category/programming/java/">Java</a> тоже грешит этой фигней.</p>
<span id="more-1143"></span>
<pre><code class="java">
package ua.kiev.mabp;

/**
 * Created by IntelliJ IDEA.
 * User: CTAPbIu_MABP
 * Date: 01.12.2009
 * Time: 18:48:00
 */
public class TrimDemo {
    public static void main(String[] args) {
        System.out.print("".concat(String.valueOf(new char[]{160, 160, 160})).trim().length());
    }
}
</code></pre>

<p>И еще <a href="http://www.jstoolbox.com/2009/11/01/funkciya-trim/" rel="nofollow external">лик</a> в тему</p>


]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/12/01/non-triming-space/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Пример модальных диалогов для Android</title>
		<link>http://mabp.kiev.ua/2009/09/16/androids-modal-dialogs-example/</link>
		<comments>http://mabp.kiev.ua/2009/09/16/androids-modal-dialogs-example/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 20:56:17 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[Modal Dialog]]></category>
		<category><![CDATA[pbank]]></category>
		<category><![CDATA[progress bar]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1121</guid>
		<description><![CDATA[Здравствуйте, дорогие слушатели, сегодня в нашем подкасте вы узнаете о том как создать красивый стандартный индикатор загрузки в своем приложении... Ой, а что, никто не записывает?! Ну, ладно... тогда проговаривайте (можно про себя) текст и думайте что это подкаст. И нет, я не курил, просто настроение хорошее. В общем решил показать массам как выглядит код [...]]]></description>
			<content:encoded><![CDATA[<p>Здравствуйте, дорогие слушатели, сегодня в нашем подкасте вы узнаете о том как создать <s>красивый</s> стандартный индикатор загрузки в своем приложении... Ой, а что, никто не записывает?! Ну, ладно... тогда проговаривайте (можно про себя) текст и думайте что это подкаст. </p>
<span id="more-1121"></span>
<p style="color:white;">И нет, я не курил, просто настроение хорошее.</p>
<p>В общем решил показать массам как выглядит код моего <a href="http://mabp.kiev.ua/2009/09/05/pbank/">e-banking'a</a>. Но что-то меня берёт жадность (нету духа опенсорса) показывать именно код приложения, поэтому я тут по-быстрому сговнял классик, который показывает на экране кнопку при нажатии на которую вылазит алерт с вопросом да/нет, при нажатии на "да" вылазит прогрессбар и потом пропадает а при нажатии на "нет" - ничего не происходит.</p>

<p>Кстати, я уже скачал себе новую SDK 1.6. Так что можете сравнить вид эмуляторов. Ну и раз уж я заговорил о ней то надо сказать что наличие новых методов для работы с CDMA, я не оценил, зато заметил что починили <a href="http://mabp.kiev.ua/2009/09/14/android-first-bugs/">баг c URLConnection</a>, а это не может не радовать :).</p>

<pre><code class="java">
package ua.kiev.mabp;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

import java.util.Random;

public class MyActivity extends Activity {

    // список диалогов
    private static final int CONFIRM = 1;
    private static final int PROGRESS = 2;

    // счетчик вызовов
    private int counter;

    /**
     * Метод вызывается один раз при создании активности
     *
     * @param savedInstanceState предыдущее состояние активности
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Создаем кнопку
        Button button = new Button(this);
        button.setText("click me!");
        // вешаем на неё листенер
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // котрый покажет диалог CONFIRM
                showDialog(CONFIRM);
            }
        });
        // сетим кнопку в основной лайаут
        setContentView(button, new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT));
    }

    /**
     * Метод вызывается один раз на каждый диалог
     *
     * @param id номер диалога онисан в начале класса
     * @return диалог
     */
    @Override
    protected Dialog onCreateDialog(int id) {
        super.onCreateDialog(id);
        switch (id) {
            case CONFIRM:
                // новый лайаут для диалога
                LinearLayout confirmView = new LinearLayout(this);

                // создаем диалог с параметрами и двумя кнопками
                return new AlertDialog.Builder(MyActivity.this)
                        .setIcon(android.R.drawable.ic_dialog_info)
                        .setView(confirmView)
                        .setTitle("Title")
                        .setMessage("Message")
                        // положительная кнопка с листенером который показывает диалог PROGRESS
                        .setPositiveButton("Click me!", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int whichButton) {
                                // запустит новый диалог загрузки
                                showDialog(PROGRESS);
                                // в новом потоке
                                new Thread(new Runnable() {
                                    public void run() {
                                        // запустит фоновую процедуру
                                        wasteMyTime();
                                        // по завершении которой в основном потоке
                                        MyActivity.this.runOnUiThread(new Runnable() {
                                            public void run() {
                                                // диплог загрузки закроется
                                                dismissDialog(PROGRESS);
                                            }
                                        });
                                    }
                                }).start();
                            }
                        })
                        // отрицатильная кнопка просто скроет диалог
                        .setNegativeButton("Cancel", null)
                        .create();
            case PROGRESS:
                // Диалог загрузки
                ProgressDialog dialog = new ProgressDialog(this);
                dialog.setTitle("Please, waite...");
                dialog.setMessage("Dummy message about loading...");
                // без процентов
                dialog.setIndeterminate(true);
                // можно закрыть кнопкой телефона
                dialog.setCancelable(true);
                return dialog;
            default:
                return null;
        }
    }

    /**
     * Метод вызывается каждый раз перед появлением диалога
     *
     * @param id     номер появляющегося диалога
     * @param dialog сам диалог
     */
    @Override
    protected void onPrepareDialog(int id, Dialog dialog) {
        super.onPrepareDialog(id, dialog);
        switch (id) {
            case CONFIRM:
                ((AlertDialog) dialog).setMessage("Этот диалог был вызван " + (++counter) + " раз");
                break;
            default:
                break;
        }
    }

    /**
     * Метод просто тратит время
     */
    public static void wasteMyTime() {
        Random random = new Random();
        for (int i = 0; i &lt; 10000; i++) {
            random.nextGaussian();
        }
    }
}

</code></pre>

<p>Вот так это выглядит в новом красивом но не очень удобном (я уже привык к прошлому) эмуляторе.</p>
<div style="text-align:center"><img src="/content/img/pbank/dialog.jpg" alt="modal dialog example"/></div>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/09/16/androids-modal-dialogs-example/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Android: первые грабли</title>
		<link>http://mabp.kiev.ua/2009/09/14/android-first-bugs/</link>
		<comments>http://mabp.kiev.ua/2009/09/14/android-first-bugs/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 17:24:59 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[pbank]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1119</guid>
		<description><![CDATA[На русском очень мало документации по андроиду поэтому я немного попишу на эту тему. Как вы уже знаете взялся я настругать на коленке e-banking. Первых два дня дико тупил и читал доки. На самом деле все интуитивно просто как в Убунте ;) Но как и везде есть грабли. Об одних я и хочу тут написать. [...]]]></description>
			<content:encoded><![CDATA[<p>На русском очень мало документации по андроиду поэтому я немного попишу на эту тему.</p>

<p>Как вы уже знаете взялся я настругать на коленке <a href="http://mabp.kiev.ua/2009/09/05/pbank/">e-banking</a>. Первых два дня дико тупил и читал доки. На самом деле все интуитивно просто как в Убунте ;) Но как и везде есть грабли. Об одних я и хочу тут написать.</p>
<span id="more-1119"></span>
<p>Для работы приложению надо по HTTPS связываться с сервером и получать xml. Для соединения я выбрал самый простой способ и использовал объект URLConnection</p>

<pre><code class="java">
URL url = new URL("https://liqpay.com/?do=api_xml");
URLConnection conn = url.openConnection();
</code></pre>

<p>Все было хорошо пока я не начал отлаживать второй проход по сценарию, то есть первый раз перевели денег и снова возвращаемся на исходную страницу для второго перевода. Тут началв вылазить ошибка "Приложение выполнило недопустимую операцию и будет закрыто", или как-то так.</p>

<p>Я сначала подумал ошибка где-то в потоках, потому что я первый раз использовал потоки вообще. Стал смотреть вроде с потоками все ок. Посмотрел может я не закрыл прошлое соединение, оно закрывается после закрытия потока. В результате добрался до того что поток изначально получается закрытым. И никакого null-pointer или другого исключения не вываливается.</p>

<p>Долго ли коротко ли гуглил и нашел что не у одного меня такая проблема. Воркэраунд был простой, открывается каждое нечетное соединение то есть 1,3,5... Но это естественно не дело. Стал искать как делают реальные пацаны. а реальные пацаны оказывается использую класс DefaultHttpClient с которым все ок. Вот сейчас проделал пару тестов все действительно нормально пашет, собираюсь внести изменения в проект. А пока побалую вас рабочим кодом, мож кому пригодится.</p>

<pre><code class="java">
String xmlContentToSend = "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;&lt;request&gt;&lt;/request&gt;";

DefaultHttpClient httpClient = new DefaultHttpClient();
// some weird header
// http://doookstechstuff.blogspot.com/2009/06/switching-off-expect-100-continue.html
httpClient.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
// Using POST or    new HttpGet
HttpPost httpPost = new HttpPost("https://liqpay.com/?do=api_xml");
// some headers 
httpPost.addHeader("Accept", "text/xml");
httpPost.addHeader("Content-Type", "application/xml");

try {
    // convert xml to StringEntity
    StringEntity entity = new StringEntity(xmlContentToSend, HTTP.UTF_8);
    entity.setContentType("application/xml");
    httpPost.setEntity(entity);

    // or use NameValuePair 
    /*
    List&lt;NameValuePair&gt; params = new ArrayList&lt;NameValuePair&gt;();
    params.add(new BasicNameValuePair("name", "value"));
    httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
    */

    // execute is a blocking call, it's best to call this code in a thread separate from the ui's
    HttpResponse response = httpClient.execute(httpPost);

    InputStream stream = response.getEntity().getContent();
}
catch (Exception ex) {
    // logging
}
</code></pre>

]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/09/14/android-first-bugs/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PBank: передача денег</title>
		<link>http://mabp.kiev.ua/2009/09/12/pbank-money-sending/</link>
		<comments>http://mabp.kiev.ua/2009/09/12/pbank-money-sending/#comments</comments>
		<pubDate>Sat, 12 Sep 2009 13:34:53 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[pbank]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1117</guid>
		<description><![CDATA[Я еще в четверг обещал выложить свежие скриншоты, но доделал только сегодня. Это было связано с ошибками в API и с какими-то невнятными косяками в Android'e. О первом я уже писал а о втором еще напишу. Итак вот что у меня получилось: Пока писал все это поднял кучу экспириенса, на самом деле все очень просто [...]]]></description>
			<content:encoded><![CDATA[<p>Я еще в четверг обещал выложить свежие скриншоты, но доделал только сегодня. Это было связано с ошибками в <a href="https://liqpay.com/?do=pages&#038;p=api" rel="nofollow external">API</a> и с какими-то невнятными косяками в Android'e. О первом я <a href="http://mabp.kiev.ua/2009/09/11/banks-mistakes/">уже писал</a> а о втором еще напишу. Итак вот что у меня получилось:</p>
<span id="more-1117"></span>
<div style="text-align:center"><img src="/content/img/pbank/send.jpg" alt="отправка денег"></div>
<p>Пока писал все это поднял кучу экспириенса, на самом деле все очень просто и большинство проблем возникает только потому что нету некоторых пакетов из стандартного JDK. Я думаю можно просуммировать на что ушло больше всего времени.</p>
<ul>
<li>Настройка соединения через прокси не увенчалась успехом вообще, так же как и настройка эмулятора. То есть с работы я так и не сделал ни одной транзакции, рисовал только интерфейс. Кто знает как настроить сие чудо, милости прошу в каменты.</li>
<li>С дуру очень много времени ушло на отпечаток SHA1, ну не додумался я что там нужна кодировка 8859_1, ну бывает.</li>
<li>Еще много времени ушло на поиск того как из org.w3c.dom.Document сделать java.lang.String. В Android SDK не включен нужный пакет поэтому в конце концов пришлось писать свой метод.</li>
<li>И сегодня долго искал ответа на вопрос почему же нельзя открыть два https соединения подряд через URLConnection. Второе почему-то не открывается и не бросает эксепшн. А третье снова открывается.</li>
<li>И еще самое главное но еще не тронутое: надо найти как хранить структуры данных, либо сериализировать и хранить в файлах либо в sqlite3 вобщем надо думать.</li>
</ul>
<p>Не думайте что я остановлюсь на достигнутом у меня в планах реализация хранения и просмотра выполненных транзакций, полное переписывание баланса (соответственно полученных с тех пор знаний) и тюнинг тока что написанной отправки денег.</p>

]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/09/12/pbank-money-sending/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Android - первые шаги</title>
		<link>http://mabp.kiev.ua/2009/09/07/android-first-steps/</link>
		<comments>http://mabp.kiev.ua/2009/09/07/android-first-steps/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 12:00:30 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[android]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1292</guid>
		<description><![CDATA[Перепост с форума, да еще и задним числом (через год). Кто видел кто нет, а я на выходных наваял вот такую штуку. Подробностей конкретно этой программы не будет а в общих чертах расскажу. Создаем новый проект и получаем дерево папок и пару файлов \ + AndroidManifest.xml \gen\ua\kiev\mabp + R.java \res\layout + main.xml \res\drawable + icon.png [...]]]></description>
			<content:encoded><![CDATA[<p>Перепост с <a href="http://pyha.ru/forum/topic/3371.0" rel="nofollow external">форума</a>, да еще и задним числом (через год).</p>

<span id="more-1292"></span>

<p>Кто видел кто нет, а я на выходных наваял вот такую <a href="http://mabp.kiev.ua/2009/09/05/pbank/">штуку</a>.</p>


<p>Подробностей конкретно этой программы не будет а в общих чертах расскажу.</p>

<p>Создаем новый проект и получаем дерево папок и пару файлов</p>

<blockquote>
\
+ AndroidManifest.xml
\gen\ua\kiev\mabp
+ R.java
\res\layout
+ main.xml
\res\drawable
+ icon.png
\res\values
+ strings.xml
\src\ua\kiev\mabp
+ MyActivity.java
</blockquote>

<p>Поехали по порядку</p>
<p><strong>AndroidManifest.xml</strong> - дескриптор развертывания, тоже самое что web.xml для J2 Enterprise Edition , для тех кто не в курсе андроид использует J2 Micro Edition (upd уже давно нет)</p>

<p>Структура фала</p>
<pre><code class="xml">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ua.kiev.mabp"&gt;
    &lt;application android:icon="@drawable/icon" android:label="tests"&gt;
        &lt;activity android:name="MyActivity" android:label="PBank"&gt;
            &lt;intent-filter&gt;
                &lt;action android:name="android.intent.action.MAIN"/&gt;
                &lt;category android:name="android.intent.category.LAUNCHER"/&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;
    &lt;/application&gt;
    &lt;uses-permission android:name="android.permission.INTERNET"&gt;&lt;/uses-permission&gt;
&lt;/manifest&gt;
</code></pre>

<ul>
<li>package="ua.kiev.mabp" - пакет приложения</li>
<li>android:label="tests" - название приложения</li>
<li>android:name="MyActivity" - запускаймая активность (может быть несколько)</li>
<li>android:label="PBank" - заголовок активности</li>
<li>android:name="android.intent.action.MAIN" - главная активность приложения</li>
<li>android:name="android.intent.category.LAUNCHER" - может запускатся из менюшки</li>
<li>android:name="android.permission.INTERNET" - приложение может выходить в интернет (есть разные разрешения например на получение SMS или доступ к SD)</li>
</ul>

<p><strong>R.java</strong> Генерируемый файл, руками его править бесполезно потому что он перезаписывается при каждой компиляции
Файл содержит класс R(esources) в котором хранятся ссылки на все ресурсы, более подробно чуть ниже</p>

<p>В папке <strong>res</strong> содержит ресурсы нескольких типов, все они при компиляции сохраняются в класс R, папка разделена на ресурсы разного типа<p>
<ul>
<li>drawable - картинки</li>
<li>layout - слои</li>
<li>values - переменные</li>
<li><a href="http://lampwww.epfl.ch/~linuxsoft/android/android-m3-rc20a/docs/reference/available-resources.html" rel="nofollow external">есть еще (доки)</a></li>
</ul>

<p>Думаю про картинки объяснять не надо. единственно что доступ к ним происходит вот так - R.drawable.image_name_without_extention</p>

<p><strong>main.xml</strong> Слои хранят в себе разметку страниц по умолчанию</p>

<pre><code class="xml">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"&gt;

    &lt;ListView
 	android:id="@id/android:list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
 	android:drawSelectorOnTop="false"/&gt;
&lt;/LinearLayout&gt;
</code></pre>


<p>Все начинается с определения LinearLayout</p>
<ul>
<li>android:orientation="vertical" - вертикальное положение (как альбомная страница)</li>
<li>android:layout_width="fill_parent" - заполняет весь экран в ширину</li>
<li>android:layout_height="fill_parent" - заполняет весь экран в высоту</li>
</ul>

<p>Основной экран содержит список ListView</p>
<ul>
<li>android:id="@id/android:list" - список доступен в ресурсах через ID R.id.list</li>
<li>android:layout_width="fill_parent" - заполняет родительский объект по ширене</li>
<li>android:layout_height="wrap_content" - имеет высоту содержимого</li>
<li>android:drawSelectorOnTop="false" - первый элемент списка не подсвечен</li>
</ul>


<p>еще пример <strong>row.xml</strong></p>
<pre><code class="xml">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/vw1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"&gt;    

    &lt;ImageView android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/&gt;

    &lt;LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"&gt;

        &lt;TextView android:id="@+id/text"
            android:textSize="12sp"
            android:textStyle="bold"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"/&gt;

    &lt;/LinearLayout&gt;
&lt;/LinearLayout&gt;
</code></pre>
<p>это ряд с списке</p>

<p><strong>strings.xml</strong> Хранит в себе локализацию. 
если создать папку values-ru то из нее будет браться русская локаль</p>

<p>пример файла</p>
<pre><code class="xml">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;resources&gt;
    &lt;string name="first"&gt;Первая строка&lt;/string&gt;
    &lt;string name="second"&gt;Вторая строка&lt;/string&gt;
&lt;/resources&gt;
</code></pre>

<p>Cтроки доступны через объект ресурсов R.string.first или через слои android:text="@string/first". Чтобы преобразовать ресурс в локализированную строку делаем так context.getString(R.string.first)</p>

<p>переходим к приложению <strong>MyActivity.java</strong></p>

<p>пример класса</p>
<pre><code class="java">
public class ResourceExplorer extends ListActivity{ 

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // список который сождержит информацию
        List&lt;Map&lt;String, Object&gt;&gt; resourceNames = new ArrayList&lt;Map&lt;String, Object&gt;&gt;();

        // Объект рядя
        Map&lt;String, Object&gt; data;

        // захардкодженые номеря взятые отсюда
        // http://code.google.com/android/reference/android/R.drawable.html
        for ( int idx = 17301504; idx &lt;= 17301655; idx++ ){
            data = new HashMap&lt;String, Object&gt;();

            try {
                String stg = Resources.getSystem().getResourceName(idx);
                data.put("text", stg );
                data.put("img", idx );
                resourceNames.add(data);
            }

            catch (Resources.NotFoundException e) {
                // игнорируем
            }
        }

        SimpleAdapter notes = new SimpleAdapter(
            this,
            resourceNames,
            R.layout.row,
            new String[] { "text", "img" },
            new int[] { R.id.text, R.id.img } );

        setListAdapter(notes);
    }
}
</code></pre>

<p>В результате получаем приложение которое отображает все картинки которые по умолчанию есть в эмуляторе</p>

<img src="http://mabp.kiev.ua/content/img/android_images.png" alt=""/>


<p>this is android, have a fun :)</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/09/07/android-first-steps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PBank</title>
		<link>http://mabp.kiev.ua/2009/09/05/pbank/</link>
		<comments>http://mabp.kiev.ua/2009/09/05/pbank/#comments</comments>
		<pubDate>Sat, 05 Sep 2009 19:00:09 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[hate]]></category>
		<category><![CDATA[pbank]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1108</guid>
		<description><![CDATA[Несмотря на то что я люто-бешено ненавижу Приват Банк за их бюрократию и прочую хуйню многократно описаную на просторах интернета, я тут взялся написать одно приложение для них. Ну не дял них а для себя, ну не для себя а на продажу... но взялся написать и пишу. Смысл вот в чем: на прошлой недели появилось [...]]]></description>
			<content:encoded><![CDATA[<p>Несмотря на то что я люто-бешено ненавижу Приват Банк за их бюрократию и прочую хуйню многократно описаную на просторах <a href="http://google.com" rel="nofollow external">интернета</a>, я тут взялся написать одно приложение для них.</p>
<span id="more-1108"></span>
<p>Ну не дял них а для себя, ну не для себя а на продажу... но взялся написать и пишу. Смысл вот в чем: на прошлой недели появилось вот такое забавное <a href="https://liqpay.com/">API</a>. По сути обычный клент-банк, ничего особенного. Единственное что появилось оно только на прошлой недели! Этим я и решил воспользоватся. У них есть родное приложение для iPhone, а я решил написать приложение для Android'a. С одной стороны реальный опыт писания под телефон с другой может даже что-то заработаю. В результате двух дней работы моё приложение умеет показывать главную менюшку, имеет настройку мерчанта, и может показывать баланс. Пока все но это еще даже на альфу не претендует.</p>
<p>Вот пара скриншотов для затравки.</p>
<div style="text-align:center"><img src="/content/img/pbank/main.jpg" alt="Главное меню" /></div>
<div style="text-align:center"><img src="/content/img/pbank/preference.jpg" alt="Настройки мерчанта" /></div>
<div style="text-align:center"><img src="/content/img/pbank/balance.jpg" alt="Баланс" /></div>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/09/05/pbank/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Cascading comboboxes on GWT, ExtGWT, ExtJS и MySQL</title>
		<link>http://mabp.kiev.ua/2009/06/12/cascading-comboboxes-on-gwt-extgwt-extjs-and-mysql/</link>
		<comments>http://mabp.kiev.ua/2009/06/12/cascading-comboboxes-on-gwt-extgwt-extjs-and-mysql/#comments</comments>
		<pubDate>Fri, 12 Jun 2009 12:27:44 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[combobox]]></category>
		<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[GWT]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1078</guid>
		<description><![CDATA[Я уже давно грозился выложить свежую версию каскадных выпадающих списков на GWT 1.5.3, ExtGWT 1.2, ExtJS 2.2.1 и MySQL 5.1. Код был написан еще в конце апреля, но меня все ломало написать к нему текстовку. А сейчас когда на подходе выход ExtGWT 2.0 и ExtJS 3.0 я решил пошевелиться и накрапать небольшое описалово. Действительно небольшое [...]]]></description>
			<content:encoded><![CDATA[<p>Я уже давно грозился выложить свежую версию каскадных выпадающих списков на GWT 1.5.3, ExtGWT 1.2, ExtJS 2.2.1 и MySQL 5.1. Код был написан еще в конце апреля, но меня все ломало написать к нему текстовку. А сейчас когда на подходе выход ExtGWT 2.0 и ExtJS 3.0 я решил пошевелиться и накрапать небольшое описалово. Действительно небольшое потому что все настройки я уже описал в <a href="http://mabp.kiev.ua/2009/04/12/gwt-extjs-connecting-to-mysql/">предыдущей статье</a>, так что тут будут описаны только изменения.</p>
<span id="more-1078"></span>
<p>Для начала опишу изменения в БД, я ее полностью поменял. Теперь у нас вместо машинок будут города и страны, но смысл тот же.</p>
<pre><code class="sql">
DROP TABLE IF EXISTS `city`;
CREATE TABLE IF NOT EXISTS `city` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `parent` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=50 ;

INSERT INTO `city` (`id`, `name`, `parent`) VALUES
(1, 'Kiev', 1),
(2, 'Lviv', 1),
(3, 'Odesa', 1),
(4, 'Kharkov', 1),
(5, 'Lugansk', 1),
(6, 'Zaporizhzhia', 1),
(7, 'Mariupol', 1),
(8, 'Moskow', 2),
(9, 'Volgograd', 2),
(10, 'Samara', 2),
(11, 'Kazan', 2),
(12, 'Perm', 2),
(13, 'Eburg', 2),
(14, 'Chelyabinsk', 2),
(15, 'Minsk', 3),
(16, 'Homel', 3),
(17, 'Grodno', 3),
(18, 'Vitebsk', 3),
(19, 'Le Havre', 4),
(20, 'Rennes', 4),
(21, 'Nantes', 4),
(22, 'Berdeaux', 4),
(23, 'Toulouse', 4),
(24, 'Montpellier', 4),
(25, 'Marseille', 4),
(26, 'Lyon', 4),
(27, 'Paris', 4),
(28, 'Reims am Main', 5),
(29, 'Berlin', 5),
(30, 'Bremen', 5),
(31, 'Hannover', 5),
(32, 'Hamburg', 5),
(33, 'Frankfurt', 5),
(34, 'Munchen', 5),
(35, 'Strasbourg', 5),
(36, 'Milano', 6),
(37, 'Bologna', 6),
(38, 'Genova', 6),
(39, 'Roma', 6),
(40, 'Napoli', 6),
(41, 'Palermo', 6),
(42, 'London', 7),
(43, 'Bristol', 7),
(44, 'Birmingham', 7),
(45, 'Liverpool', 7),
(46, 'Manchester', 7),
(47, 'Edinburg', 7),
(48, 'Glasgow', 7),
(49, 'Belfast', 7);

DROP TABLE IF EXISTS `country`;
CREATE TABLE IF NOT EXISTS `country` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;

INSERT INTO `country` (`id`, `name`) VALUES
(1, 'Ukrain'),
(2, 'Russia'),
(3, 'Belarus'),
(4, 'France'),
(5, 'German'),
(6, 'Italia'),
(7, 'Uniited Kingdom');
</code></pre>

<p>И EntryPoint у нас на этот раз будет по проще. В нем не будет кучи виджетов, а только один.</p>

<pre><code class="java">
package ua.kiev.mabp.client;

import com.extjs.gxt.ui.client.Events;
import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Viewport;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;
import ua.kiev.mabp.client.utility.CityToCountryUtility;
import ua.kiev.mabp.client.widget.CitySuggestBox;
import ua.kiev.mabp.client.widget.CountrySuggestBox;

public class HelloWorld implements EntryPoint {

    public void onModuleLoad() {

        // создаем рабочую область
        ContentPanel contentPanel = new ContentPanel();
        contentPanel.setLayout(new FitLayout());
        contentPanel.setHeading("Cascading combobox");

        // и новый комбобокс для стран
        CountrySuggestBox countrySuggestBox = new CountrySuggestBox();
        countrySuggestBox.setDisplayField("name");
        countrySuggestBox.setFieldLabel("Country");

        // вот тут вся магия
        CityToCountryUtility.getInstance().setCountryComboBox(countrySuggestBox);

        // ну и листенер конечно
        countrySuggestBox.addListener(Events.SelectionChange, new Listener&lt;BaseEvent&gt;(){
            public void handleEvent(BaseEvent be) {
                CityToCountryUtility.getInstance().eraseCity();
            }
        });

        // новый комбобокс для городов
        CitySuggestBox citySuggestBox = new CitySuggestBox();
        citySuggestBox.setDisplayField("name");
        citySuggestBox.setFieldLabel("City");
        citySuggestBox.setForceSelection(false);

        // еще немного магии
        CityToCountryUtility.getInstance().setCityComboBox(citySuggestBox);

        // дальше манипуляции с отображением 
        FormPanel formPanel = new FormPanel();
        formPanel.setHeaderVisible(false);
        formPanel.add(countrySuggestBox);
        formPanel.add(citySuggestBox);

        contentPanel.add(formPanel);

        Viewport viewport = new Viewport();
        viewport.setLayout(new FlowLayout());
        viewport.setScrollMode(Scroll.AUTO);
        viewport.add(contentPanel);
        RootPanel.get().add(viewport);
    }
}
</code></pre>

<p>Тут интересны два, точнее три объекта, CountrySuggestBox, CitySuggestBox и CityToCountryUtility, но два практически одинаковые, поэтому я буду рассказывать только про больший.</p>
<pre><code class="java">
package ua.kiev.mabp.client.widget;

import com.extjs.gxt.ui.client.data.BasePagingLoadConfig;
import com.extjs.gxt.ui.client.data.BasePagingLoadResult;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.RpcProxy;
import ua.kiev.mabp.client.proxy.CitySuggestBoxRpcProxy;

/**
 * Created by IntelliJ IDEA.
 * User: CTAPbIu_MABP
 * Date: 16.04.2009
 * Time: 22:46:56
 */
public class CitySuggestBox&lt;D extends ModelData&gt; extends AbstractSuggestBox&lt;D&gt; {

    @Override
    protected RpcProxy&lt;BasePagingLoadConfig, BasePagingLoadResult&lt;D&gt;&gt; getRpcProxy() {
        return new CitySuggestBoxRpcProxy&lt;BasePagingLoadConfig, BasePagingLoadResult&lt;D&gt;&gt;();
    }
}
</code></pre>
<p>CitySuggestBox и CountrySuggestBox всеголишь обертки, поэтому показываю AbstractSuggestBox.</p>

<pre><code class="java">
package ua.kiev.mabp.client.widget;

import com.extjs.gxt.ui.client.data.*;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.google.gwt.user.client.Element;

/**
 * Created by IntelliJ IDEA.
 * User: CTAPbIu_MABP
 * Date: 16.04.2009
 * Time: 22:46:09
 */

public abstract class AbstractSuggestBox&lt;D extends ModelData&gt; extends ComboBox&lt;D&gt; {

    public AbstractSuggestBox() {
        RpcProxy&lt;BasePagingLoadConfig, BasePagingLoadResult&lt;D&gt;&gt; proxy = getRpcProxy();
        PagingLoader&lt;BasePagingLoadConfig&gt; bpl = new BasePagingLoader&lt;BasePagingLoadConfig, BasePagingLoadResult&lt;D&gt;&gt;(proxy);
        ListStore&lt;D&gt; store = new ListStore&lt;D&gt;(bpl);
        setStore(store);
        setTypeAhead(true);
        setForceSelection(true);
        setPageSize(5);
        setWidth("500px");
    }

    protected abstract RpcProxy&lt;BasePagingLoadConfig, BasePagingLoadResult&lt;D&gt;&gt; getRpcProxy();

    @Override
    protected void onRender(Element parent, int index) {
        setEditable(true);
        setTriggerAction(TriggerAction.QUERY);
        super.onRender(parent, index);
    }
}
</code></pre>

<p>Тут тоже практически ничего интересного - главное получить правильно параметризированый RpcProxy. Дальше дело техники. Прокси на самом деле тоже только обертка.</p>

<pre><code class="java">
package ua.kiev.mabp.client.proxy;

import com.extjs.gxt.ui.client.data.BasePagingLoadConfig;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.widget.Info;
import com.google.gwt.user.client.rpc.AsyncCallback;
import ua.kiev.mabp.client.HelloWorldService;
import ua.kiev.mabp.client.HelloWorldServiceAsync;
import ua.kiev.mabp.client.utility.CityToCountryUtility;

/**
 * Created by IntelliJ IDEA.
 * User: CTAPbIu_MABP
 * Date: 16.04.2009
 * Time: 22:51:48
 */
public class CitySuggestBoxRpcProxy&lt;C extends BasePagingLoadConfig, D&gt; extends RpcProxy&lt;C, D&gt; {

    final HelloWorldServiceAsync service = HelloWorldService.App.getInstance();

    @Override
    protected final void load(C loadConfig, final AsyncCallback&lt;D&gt; asyncCallback) {
        String parernt = CityToCountryUtility.getInstance().getParentForCity();
        loadConfig.getParams().put("parent", parernt);
        service.getCity(loadConfig, new AsyncCallback&lt;D&gt;() {
            public void onSuccess(D result) {
                Info.display("Success", "success");
                asyncCallback.onSuccess(result);
            }

            public void onFailure(Throwable caught) {
                Info.display("Failure", "fail");
                asyncCallback.onFailure(caught);
            }

        });
    }
}
</code></pre>

<p>Но только эта обертка для городов имеет две лишних строки (по сравнению с оберткой для стран) в которых происходит получение выбранной страны и подставления этого значения в параметры запроса. Для этого я использую класс CityToCountryUtility, который реализует паттерн Registry.</p>

<pre><code class="java">
package ua.kiev.mabp.client.utility;

import com.extjs.gxt.ui.client.data.ModelData;
import ua.kiev.mabp.client.widget.CitySuggestBox;
import ua.kiev.mabp.client.widget.CountrySuggestBox;

/**
 * Created by IntelliJ IDEA.
 * User: CTAPbIu_MABP
 * Date: 28.04.2009
 * Time: 15:20:29
 */
public class CityToCountryUtility {

    private static CityToCountryUtility manager;
    private CountrySuggestBox country;
    private CitySuggestBox city;

    private CityToCountryUtility() {

    }

    public static CityToCountryUtility getInstance() {
        if (manager == null) {
            manager = new CityToCountryUtility();
        }
        return manager;
    }

    public void setCountryComboBox(CountrySuggestBox country) {
        this.country = country;
    }

    public void eraseCity() {
        //city.clearSelections();
        city.getStore().removeAll();
    }

    public void setCityComboBox(CitySuggestBox city) {
        this.city = city;
    }

    public String getParentForCity() {
        ModelData value = country.getValue();
        return value != null ? (String) value.get("abbr") : "";
    }
}
</code></pre>

<p>Пожалуй это все что надо для того, чтобы сделать каскадные комбобоксы. Повторюсь что как настроить мавен, какие либы подключать и как замапить комбобокс к базе данных описано в <a href="http://mabp.kiev.ua/2009/04/12/gwt-extjs-connecting-to-mysql/">предыдущей статье</a>. Осталось только прикрепить <a href="http://mabp.kiev.ua/content/source/cascading_combobox.rar">проект</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/06/12/cascading-comboboxes-on-gwt-extgwt-extjs-and-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

