<?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>narsereg&#039;s blog</title>
	<atom:link href="http://narsereg.ru/feed/" rel="self" type="application/rss+xml" />
	<link>http://narsereg.ru</link>
	<description>блог narsereg&#039;а о Java и остальном</description>
	<lastBuildDate>Tue, 06 Dec 2011 12:50:00 +0000</lastBuildDate>
	<language>ru</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Фон в Andoid приложении</title>
		<link>http://narsereg.ru/2011/12/06/fon-v-android-prilozhenii/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=fon-v-android-prilozhenii</link>
		<comments>http://narsereg.ru/2011/12/06/fon-v-android-prilozhenii/#comments</comments>
		<pubDate>Tue, 06 Dec 2011 12:50:00 +0000</pubDate>
		<dc:creator>narsereg</dc:creator>
				<category><![CDATA[Без рубрики]]></category>

		<guid isPermaLink="false">http://narsereg.ru/?p=110</guid>
		<description><![CDATA[Все-таки, дизайн – дело важное, к тому же в мобильных приложениях, где конкуренция крайне велика. И начинать приходится с малого. Буковки там, кнопочки и фон приложения. Собственно про фон я сейчас и расскажу. Сделать фон черным или зеленым не сложно. &#8230; <a href="http://narsereg.ru/2011/12/06/fon-v-android-prilozhenii/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Все-таки, дизайн – дело важное, к тому же в мобильных приложениях, где конкуренция крайне велика. И начинать приходится с малого. Буковки там, кнопочки и фон приложения. Собственно про фон я сейчас и расскажу.<br />
Сделать фон черным или зеленым не сложно. Достаточно указать цвет xml файле нужного intent:</p>
<pre>&lt;TableLayout android:background="#000000" /&gt;</pre>
<p>Теперь задачка посложнее – сделать фоновый рисунок. Ну не сильно посложнее, если быть честным. Первое что мы делаем – это указываем откуда брать информацию по рисунку:</p>
<pre>&lt;TableLayout android:background="@drawable/background" /&gt;</pre>
<p>Теперь создаем в папке res новую папку с названием drawable, а в ней файл background.xml, который наполняем такими данными:</p>
<pre>&lt;bitmap xmlns:android=http://schemas.android.com/apk/res/android android:src="@drawable/backgroundpicture" /&gt;</pre>
<p>Главное не забыть положить в папку drawable само изображение и обозвать его backgroundpicture.png.<br />
Запускаем эмулятор и видим, что получили мы именно то, что хотели.<br />
А теперь представим, что хотим мы не одну большую картинку положить, а размножить маленькую. Замостить, так сказать. Ну вот сейчас то как раз и начнется… ничего. Просто немного изменяем background.xml файл:</p>
<pre>&lt;bitmap xmlns:android=http://schemas.android.com/apk/res/android android:src="@drawable/backgroundpicture" android:tileMode="repeat" /&gt;</pre>
<p>Вот и все. Теперь наша маленькая картинка, повторенная бесконечное число раз создает фон программы. Не правда ли все элементарно?<br />
Ну и чтоб всем стало совсем все понятно скажу – в LinearLayout добавлять android:background нужно в том случае если вы хотите статически замощённый фон, а в</p>
<pre>&lt;ScrollView&gt;&lt;TableLayout android:background="@drawable/repeatline" / &gt;&lt;/ScrollView&gt; </pre>
<p>чтоб фон скролился вместе с текстом в программе.</p>
]]></content:encoded>
			<wfw:commentRss>http://narsereg.ru/2011/12/06/fon-v-android-prilozhenii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Парсим json с помощью json-simple</title>
		<link>http://narsereg.ru/2011/11/01/parse-json-with-json-simple/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=parse-json-with-json-simple</link>
		<comments>http://narsereg.ru/2011/11/01/parse-json-with-json-simple/#comments</comments>
		<pubDate>Tue, 01 Nov 2011 09:48:47 +0000</pubDate>
		<dc:creator>narsereg</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[json]]></category>

		<guid isPermaLink="false">http://narsereg.ru/?p=98</guid>
		<description><![CDATA[Потребовалось мне недавно распарсить небольшой JSON, взятый со стороннего сайта. Естественно java и естественно не хотелось заморачиваться больше необходимого. И я пошел в интернеты искать что-то, что устроит меня по обоим этим параметрам. Первая строчка при поиске через Google – &#8230; <a href="http://narsereg.ru/2011/11/01/parse-json-with-json-simple/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Потребовалось мне недавно распарсить небольшой JSON, взятый со стороннего сайта. Естественно java и естественно не хотелось заморачиваться больше необходимого. И я пошел в интернеты искать что-то, что устроит меня по обоим этим параметрам. Первая строчка при поиске через Google – json-simple. Чтобы не противоречить самому себе и не усложнять задачу <a title="json-simple DOwnload" href="http://code.google.com/p/json-simple/downloads/list" target="_blank">берем его</a> и подключаем к проекту.<br />
В кратком виде документ, получаемый мной от сервера выглядит так:</p>
<p><code>{<br />
&nbsp;"current_observation": {<br />
&nbsp;&nbsp;"weather":"Partly Cloudy",<br />
&nbsp;&nbsp;"temp_c":14,<br />
&nbsp;&nbsp;"relative_humidity":"72%",<br />
&nbsp;}<br />
}.</code></p>
<p>Все просто и понятно.<br />
Корнем всех добр json-simple является класс JSONParser, являющийся, как не трудно догадаться, парсером JSON документа.</p>
<pre>JSONParser jsonParser = new JSONParser();</pre>
<p>Теперь парсим JSON методом parse (оригинально, не правда ли?) и сохраняем его в json-simple объект JSONObject.</p>
<pre>JSONObject jsonObject = (JSONObject)jsonParser.parse(здесь_ваш_json);</pre>
<p>Ищем вхождение current_observation</p>
<pre>JSONObject jsonObserv = (JSONObject)jsonObject.get("current_observation");</pre>
<p>и получаем такой же объект но только не для корня JSON, а уже для него.<br />
Ну, а далее все тем же методом get() получаем значения ключей:</p>
<pre>Double temperature = Double.parseDouble((jsonObserv.get("temp_c").toString()));
String weatherType = jsonObserv.get("weather").toString();
Integer humidity = Integer.parseInt(jsonObserv.get("relative_humidity").toString().replace("%", ""));</pre>
<p>Вот, собственно, и все.<br />
Конечно, это был самый простой способ парсинга. Можно было делать это через Map’ы с итераторами, но, как вы помните, я искал именно простоты и удобства на неизменяемых по структуре документах.<br />
Если захочется посмотреть на примеры, то их есть <a title="Примеры json-simple" href="http://code.google.com/p/json-simple/wiki/DecodingExamples" target="_blank">у гугла</a>.<br />
Пользуйтесь на здоровье.</p>
]]></content:encoded>
			<wfw:commentRss>http://narsereg.ru/2011/11/01/parse-json-with-json-simple/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Установка Oracle XE 11g на Ubuntu под VirtualBox</title>
		<link>http://narsereg.ru/2011/09/16/install-oracle-xe-11g-on-ubuntu-on-virtualbox/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=install-oracle-xe-11g-on-ubuntu-on-virtualbox</link>
		<comments>http://narsereg.ru/2011/09/16/install-oracle-xe-11g-on-ubuntu-on-virtualbox/#comments</comments>
		<pubDate>Fri, 16 Sep 2011 06:18:25 +0000</pubDate>
		<dc:creator>narsereg</dc:creator>
				<category><![CDATA[БД]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[virtualbox]]></category>
		<category><![CDATA[бд]]></category>

		<guid isPermaLink="false">http://narsereg.ru/?p=88</guid>
		<description><![CDATA[Вчера половину дня потратил на то, чтобы запустить СУБД Oracle XE 11g на Ubuntu в VirtualBox. Тысячи нервных клеток головного мозга были уничтожены, но задача, наконец, выполнена. И чтобы с этим смогли справиться люди, не имеющие в багаже английского языка &#8230; <a href="http://narsereg.ru/2011/09/16/install-oracle-xe-11g-on-ubuntu-on-virtualbox/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Вчера половину дня потратил на то, чтобы запустить СУБД Oracle XE 11g на Ubuntu в VirtualBox. Тысячи нервных клеток головного мозга были уничтожены, но задача, наконец, выполнена. И чтобы с этим смогли справиться люди, не имеющие в багаже английского языка я решил написать в этот блог кратенькую инструкцию.<br />
Итак:<br />
Что нам понадобится<br />
VirtualBox &#8211; <a title="VirtualBox" href="http://www.virtualbox.org/wiki/Downloads" target="_blank">http://www.virtualbox.org/wiki/Downloads</a><br />
Ubuntu &#8211; <a title="Ubuntu" href="http://www.ubuntu.com/download/ubuntu/download" target="_blank">http://www.ubuntu.com/download/ubuntu/download</a> (берем x64, так как только для нее есть Express версия Oracle)<br />
Oracle Database Express Edition 11g Release 2 &#8211; <a title="Oracle XE 11g" href="http://www.oracle.com/technetwork/database/express-edition/downloads/index.html" target="_blank">http://www.oracle.com/technetwork/database/express-edition/downloads/index.html</a><br />
Oracle SQL Developer &#8211; <a title="SQL Developer" href="http://www.oracle.com/technetwork/developer-tools/sql-developer/downloads/index.html" target="_blank">http://www.oracle.com/technetwork/developer-tools/sql-developer/downloads/index.html</a> (не хотим же мы постоянно работать с SQL строками. GUI сильно упрощает жизнь)<span id="more-88"></span></p>
<p>Теперь поехали:<br />
1. 1. Устанавливаем Ubuntu в VirtualBox. Я думаю вы справитесь с этим и сами, так как процесс элементарен.<br />
2. Запускаем Терминал.<br />
3. Разрешаем себе ssh с рутовыми правами</p>
<pre>sudo apt-get install openssh-server
sudo passwd root</pre>
<p>4. Устанавливаем зависимости и необходимые библиотеки</p>
<pre>sudo apt-get install alien libaio1 unixodbc</pre>
<p>5. Устанавливаем минимальное значение swap, хотя я думаю вам хватит и того что есть по умолчанию при установке</p>
<pre>sudo dd if=/dev/zero of=/swapfile bs=1024 count=1048576
sudo mkswap /swapfile
sudo swapon /swapfile
sudo cp /etc/fstab /etc/fstab.orig</pre>
<p>Выполняем</p>
<pre>sudo nano /etc/fstab</pre>
<p>Добавляем в конец строку</p>
<pre>sudo echo '/swapfile swap swap defaults 0 0'</pre>
<p>6. Правим параметры ядра:</p>
<pre>sudo nano /etc/sysctl.d/60-oracle.conf</pre>
<p>и добавляем сюда следующие строки:</p>
<pre># Oracle 11g XE kernel parameters
fs.file-max=6815744
net.ipv4.ip_local_port_range=9000 65000
kernel.sem=250 32000 100 128
kernel.shmmax=536870912</pre>
<p>Проверить выполнение:</p>
<pre>sudo cat /etc/sysctl.d/60-oracle.conf</pre>
<p>Подгружаем новые параметры:</p>
<pre>sudo service procps start</pre>
<p>Проверить выполнение:</p>
<pre>sudo sysctl -q fs.file-max</pre>
<p>Должны получить fs.file-max = 6815744<br />
7. Создаем папку, в которую потом установим БД</p>
<pre>sudo mkdir /home/oracle-xe
sudo ln -s /home/oracle-xe /u01</pre>
<p>8. Переходим в папку где у вас лежит rpm с Oracle XE 11g и выполняем</p>
<pre>sudo unzip oracle-xe-11.2.0-1.0.x86_64.rpm.zip</pre>
<p> (или какая у вас там версия)</p>
<pre>sudo alien --to-deb —scripts oracle-xe-11.2.0-1.0.x86_64.rpm</pre>
<p> (преобразовываем rpm в deb)<br />
9. Из-за того, что инсталятор Red Hat использует /sbin/chkconfig, которого нет в Ubuntu, то сделаем финт ушами</p>
<pre>sudo nano /sbin/chkconfig</pre>
<p>и добавим в него следующее:</p>
<pre>#!/bin/bash
# Oracle 11gR2 XE installer chkconfig hack for Debian by Dude
file=/etc/init.d/oracle-xe
if [[ ! `tail -n1 $file | grep INIT` ]]; then
echo &gt;&gt; $file
echo '### BEGIN INIT INFO' &gt;&gt; $file
echo '# Provides:             OracleXE' &gt;&gt; $file
echo '# Required-Start:       $remote_fs $syslog' &gt;&gt; $file
echo '# Required-Stop:        $remote_fs $syslog' &gt;&gt; $file
echo '# Default-Start:        2 3 4 5' &gt;&gt; $file
echo '# Default-Stop:         0 1 6' &gt;&gt; $file
echo '# Short-Description:    Oracle 11g Express Edition' &gt;&gt; $file
echo '### END INIT INFO' &gt;&gt; $file
fi
update-rc.d oracle-xe defaults 80 01</pre>
<p>после чего дадим привилегии на выполнение</p>
<pre>sudo chmod 755 /sbin/chkconfig</pre>
<p>10. Устанавливаем свеженький deb</p>
<pre>sudo dpkg --install ./oracle-xe_11.2.0-2_amd64.deb
/etc/init.d/oracle-xe configure</pre>
<p>Не советую использовать стандартный 8080 порт — слишком много на него претендентов всегда. Я себе поставил 8082.<br />
11. Удаляем /sbin/chkconfig</p>
<pre>sudo rm /sbin/chkconfig</pre>
<p>12. Изменяем пользователя oracle</p>
<pre>sudo /etc/init.d/oracle-xe stop
sudo kill -9 `ps -ef | grep oracle | grep -v grep | awk '{print $2}'`
sudo userdel oracle
sudo useradd -s /bin/bash -G dba -g dba -m oracle
sudo passwd oracle</pre>
<p>13. Добавляем необходимые environment variables, которые будут подгружаться при любом логине oracle в систему:</p>
<pre>sudo nano /home/oracle/.bashrc</pre>
<p>и добавляем<br />
&#8216;. /home/oracle-xe/app/oracle/product/11.2.0/xe/bin/oracle_env.sh&#8217;<br />
Сразу же добавим сюда ORACLE_HOME:<br />
ORACLE_HOME=/home/oracle-xe/app/oracle/product/11.2.0/xe<br />
export ORACLE_HOME<br />
14. Разрешим sudo для пользователя oracle</p>
<pre>usermod -G admin oracle</pre>
<p>Все, Oracle XE работает. (Должен по крайней мере).<br />
15. Займемся SQL Developer<br />
Переходим в папку с rpm и выполняем</p>
<pre>sudo alien --to-deb —scripts sqldeveloper-3.0.04.34-1.noarch.rpm</pre>
<p>Ждем&#8230;<br />
16. Устанавливем готовый пакет</p>
<pre>sudo dpkg --install ./sqldeveloper_3.0.04.34-2_all.deb</pre>
<p>17. Выполняем</p>
<pre>sudo /opt/sqldeveloper/sqldeveloper/bin/sqldeveloper.conf</pre>
<p>и добавляем в него следующие строки:<br />
AddVMOption -Duser.language=en<br />
AddVMOption -Duser.region=us<br />
18. PROFIT&#8230;<br />
Удачи в разработке. А если что-то не получится — жду комментариев.</p>
]]></content:encoded>
			<wfw:commentRss>http://narsereg.ru/2011/09/16/install-oracle-xe-11g-on-ubuntu-on-virtualbox/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Стар(та)пер</title>
		<link>http://narsereg.ru/2011/08/15/startaper/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=startaper</link>
		<comments>http://narsereg.ru/2011/08/15/startaper/#comments</comments>
		<pubDate>Mon, 15 Aug 2011 18:30:03 +0000</pubDate>
		<dc:creator>narsereg</dc:creator>
				<category><![CDATA[Книги]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[Guy Kawasaki]]></category>
		<category><![CDATA[startup]]></category>

		<guid isPermaLink="false">http://narsereg.ru/?p=83</guid>
		<description><![CDATA[Только что отложил в стопку прочитанных книг еще одну. Она хоть и не связана с Java или программированием, все же с большей вероятностью тематически попадает в этот блог, чем в мой Google+ бложек. Я говорю о книге Гая Кавасаки &#8211; &#8230; <a href="http://narsereg.ru/2011/08/15/startaper/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Только что отложил в стопку прочитанных книг еще одну. Она хоть и не связана с Java или программированием, все же с большей вероятностью тематически попадает в этот блог, чем в мой <a href="http://plus.google.com/100166798487490970650" target="_blank">Google+ бложек</a>.</p>
<p><a href="http://narsereg.ru/wp-content/uploads/2011/08/755104.jpg"><img class="alignleft size-full wp-image-84" title="755104" src="http://narsereg.ru/wp-content/uploads/2011/08/755104.jpg" alt="" width="150" height="211" /></a>Я говорю о книге Гая Кавасаки &#8211; Стартап. 11 мастер-классов от экс-евангелиста Apple и самого дерзкого венчурного капиталиста Кремниевой долины.</p>
<p>Сам Кавасаки занимается продвижением различных стартапов и зарабатывает этим (насколько я могу судить) неплохо. Но считать чужие деньги не стоит &#8211; лучше читать чужие книги. А книга эта очень полезная для любого человека, который хочет профессионально заниматься бизнесом. Нет, это не опечатка &#8211; не стартаперством, а любым бизнесом, так как законы у всей индустрии зарабатывания денег примерно одинаковы.</p>
<p>В книге вы получите множество советов о начале и раскрутке вашего собственного предприятия и сможете почерпнуть немало информации о том, как понять, что пора открывать новый. Гай рассказывает о собственном опыте наема и увольнения персонала, о работе с юристами и маркетологами, партнерами и конкурентами. Это все подается в легкой манере, без занудства и навязчивости.</p>
<p>Но раскрутка бренда и наем персонала &#8211; далеко не все темы, которые должны волновать настоящего профессионального предпринимателя. Очень большую долю успеха Гай Кавасаки отдает карме, то есть отношению окружающего мира к вам, как реакцию на ваши собственные дела. Все время, пока вы читаете, он твердит вам одно и тоже &#8211; относитесь к миру так, как вы хотите, чтобы мир относился к вам. Помогайте людям, не врите, слушайте и отвечайте, и тогда вы получите друзей и помощников, которые никогда вам не откажут.</p>
<p>Пересказывать все то, что вы почерпнете из этого небольшого томика я не буду, да и не смогу &#8211; не тот жанр, но могу сказать, что если вы мечтаете стать владельцем собственной (скорее, высокотехнологичной) фирмы &#8211; вы обязаны прочитать книгу. Не потому, что ВСЕ что тут написано вам ОБЯЗАТЕЛЬНО пригодится; совершенно не обязательно (мы, как минимум, живем в условиях совсем другой страны и общества), но скорее, потому, что это &#8211; бизнес-биография человека, верящего в принцип &laquo;возмездия&raquo; за все хорошее и при этом добившегося немалого успеха обязательно подтолкнет вас к верным шагам в будущем.</p>
]]></content:encoded>
			<wfw:commentRss>http://narsereg.ru/2011/08/15/startaper/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OhYeah!</title>
		<link>http://narsereg.ru/2011/08/10/ohyeah/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ohyeah</link>
		<comments>http://narsereg.ru/2011/08/10/ohyeah/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 08:19:23 +0000</pubDate>
		<dc:creator>narsereg</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://narsereg.ru/?p=79</guid>
		<description><![CDATA[Недавно написал новую программу под Android, про которую не мог сказать здесь, так как в то время narsereg.ru лежал в дауне, а потом, как-то руки не доходили. И вот появилось немного времени и энтузиазма для написания небольшого поста. Ну, для &#8230; <a href="http://narsereg.ru/2011/08/10/ohyeah/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Недавно написал новую программу под Android, про которую не мог сказать здесь, так как в то время <a title="narsereg.ru" href="http://narsereg.ru">narsereg.ru</a> лежал в дауне, а потом, как-то руки не доходили. И вот появилось немного времени и энтузиазма для написания небольшого поста.</p>
<p>Ну, для начала, тема программы &#8211; это приложение, которое напоминает вам о теме разговора с человеком, который был недоступен до этого. Например, он или вы находитесь в полете или в страшно дорогом роуминге и не можете поговорить с партнером по бизнесу или любым другим человеком. В программе делается заметка, которая отражается на экране в тот момент, когда устанавливается связь с нужным абонентом. Звонок может быть, как исходящий, так и входящий.</p>
<p>Все очень просто &#8211; никаких заморочек. Запускаете программу -&gt; Выбираете контакт -&gt; Вводите тему для разговора -&gt; Сохраняете. При начале разговора с нужным абонентом получаете сообщение на экране.</p>
<p>Программа называется OhYeah!, как вскрик, когда англоязычанин вспоминает о чем-то &#8211; аналог российского АхДа! А вот и ссыль на нее &#8211; <a href="http://market.android.com/details?id=com.narsereg.ohyeah">https://market.android.com/details?id=com.narsereg.ohyeah</a></p>
<p>А для любителей QR:</p>
<p><img class="alignnone" title="QR OhYeah!" src="http://qrcode.kaywa.com/img.php?s=8&amp;d=https%3A%2F%2Fmarket.android.com%2Fdetails%3Fid%3Dcom.narsereg.ohyeah" alt="" width="312" height="312" /></p>
]]></content:encoded>
			<wfw:commentRss>http://narsereg.ru/2011/08/10/ohyeah/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pragmatic Unit Testing in Java with JUnit</title>
		<link>http://narsereg.ru/2011/02/22/pragmatic-unit-testing-in-java-with-junit/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pragmatic-unit-testing-in-java-with-junit</link>
		<comments>http://narsereg.ru/2011/02/22/pragmatic-unit-testing-in-java-with-junit/#comments</comments>
		<pubDate>Tue, 22 Feb 2011 19:37:32 +0000</pubDate>
		<dc:creator>narsereg</dc:creator>
				<category><![CDATA[Книги]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JUnit]]></category>

		<guid isPermaLink="false">http://narsereg.ru/?p=64</guid>
		<description><![CDATA[Только что закончил чтение книги Pragmatic Unit Testing in Java with JUnit Эндрю Ханта и Дэвида Томаса. Давно пора было немного систематизировать знания по тестированию, чем я, собственно, и занялся. То, что до этого хранилось у меня в голове по &#8230; <a href="http://narsereg.ru/2011/02/22/pragmatic-unit-testing-in-java-with-junit/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img style="margin: 0px 10px 10px 0px; display: inline; float: left;" src="http://covers.oreilly.com/images/9780974514017/cat.gif" alt="" align="left" />Только что закончил чтение книги Pragmatic Unit Testing in Java with JUnit Эндрю Ханта и Дэвида Томаса.</p>
<p>Давно пора было немного систематизировать знания по тестированию, чем я, собственно, и занялся. То, что до этого хранилось у меня в голове по тестированию было, порой, странно и запутано. И, несмотря на всю элементарность работы с JUnit, редко применялось в достаточных количествах и в нужных местах. Со времен посмотрю, изменится ли что-нибудь. Надеюсь, что да.</p>
<p>Теперь перейдем к самой книге.</p>
<p>Язык книги прост и очень легко читаем. Несмотря на совершенно не родной мне английский (правда учу я его довольно давно) книга читается с одной попытки. Всего несколько раз мне требовалось возвращаться в начало абзаца или предложения, чтобы перечитать. Все остальное было понятно. Конечно, я вынес из этой книги (как и из любой другой) список слов для очередной стопки флеш-карт, но, а это немаловажно для русскоговорящей аудитории, язык прост и доступен.</p>
<p>Собственно JUnit в книге посвящено не так чтобы много места. По большей части это все-таки книга по основам тестирования. И это, пожалуй, минус. Ну что им стоило больше времени потратить на обучение конкретно JUnit? Просто когда ты берешь в руки книгу на обложке которой красуются слова JUnit и Java, то именно на них ты и ориентируешься, так как они вынесены в заголовок.</p>
<p>То есть, книга то отличная, хорошо написанная, но не про то, на что мы все рассчитывали.</p>
<p>Про теорию тестирования, подающуюся в Pragmatic Unit Testing in Java with JUnit никаких ругательных слов я сказать не могу. Эта часть описана более, чем полностью и в терминах, усваивающихся великолепно. После прочтения вы поймете как, что, где и почему нужно тестировать (а тестировать нужно абсолютно все, везде, всегда и всеми возможными способами).</p>
<p>В сухом остатке: книга отличная, но слишком мало отведено теме конкретной реализации тестирования. Читайте Pragmatic Unit Testing + javadocs и будет вам счастье.</p>
]]></content:encoded>
			<wfw:commentRss>http://narsereg.ru/2011/02/22/pragmatic-unit-testing-in-java-with-junit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Будущее JavaFX. Часть 2</title>
		<link>http://narsereg.ru/2010/11/12/budushee-javafx-par-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=budushee-javafx-par-2</link>
		<comments>http://narsereg.ru/2010/11/12/budushee-javafx-par-2/#comments</comments>
		<pubDate>Fri, 12 Nov 2010 19:11:33 +0000</pubDate>
		<dc:creator>narsereg</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[JavaFX]]></category>

		<guid isPermaLink="false">http://narsereg.ru/?p=48</guid>
		<description><![CDATA[Как и было обещано продолжаю. Что же нас ждет в свежем 2.0 релизе JavaFX кроме смены парадигмы разработки? Так как последовательности в JavaFX неизменяемы и не поддерживают null-значения, то требовались некоторые изменения. Мы их и получим. Обещаны ObservableList и ObservableMap. &#8230; <a href="http://narsereg.ru/2010/11/12/budushee-javafx-par-2/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Как и было обещано продолжаю. Что же нас ждет в свежем 2.0 релизе JavaFX кроме смены парадигмы разработки?</p>
<p>Так как последовательности в JavaFX неизменяемы и не поддерживают null-значения, то требовались некоторые изменения. Мы их и получим. Обещаны ObservableList и ObservableMap.</p>
<p>Поддержка многопоточности станет более полной и удобной (например, исчезнет необходимость в классе JavaTaskBase). Кроме того, появится возможность запускать процесс создания сцены в другом потоке, а затем объединять его с основным.</p>
<p>Улучшиться, по сравнению с версией 1.3 поддержка клавиатуры, то есть можно будет строить приложения, с которыми будет легче работать с клавиатуры.</p>
<p>Улучшиться как скорость работы работы приложения, так и скорость его загрузки. Кроме того с меньшими затратами будет работать и анимация.</p>
<p>Наконец-то мы получим новый движок рендеринга Prism, который будет поддерживать как DirectX, так и OpenGL. Кроме того будет возможность программного рендеринга. Появится компонент, позволяющий изменить способ рендеринга на Prism с AWT.</p>
<p>Также мы увидим новые контейнеры, которые позволят работать с ними из CSS. Это очень хорошо, так как позволит более гибко управлять своим приложением. Появится контейнер GridLayout с огромными возможностями по компановке интерфейса. Да и анимация, настраиваемая через CSS будет огромным прорывом.</p>
<p>Работа с медиа данными также улучшится. Во-первых увеличится производительность. Улучшится поддержка аудио с помощью нового аудио стека, что позволит мгновенно проигрывать некоторый звук, что критично при, например, реакции на нажатие кнопки. Появится поддержка полноэкранного режима в видеопроигрывателе. Ну и важнейшими нововведениями станут маркеры в медиапотоке, позволяющие привязывать события в программе к некоторым моментам в медиа, а также привязка медиа к timeline.</p>
<p>Наконец, в стандартные компоненты придет TableView. Ждали мы этого долго и наконец дождались. Еще появятся SplitView, TabView. MediaPlayer позволит сразу приступать к работе с медиа, так на этом компоненте уже будут все необходимые элементы управления.</p>
<p>С интернетом тоже будет бОльшая интеграция. Появится компонент WebView, отображающий web страницу, а также WebBrowsr (сразу готовый к серфингу браузер).</p>
<p>Ну вот, в принципе, и все. Нововведений много, а взлетит ли это все или нет – узнаем уже в следующем году.</p>
]]></content:encoded>
			<wfw:commentRss>http://narsereg.ru/2010/11/12/budushee-javafx-par-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Будущее JavaFX. Часть 1</title>
		<link>http://narsereg.ru/2010/11/09/budushee-javafx-par-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=budushee-javafx-par-1</link>
		<comments>http://narsereg.ru/2010/11/09/budushee-javafx-par-1/#comments</comments>
		<pubDate>Tue, 09 Nov 2010 18:26:38 +0000</pubDate>
		<dc:creator>narsereg</dc:creator>
				<category><![CDATA[Без рубрики]]></category>

		<guid isPermaLink="false">http://narsereg.ru/?p=39</guid>
		<description><![CDATA[Мда, немало новостей появилось вокруг столь мной любимого JavaFX. Мы все надеялись на экстенсивное развитие языка, а никак не на интенсивное. Но Oracle нас удивил. Я думаю, что немногие ожидали столь радикального хода событий. Я, конечно же, говорю об отказе &#8230; <a href="http://narsereg.ru/2010/11/09/budushee-javafx-par-1/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Мда, немало новостей появилось вокруг столь мной любимого JavaFX. Мы все надеялись на экстенсивное развитие языка, а никак не на интенсивное. Но Oracle нас удивил. Я думаю, что немногие ожидали столь радикального хода событий.</p>
<p>Я, конечно же, говорю об отказе от языка JavaFX Script. В чем была необходимость этого события я понять не в силах, но несмотря на все наши причитания во 2-й версии JavaFX, столь полюбившегося нам синтаксиса мы уже не увидим. Естественно, уже появился fork (который получил название Visage), но все же без такого могущественного союзника как Oracle (или если не получит поддержки, например, Apache) конкурировать на рынке он, к сожалению, не сможет.</p>
<p>Что же нам предлагает Oracle взамен? А предлагает она нам тоже самое, но под другим соусом. Мы увидим отличный продукт, но с синтаксисом классической Java. Разработчик получит GUI, но получать мы его будем не из скриптового языка, а из JavaBeans, содержащего все необходимые компоненты. То есть, богатство интерфейса JavaFX объединится с богатством самого языка Java. Во всяком случае, так обещается, а мы будем надеяться, что все не усложниться до того, что работать с этим будет невозможно.</p>
<p>В следующем посту посмотрим на JavaFX 2.0, так что далеко от мониторов не отходите.</p>
]]></content:encoded>
			<wfw:commentRss>http://narsereg.ru/2010/11/09/budushee-javafx-par-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Чистый кот</title>
		<link>http://narsereg.ru/2010/09/22/chisty-kot/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=chisty-kot</link>
		<comments>http://narsereg.ru/2010/09/22/chisty-kot/#comments</comments>
		<pubDate>Wed, 22 Sep 2010 17:48:22 +0000</pubDate>
		<dc:creator>narsereg</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Книги]]></category>

		<guid isPermaLink="false">http://narsereg.ru/?p=27</guid>
		<description><![CDATA[Довольно давно меня интересовал способ написания АДЕКВАТНОГО кода на любом языке программирования. Так уж получилось, что в течение длительного времени я занимался исключительно ухудшением своего программного почерка. Собственно писал так, как меня учили &#8211; лишь бы работало. Оно и работало. &#8230; <a href="http://narsereg.ru/2010/09/22/chisty-kot/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://narsereg.ru/wp-content/uploads/2011/08/11.jpg"><img class="alignleft size-full wp-image-28" title="1" src="http://narsereg.ru/wp-content/uploads/2011/08/11.jpg" alt="" width="248" height="352" /></a><br />
Довольно давно меня интересовал способ написания АДЕКВАТНОГО кода на любом языке программирования. Так уж получилось, что в течение длительного времени я занимался исключительно ухудшением своего программного почерка. Собственно писал так, как меня учили &#8211; лишь бы работало. Оно и работало. И даже проходило тесты, но возвращаться к коду было абсолютно невозможно &#8211; разобрать свой почерк без длительного вкуривания комментов (слава нулям и единицам &#8211; их я осиливал) я не мог. Несколько месяцев назад я полез в старый код, который писал еще на Delphi и ужаснулся тому, что понять ничего не возможно как не пытайся. В этот момент меня стукнуло по голове &#8211; надо браться за чистоту и понятность кода. Погуглив секунд 30 я понял, что лучшее, что написано на данный момент &#8211; &laquo;Чистый код&raquo; Роберта Мартиина. Так как в моей олимпийской столице найти хоть что-то отличное от книг по Delphi нереально, то заказал через интернет. Дождался. Прочитал. Читайте краткую рецензию.</p>
<p>Конечно, можно долго рассуждать про то, какой код можно читать лучшим &#8211; быстрый или читаемый (читаемый и быстрый &#8211; это идеал). Я свой выбор сделал. Нечитаемый код бесполезен, так как не подлежит копипасту. Копипаст &#8211; жесткий способ проверки кода. Если в двух проектах нужен примерно один функционал, то дважды писать плохой код &#8211; это намного хуже, чем скопировать хороший. Если же вернуться к книге, то она учит писать именно такой хороший код.</p>
<p>Книга написана очень хорошо. Все рассасывается до состояния кашицы и впрыскивается в вас так, чтобы вопросов не возникало. Конечно, сразу видно, что разные главы писали разные люди, так как иногда то, что принципиально для одного, для другого является лишь рекомендацией, но это лишь дает место для брожения мысли в вашей черепной коробке &#8211; вы сами должны определить приоритеты в работе. Но некоторые принципы абсолютны для всех &#8211; например, читабельность названий переменных и повторяемость кода. В первом случае она нужна, во втором, соответственно, нет.</p>
<p>Еще мне очень понравилось, что Роберт Мартин написал все очень краткими главами, которые просто прочитать даже в те моменты, когда ты отвлекаешься от своего кода, чтобы поплевать в потолок и помечтать о собственном Гугле. Немного напрягла глава про последовательное очищение кода, написанная интересно, но включающая слишком большие куски кода, которые читать (а потом еще и сравнивать с новым релизом) крайне сложно. Уверен, что можно было бы сделать это и попроще. Хотя, что я могу знать.</p>
<p>Издательство &laquo;Питер&raquo;, конечно, ничего особого предложить не смогло в оформлении книги, но перевод хороший и ровный (а еще очень мало опечаток, что радует безмерно, ибо испытываю к ним вселенскую ненависть).</p>
<p>В общем книга отличная и если вы еще не пишите правильно, то пожалуйста, начинайте &#8211; вдруг мне когда-нибудь придется это читать.</p>
<p>А название этой записи мне навеяла другая книга этого издательства &#8211; &laquo;Как пасти котов&raquo;. Кстати тоже довольно любопытная.</p>
]]></content:encoded>
			<wfw:commentRss>http://narsereg.ru/2010/09/22/chisty-kot/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaFX для меломана. Часть 3</title>
		<link>http://narsereg.ru/2010/07/20/javafx-dlya-meloman-part-3/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=javafx-dlya-meloman-part-3</link>
		<comments>http://narsereg.ru/2010/07/20/javafx-dlya-meloman-part-3/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 17:26:57 +0000</pubDate>
		<dc:creator>narsereg</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[JavaFX]]></category>

		<guid isPermaLink="false">http://narsereg.ru/?p=18</guid>
		<description><![CDATA[И вот, после трех месяцев мы, наконец-то, оказались на финишной прямой. Последний бой &#8211; он трудный самый. В предыдущих частях повествования стал проглядывать интерфейс и мы получили возможность управлять приложением. Пусть чуть-чуть, но это, все же, лучше чем ничего. Что &#8230; <a href="http://narsereg.ru/2010/07/20/javafx-dlya-meloman-part-3/">Читать далее <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>И вот, после трех месяцев мы, наконец-то, оказались на финишной прямой. Последний бой &#8211; он трудный самый.</p>
<p>В предыдущих частях повествования стал проглядывать интерфейс и мы получили возможность управлять приложением. Пусть чуть-чуть, но это, все же, лучше чем ничего.</p>
<p>Что осталось? Вот основные пункты:</p>
<p>1. Добавление файлов в список плейлиста.</p>
<p>2. Проигрывание этих файлов.</p>
<p>3. Перемотка по плейлисту.</p>
<p>4. Управление звуком.</p>
<p>5. Вывод названия трека на экран.</p>
<p>6. Перемотка внутри песни.</p>
<p>Так как времени мало, а материала много, то именно по этим пунктам и пройдемся.</p>
<p>Для добавления файлов естественно понадобится кнопка. Увидеть ее можно, запустив исходники, которые можно получить со ссылки в конце статьи (она выглядит так же, как и кнопка сворачивания окна, только с тремя точками). А вот работу этой кнопки необходимо рассмотреть более подробно.</p>
<pre class="brush: jfx;">Листинг 1.
onMouseClicked: function(evt: MouseEvent): Void {
  if ((evt.clickCount == 1) and (evt.button == MouseButton.PRIMARY))
  then {
    var dialogOpen : JFileChooser = new JFileChooser();
    dialogOpen.setMultiSelectionEnabled(true);
    dialogOpen.setFileFilter(new Mp3FileFilter());
    dialogOpen.setAcceptAllFileFilterUsed(false);
    if (JFileChooser.APPROVE_OPTION == dialogOpen.showOpenDialog(null)) {
      for (file in dialogOpen.getSelectedFiles()){
        insert file.getAbsolutePath() into fileList;
      }
    }
  }
}</pre>
<p>С первой парой строк все ясно из предыдущих статей, а дальше начинается непонятное. Разъясняю. Сначала создается диалоговое окно выбора файлов JFileChooser. Это окно &#8211; одно из самых часто используемых в работе, так как почти в каждой программе требуется выбор файлов и их открытие. JFileChooser имеет множество опций, одной из которых является использование фильтров, то есть возможность отображать только те файлы, которые подходят условию. В нашем случае должны быть видны только mp3 файлы и папки, поэтому мы создаем следующий класс:</p>
<pre class="brush: jfx;">Листинг 2.
class Mp3FileFilter extends FileFilter{
  override public function accept(file : File) : Boolean{
    if (file.getName().endsWith(".mp3"))
    then { return true; };
    if (file.isDirectory())
    then { return true; };
    return false;
  }
  override public function getDescription() : String{
    return "Mp3 files";
  }
}</pre>
<p>И указываем, что этот фильтр необходимо использовать dialogOpen.setFileFilter(new Mp3FileFilter()). Все, теперь при запуске окна JFileChooser будут видны только папки и файлы с расширением mp3.</p>
<p>В рамках статьи нам понадобятся свойства setMultiSelectionEnabled(true), позволяющее выбирать несколько файлов одновременно, и setAcceptAllFileFilterUsed(false), убирающее возможность просмотра всех файлов (только mp3). Далее программа проверяет, была ли нажата кнопка Open, и если это так, в переменную fileList (а она, напомню, связана со списком песен) добавляются абсолютные пути выбранных файлов (file.getAbsolutePath()).</p>
<p><a href="http://narsereg.ru/wp-content/uploads/2011/08/¦б¦¦TА¦¬¦-TИ¦-TВ-1.jpg"><img class="alignnone size-full wp-image-21" title="¦б¦¦TА¦¬¦-TИ¦-TВ 1" src="http://narsereg.ru/wp-content/uploads/2011/08/¦б¦¦TА¦¬¦-TИ¦-TВ-1.jpg" alt="" width="299" height="217" /></a></p>
<p>Вот теперь мы готовы к решительному шагу запуска медиафайла в проигрывателе. Будем это делать двойным кликом на файле в плейлисте, как это принято в больших плеерах. Для этого достаточно добавить пару строчек в код listviewPlaylist:</p>
<pre class="brush: jfx;">Листинг 3.
onMouseClicked: function(evt: MouseEvent): Void {
  if ((evt.clickCount == 2) and (evt.button == MouseButton.PRIMARY))
  then {
    playMedia(fileList[listviewPlaylist.selectedIndex]);
  }
}</pre>
<p>Здесь вызывается функция playMedia(), которую рассмотрим чуть позже, так как она требует небольшой подготовки с нашей стороны. Добавить работоспособности интерфейсу можно назначив onMouseClicked для кнопок перемотки:</p>
<pre class="brush: jfx;">Листинг 4.
onMouseClicked: function(evt: MouseEvent): Void {
  if ((evt.clickCount == 1) and (evt.button == MouseButton.PRIMARY)) {
    if (listviewPlaylist.selectedIndex != sizeof listviewPlaylist.items - 1)
    then {
      listviewPlaylist.selectNextRow()
    } else {
      listviewPlaylist.selectFirstRow();
    }
    playMedia(fileList[listviewPlaylist.selectedIndex]);
  }
}</pre>
<p>Здесь представлен код для кнопки Вперед и он прост как две копейки &#8211; при нажатии на кнопку проверяется условие на конец списка, в зависимости от результата выбирается следующий или первый трек и запускается все та же незнакомая функция playMedia(). Кнопка Назад аналогична по функциональности и ее код приводиться здесь не будет.</p>
<p>Следующим пунктом списка мы должны рассмотреть звук, а точнее его регулировку. Для этого на форму положим Swing-компонент Slider:</p>
<pre class="brush: jfx;">Листинг 5.
sliderVolume = Slider {
  layoutX: bind display.layoutX + 10
  layoutY: bind display.layoutY + 10
  min: 0
  max: 9
  value: 0
  vertical: true
  height: 80
}</pre>
<p>Переменные layoutX и layoutY &#8211; положение слайдера на форме; min и max &#8211; минимальное и максимальное значение слайдера; value &#8211; значение по умолчанию; vertical &#8211; показывает, что слайдер имеет вертикальное расположение; height &#8211; высота в пикселах. Теперь привязка к громкости mediaPlayer будет выглядеть как одна строчка в переменных этого компонента:</p>
<pre class="brush: jfx;">volume: bind (9 - sliderVolume.value) / 10</pre>
<p>Вывод названия трека на экран оказывается ничуть не сложнее, чем предыдущая задача. Добавим компонент Text на небольшой Rectangle в центре нашей сцены, который мы считаем экраном:</p>
<pre class="brush: jfx;">Листинг 6.
trackName = Text {
  content: bind track;
  wrappingWidth: 130
  layoutX: bind display.layoutX + 30
  layoutY: bind (display.height - trackName.layoutBounds.height) / 2
    + display.layoutY + trackName.font.size / 2
  fill: Color.AQUA
  textAlignment: TextAlignment.CENTER
  font: Font{ size:14 }
  effect: Bloom{ }
}</pre>
<p>Самая главная строчка здесь &#8211; content: bind track. С помощью нее выводимый текст привязывается к переменной track типа String.</p>
<p>Чтоб не загружать статью еще одним огромным листингом предлагаю открыть исходные коды программы и найти место, где мы выводим на сцену lineProgress и rectProgress. LineProgress &#8211; линия, по которой будет двигаться слайдер перемотки. Более интересен другой компонент &#8211; rectProgress, являющийся тем самым ползунком перемотки песни. Здесь мы используем переменную blocksMouse, которая запрещает передавать событие вниз по слоям интерфейса. Эту возможность необходимо использовать для того, что бы при перетаскивании ползунка не начинала двигаться наша форма (напомню, что мы добавили возможность drag&#8217;n'drop для Stage в прошлой статье). Листинг обработчика событий для этого компонента необходим, так что вот и он:</p>
<pre class="brush: jfx;">Листинг 7.
onMousePressed: function(e: MouseEvent):Void {
  timelineProgress.pause();
  beginPointX = e.sceneX - rectProgress.width / 2;
}
onMouseDragged: function(e: MouseEvent):Void {
  var minPosition = lineProgress.layoutX - rectProgress.width / 2;
  var maxPosition = lineProgress.layoutX - rectProgress.width / 2 + 350;
  var xPosition = e.sceneX - rectProgress.width / 2;
  if(xPosition &lt;= minPosition)
  then {
    xPosition = minPosition
  } else if (xPosition &gt;= maxPosition)
  then { xPosition = maxPosition }
  rectProgress.layoutX = xPosition;
}
onMouseReleased: function(e: MouseEvent):Void {
  resumeMedia(e.sceneX - rectProgress.width / 2
    - lineProgress.layoutX - rectProgress.width / 2);
}</pre>
<p>В этом коде придется разобраться достаточно подробно. Во-первых &#8211; что такое timelineProgress?</p>
<pre class="brush: jfx;">Листинг 8.
var timelineProgress = Timeline {
  repeatCount: Timeline.INDEFINITE
  keyFrames : [
    KeyFrame {
      time : bind Duration.valueOf(mediaDurStep);
      canSkip : true
      action: function () {
        if (rectProgress.layoutX &gt;= lineProgress.layoutX - rectProgress.width / 2 + 350)
        then { } else { rectProgress.layoutX++ }
      }
    }
  ]
}</pre>
<p>TimelineProgress имеет тип TimeLine &#8211; один из базовых типов JavaFX, с которыми придется работать постоянно. TimeLine дает нам возможность изменения параметров нашего приложения в процессе выполнения приложения. Стоит рассмотреть его подробнее. Ключевые переменные этого типа следующие:</p>
<p>1. autoReverse &#8211; разрешает возврат анимации. После завершения анимации объект возвращается на исходную позицию по той же траектории.</p>
<p>2. keyFrames &#8211; содержит последовательность KeyFrame.</p>
<p>3. repeatCount &#8211; количество повторов TimeLine.</p>
<p>4. time &#8211; указывается с какого времени начать проигрывание анимации.</p>
<p>В нашем случае repeatCount получил значение Timeline.INDEFINITE. Это значит, что анимация будет повторяться бесконечное количество раз.</p>
<p>В переменной keyFrames мы используем только один компонент. KeyFrame &#8211; своеобразная единица анимации, которая выполняется необходимое количество раз с интервалом time. Action &#8211; функция, которая выполняется каждый период времени. Наша функция перемещает слайдер перемотки по линии и нельзя допустить, чтоб он вышел за пределы этой полосы перемотки, для этих целей и написана проверка на границы. Длина полосы перемотки &#8211; 350 пикселей.</p>
<p>TimeLine имеет четыре функции:</p>
<p>1. pause() &#8211; ставит анимацию на паузу, то есть временно ее приостанавливает.</p>
<p>2. play() &#8211; снимает анимацию с паузы, либо запускает с указанной позиции.</p>
<p>3. playFromStart() &#8211; запускает TimeLine с самого начала.</p>
<p>4. stop() &#8211; останавливается анимация и возвращает все значения в начальные позиции.</p>
<p>После всех этих строк теории становится немного понятнее практика. В Листинге 7 событие onMousePressed запоминает начальную позицию ползунка и останавливает анимацию. При перетаскивании вызывается onMouseDragged, в котором мы просто перемещаем ползунок по полосе перемотки. Опять же, постоянно следим за тем, что бы Rectangle не выходил за границы. И, наконец, при отпускании кнопки мыши вызываем resumeMedia() &#8211; функцию, которая продолжает выполнение timelineProgress и включает наш трек в выбранном месте. Делается это так:</p>
<pre class="brush: jfx;">Листинг 9.
function resumeMedia(position : Number){
  mediaplayer.mediaPlayer.currentTime = Duration.valueOf(position * mediaDurStep);
  timelineProgress.play();
}</pre>
<p>Здесь position &#8211; положение слайдера на полосе перемотки. Duration.valueOf() переводит некоторое значение в тип данных Duration &#8211; время. В нашем контексте мы устанавливаем текущим временем внутри песни положение ползунка, умноженное на шаг выполнения TimeLine. После чего возобновляем выполнение timelineProgress().</p>
<p>Осталась малость &#8211; разобраться с нашим Неуловимым Джо &#8211; функцией playMedia(). Вот ее листинг:</p>
<pre class="brush: jfx;">Листинг 10.
function playMedia(mediaSrc : String){
  mediaplayer.mediaPlayer.stop();
  rectProgress.layoutX = lineProgress.layoutX - rectProgress.width / 2;
  playPause = true;
  mediaplayer.mediaPlayer.media = Media{source: "file:/{mediaSrc.replace("\\","/").replace(" ","%20")}"};
  mediaDurStep = mediaplayer.mediaPlayer.media.duration.toMillis() / 350;
  mediaplayer.mediaPlayer.play();
  timelineProgress.playFromStart();
  track = mediaSrc.substring(mediaSrc.lastIndexOf("\\") + 1);
}</pre>
<p>Я не продемонстрировал эту функцию в самом начале, так как тогда она оставила бы больше вопросов, чем ответов и только занимала бы голову. Сейчас же все становится намного яснее. Эта функция вызывается при начале проигрывания песни. В качестве параметра в нее передается строка с путем и именем медиафайла. Далее по шагам:</p>
<p>1. Останавливается проигрывание предыдущей песни.</p>
<p>2. Слайдер перемотки устанавливается в начальное положение.</p>
<p>3. Переменная playPause (на нее, например, завязано переключение кнопки Пауза/Проигрывание) устанавливается в true.</p>
<p>4. Присваиваем переменной media новый медиафайл (здесь производится форматирование и приведение к принятому в JavaFX имени файла).</p>
<p>5. Вычисляем mediaDurStep &#8211; количество секунд, которые должны пройти между перемещением ползунка на один пиксел, для чего берем продолжительность песни и делим на длину полосы перемотки.</p>
<p>6. Запускаем проигрывание файла.</p>
<p>7. Запускаем наш TimeLine с начала.</p>
<p>8. Присваиваем переменной track (к ней привязано название песни, выводимое на экран) значение, которое будет выглядеть примерно как &laquo;название-песни.mp3&#8243;.</p>
<p>Ну, вот и все. Теперь наша программа готова к выполнению своих непосредственных задач. Компилируем код и проверяем.</p>
<p><a href="http://narsereg.ru/wp-content/uploads/2011/08/¦б¦¦TА¦¬¦-TИ¦-TВ-2.jpg"><img class="alignnone size-full wp-image-22" title="¦б¦¦TА¦¬¦-TИ¦-TВ 2" src="http://narsereg.ru/wp-content/uploads/2011/08/¦б¦¦TА¦¬¦-TИ¦-TВ-2.jpg" alt="" width="354" height="295" /></a></p>
<p>JavaFX предоставляет огромные возможности всем разработчикам. Эта технология смогла совместить в себе всю мощь Java и простоту написания интерфейса для любых программ. Всего за несколько минут можно создать вполне функциональный код, а если потратить еще немного, то его будет не стыдно даже напечатать в журнале. Что я и продемонстрировал на своем примере.</p>
<p>Ну а исходники вы как всегда найдете по этой <a href="http://narsereg.ru/files/article/javafx_dlya_melomana_part3/ChinesePlayer_article3.zip">ссылке</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://narsereg.ru/2010/07/20/javafx-dlya-meloman-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

