<?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>SimpleCoding.org &#187; Java</title>
	<atom:link href="http://www.simplecoding.org/category/j/feed" rel="self" type="application/rss+xml" />
	<link>http://www.simplecoding.org</link>
	<description>Блог о программировании</description>
	<lastBuildDate>Fri, 27 Jan 2012 18:27:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Графики своими руками – Open Flash Chart 2</title>
		<link>http://www.simplecoding.org/grafiki-svoimi-rukami-open-flash-chart-2.html</link>
		<comments>http://www.simplecoding.org/grafiki-svoimi-rukami-open-flash-chart-2.html#comments</comments>
		<pubDate>Mon, 20 Apr 2009 16:21:36 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=809</guid>
		<description><![CDATA[Об этой библиотеке я раньше рассказывал (Open Flash Chart – строим графики). Но с тех пор прошло почти 8 месяцев и за это время многое изменилось. Вышла новая версия библиотеки Open Flash Chart 2 и она довольно серьезно отличается от первой версии. Объяснять причины введения изменений я не буду, просто процитирую автора. Open Flash Chart [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_810" class="wp-caption alignnone" style="width: 310px"><img src="http://www.simplecoding.org/wp-content/uploads/2009/04/open_flash_chart_2.png" alt="open_flash_chart_2" title="open_flash_chart_2" width="300" height="270" class="size-full wp-image-810" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>Об этой библиотеке я раньше рассказывал (<a href="http://www.simplecoding.org/open-flash-chart-stroim-grafiki.html">Open Flash Chart – строим графики</a>). Но с тех пор прошло почти 8 месяцев и за это время <strong>многое изменилось</strong>.</p>
<p>Вышла новая версия библиотеки <a href="http://teethgrinder.co.uk/open-flash-chart-2/">Open Flash Chart 2</a> и она довольно серьезно отличается от первой версии. Объяснять причины введения изменений я не буду, просто процитирую автора.</p>
<blockquote><p><em>Open Flash Chart 1.x была отличной и хорошо работала. Но я сделал несколько маленьких ошибок, которые со временем выросли, стали раздражать меня и сделали исходный код жутким. Поэтому я решил, что настало время переработать код и снова сделать его красивым. Теперь в качестве формата данных используется JSON. Это привело к значительным изменениям и позволило реализовать несколько новых возможностей.</p>
<p>Выход новой версии не сделал V 1.x устаревшей. Вы можете использовать обе версии одновременно. Поэтому не трогайте ваш работающий с V 1.x код, а для новых графиков используйте ту версию которой вам удобнее (проще) пользоваться.</em></p></blockquote>
<p>Думаю, ситуация более-менее ясна, поэтому сразу приведу <strong>пример использования второй версии</strong>.</p>
<p>Как и в первой версии нужно внимательно следить за размещением библиотеки и правильно указывать пути к файлам.<br />
<span id="more-809"></span><br />
<strong>Структура сайта.</strong></p>
<p>Допустим у нас есть домен <code>http://localhost/</code></p>
<p>Библиотека находится в папке <code>tests/ofc/lib/</code> и имеет такую структуру</p>
<pre>tests/ofc/lib
	open-flash-chart.swf
	php-ofc-library/
		... (все файлы из папки php-ofc-library)</pre>
<p><em>Примечание</em>. Из дистрибутива я скопировал только флеш-ролик для создания графика и PHP версию библиотеки.</p>
<p>Страница, на которой мы будем показывать графики &#8211; <code>http://localhost/tests/ofc/mygraphs.php</code>.</p>
<p><strong>Источники данных.</strong></p>
<p>Данные можно брать откуда угодно, из базы, текстового файла, рассчитывать. Для этого примера мы создадим <strong>2 php скрипта</strong> (<code>data1.php</code> и <code>data2.php</code>), которые будут формировать массивы с данными для построения графиков и преобразовывать их в формат <strong>JSON</strong>. Оба файла разместим в папке <code>datasrc</code>.</p>
<p>Т.к. источников данных у нас два, а график будет один, то нам нужно как-то указать какой из них необходимо использовать.</p>
<p>Имя скрипта – источника данных можно передать вместе с URL (в параметре <code>ofc</code>).</p>
<p>Т.е., на странице<br />
<code>http://localhost/tests/ofc/mygraphs.php?ofc=datasrc/data1.php</code><br />
мы увидим график с данными сформированными скриптом data1.php.<br />
А на странице<br />
<code>http://localhost/tests/ofc/mygraphs.php?ofc=datasrc/data2.php</code><br />
график с данными из data2.php.</p>
<p><em>Обратите внимание</em>. При указании источника данных мы указываем путь к файлу (относительно данной страницы).</p>
<p>Теперь рассмотрим сами скрипты.</p>
<p><strong>mygraphs.php</strong></p>
<pre class="brush: php">&lt;?php
if (!isset($_GET['ofc'])) {
	Header('Location: mygraphs.php?ofc=datasrc/data1.php');
}
?&gt;
&lt;?php echo '&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;'; ?&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot;
		&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;

&lt;head&gt;
	&lt;title&gt;Open Flash Chart 2&lt;/title&gt;
	&lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html;charset=utf-8&quot; /&gt;
&lt;/head&gt;

&lt;body&gt;

&lt;h1&gt;Графики&lt;/h1&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;mygraphs.php?ofc=datasrc/data1.php&quot;&gt;Первый график (data1.php)&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;mygraphs.php?ofc=datasrc/data2.php&quot;&gt;Второй график (data2.php)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;object classid=&quot;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000&quot;
		codebase=&quot;http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0&quot;
		width=&quot;500&quot;
		height=&quot;250&quot; id=&quot;graph-2&quot; align=&quot;middle&quot;&gt;

	&lt;param name=&quot;allowScriptAccess&quot; value=&quot;sameDomain&quot; /&gt;
	&lt;param name=&quot;movie&quot; value=&quot;lib/open-flash-chart.swf&quot; /&gt;
	&lt;param name=&quot;quality&quot; value=&quot;high&quot; /&gt;
	&lt;embed src=&quot;lib/open-flash-chart.swf&quot;
		   quality=&quot;high&quot;
		   bgcolor=&quot;#FFFFFF&quot;
		   width=&quot;500&quot;
		   height=&quot;250&quot;
		   name=&quot;open-flash-chart&quot;
		   align=&quot;middle&quot;
		   allowScriptAccess=&quot;sameDomain&quot;
		   type=&quot;application/x-shockwave-flash&quot;
		   pluginspage=&quot;http://www.macromedia.com/go/getflashplayer&quot; /&gt;
&lt;/object&gt;

&lt;/body&gt;

&lt;/html&gt;</pre>
<p><strong>Принцип работы</strong> здесь следующий. Сначала проверяем указан ли параметр <code>ofc</code> и если нет, отправляем посетителя на <code>mygraphs.php?ofc=datasrc/data1.php</code>. Т.е. на страницу с графиком, построенным по данным из скрипта <code>data1.php</code>.</p>
<p>На самой странице мы создаем список со ссылками на оба наших графика (строки 20-23) и размещаем <strong>flash ролик</strong>, с помощью которого и будет показан график (строки 25-43).</p>
<p>Код вставки ролика в основном остается без изменений. Нас, прежде всего, интересуют параметры <code>width</code> и <code>height</code> (задают размер графика в пикселях, строки 27, 28, 36, 37), <code>id</code> и <code>align</code> (строки 28, 39).</p>
<p>И, самое главное, атрибут <code>value</code> в параметре <code>movie</code> (строки 31 и 33). В нем указываем размещение ролика (<code>lib/open-flash-chart.swf</code>). Здесь также путь указан относительно данной страницы.</p>
<p>Теперь рассмотрим <strong>PHP скрипты, которые формируют данные для графиков</strong>.</p>
<p><strong>data1.php</strong></p>
<pre class="brush: php">&lt;?php
include '../lib/php-ofc-library/open-flash-chart.php';

$tmp = array();
for( $i=0; $i&lt;9; $i++ )
{
	$tmp[] = abs($i - 5);
}

$title = new title(&quot;Данные получены из файла data1.php&quot;);

$bar = new bar();
$bar-&gt;set_values($tmp);

$chart = new open_flash_chart();
$chart-&gt;set_title($title);
$chart-&gt;add_element($bar);

echo $chart-&gt;toString();

?&gt;</pre>
<p>Здесь мы загружаем библиотеку <code>open-flash-chart.php</code> (обратите внимание на то, как указано её размещение).</p>
<p>Затем формируем массив с данными <code>$tmp</code> (строки 4-8). Здесь я использовал не сложную функцию.</p>
<p>После этого создаём объект типа <code>bar</code>. Думаю, не сложно догадаться, что он используется для создания гистограмм. И с помощью метода <code>set_values</code> указываем массив с исходными данными.</p>
<p>Второй объект, который нам понадобиться &#8211; <code>open_flash_chart</code>. Его метод <code>set_title</code> используется для установки заголовка графика, а <code>add_element</code> – добавляет нашу гистограмму.</p>
<p>Последний шаг. Формируем строку в формате JSON с данными нашего графика (метод <code>toString()</code>).</p>
<p>Скрипт data2.php практически не отличается. Я только изменил функцию, формирующую массив с данными и тип графика.</p>
<p><strong>data2.php</strong></p>
<pre class="brush: php">&lt;?php
include '../lib/php-ofc-library/open-flash-chart.php';

$tmp = array();
for( $i=0; $i&lt;9; $i++ )
{
	$tmp[] = abs($i - 2);
}

$title = new title(&quot;Данные получены из файла data2.php&quot;);

$line = new line();
$line-&gt;set_values($tmp);

$chart = new open_flash_chart();
$chart-&gt;set_title($title);
$chart-&gt;add_element($line);

echo $chart-&gt;toString();

?&gt;</pre>
<p>Как видите, принцип работы библиотеки достаточно простой. А на <a href="http://teethgrinder.co.uk/open-flash-chart-2/">официальном сайте</a> вы найдете множество других интересных примеров.</p>
<p>В заключение хочу сказать пару слов об <strong>эффективности</strong> этой библиотеки.</p>
<p>Т.к. картинка с графиком формируется на стороне клиента (с помощью Flash), то нагрузка на сервер будет минимальной. Получение данных и преобразование их в JSON формат потребует значительно меньше ресурсов, чем получение данных и создание графика, например, с помощью библиотеки GD.</p>
<p>Но в тоже время посетителю будет отправлен flash ролик (open-flash-chart.swf) объемом <strong>264</strong>кБ. Для сравнения аналогичный png файл с изображением графика будет занимать <strong>10-30</strong>кБ.</p>
<p>Отсюда простой <strong>вывод</strong>. Если ваше приложение напоминает Google Analytics, то с помощью <strong>Open Flash Chart</strong> вы не только снизите нагрузку на свой сервер, но и сэкономите трафик пользователей, т.к. flash ролик грузится только один раз. Но если вам нужно показать всего один или два графика, то вряд ли эта библиотека будет самым удачным выбором.</p>
<p>Если вы не согласны или хотите что-то спросить, не стесняйтесь, комментарии открыты <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><strong>P.S.</strong> В следующий раз я продолжу тему графиков и расскажу об использовании сторонних сервисов для этих целей.</p>
<p><strong>Интересно почитать</strong></p>
<p>Аутсорсинг непрофильных операций. Логос-Аудит &#8211; <a href="http://www.logos-audit.ru/bookkeeping/hr/">ведение кадрового учёта</a> для малого и среднего бизнеса.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/grafiki-svoimi-rukami-open-flash-chart-2.html/feed</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Управление поиском файлов. Создание приложения на Java.</title>
		<link>http://www.simplecoding.org/upravlenie-poiskom-fajlov.html</link>
		<comments>http://www.simplecoding.org/upravlenie-poiskom-fajlov.html#comments</comments>
		<pubDate>Sun, 19 Aug 2007 14:47:05 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/upravlenie-poiskom-fajlov.html</guid>
		<description><![CDATA[Создание программы поиска файлов]]></description>
			<content:encoded><![CDATA[<p>Эта статья завершает цикл, посвящённый созданию библиотеки поиска файлов. На данный момент мы можем найти нужные файлы, и отсортировать их.<br />
Теперь добавим возможности управления процессом поиска, получения промежуточных результатов, и напишем простейший поисковик с графическим интерфейсом.<br />
<span id="more-59"></span><br />
<strong>Новые возможности</strong><br />
Итак, начнём. Прежде всего, вспомним, каким образом выполняется поиск в нашей библиотеке. Всё предельно просто. Для того чтобы найти файлы нужно вызвать один из методов <code>find...</code> класса <code>FileFinder</code>.</p>
<p>Проблема заключается в том, что продолжительность поиска может быть довольно большой, и, если мы просто вызовем метод <code>find...</code>, то работа программы будет заблокирована, пока он не возвратит результат. Это не играет роли в учебном примере, но если вашей программой будут пользоваться другие люди, такая ситуация недопустима. Конечно, пользователь услышит жужжание винчестера, но, скорее всего, ему не понравится, что программа внешне выглядит &#034;зависнувшей&#034;.</p>
<p>Поэтому, нам нужно, чтобы поиск файлов выполнялся отдельно от основной программы (кода, который отвечает за работу интерфейса). Сделать это не сложно. Любая современная операционная система поддерживает многозадачность, и, естественно, в стандартную библиотеку Java входят классы для создания многопоточных (multithreaded) приложений. К сожалению, описание этих классов выходит далеко за рамки этой статьи, поэтому, если у вас возникнут вопросы, советую почитать: <a href="http://java.sun.com/docs/books/tutorial/">&#034;Threads: Doing Two or More Tasks at Once&#034;</a>, <a href="http://lib.juga.ru/article/articleview/166/1/68/">&#034;Создание многопоточных приложений в Java&#034;</a> (на русском) или любую другую статью о создании многопоточных приложений.</p>
<p>Теперь поиск не будет блокировать работу программы, но кроме этого, хотелось бы знать о текущем состоянии процесса (например, сколько файлов найдено на данный момент). Для этого, наш класс <code>FileFinder</code> должен периодически передавать информацию о своем состоянии.</p>
<p>Тут возникает два вопроса: &#034;Кому и как передавать информацию?&#034;. Ответы предельно просты: &#034;Тому, кто её запросил. С помощью вызова соответствующих методов&#034;. Т.е. класс <code>FileFinder</code> должен содержать список объектов, которые следят за процессом поиска, и периодически вызывать нужные методы.</p>
<p>Естественно, все эти объекты должны иметь одинаковый тип. Тут очень удобно использовать интерфейсы. Если какой-нибудь класс, например, <code>MainPanel</code> реализует интерфейс <code>SearchListener</code>, то мы сможем привести объект типа <code>MainPanel</code> к типу <code>SearchListener</code>. Кроме того, <code>MainPanel</code> будет обязан реализовать все методы, объявленные в <code>SearchListener</code>.</p>
<p>Как видите, идея довольна простая. Теперь приступим к её реализации. В первую очередь я хочу показать, как будет выглядеть программа, использующая нашу библиотеку (рис.1). Как вы уже догадались, это простейшая программа поиска файлов. В верхнем текстовом поле нужно задать начальную папку поиска (можно использовать кнопку &#034;Обзор&#034;). В нижнем поле можно задать регулярное выражение (о правилах составления регулярных выражений, можно прочитать в статье &#034;<a href="analiz-dannyx-s-pomoshhyu-regulyarnyx-vyrazhenij-ili-bystryj-sposob-proverki-vvedennyx-dannyx.html">Анализ данных с помощью регулярных выражений или быстрый способ проверки введённых данных</a>&#034;). Если выражение задано, то в список результатов будут включены те файлы и папки, которые ему соответствуют. Кнопка &#034;Поиск&#034; запускает процесс поиска.</p>
<p><img src="/wp-content/uploads/2007/08/program.png" alt="Программа поиска файлов" title="program.png" width="339" border="0" height="218" /><br />
Рис.1. Программа поиска файлов</p>
<p>Во время поиска текст на кнопке &#034;Поиск&#034; изменяется на &#034;Остановить&#034;, а напротив соответствующих надписей отображается информация о работе программы (рис.2).</p>
<p><img src="/wp-content/uploads/2007/08/file_searching.png" alt="Информация о текущих результатах" title="Информация о текущих результатах" width="339" border="0" height="218" /><br />
Рис.2. Информация о текущих результатах</p>
<p>После завершения поиска, или если пользователь нажал на кнопку &#034;Остановить&#034;, программа открывает окно с результатами (рис.3).</p>
<p><img src="/wp-content/uploads/2007/08/results.png" alt="Результаты поиска" title="Результаты поиска" width="408" border="0" height="357" /><br />
Рис.3. Результаты поиска</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/upravlenie-poiskom-fajlov.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Программирование на Java. Сортировка списка файлов.</title>
		<link>http://www.simplecoding.org/sortirovka-spiska-fajlov.html</link>
		<comments>http://www.simplecoding.org/sortirovka-spiska-fajlov.html#comments</comments>
		<pubDate>Sat, 18 Aug 2007 19:16:13 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/sortirovka-spiska-fajlov.html</guid>
		<description><![CDATA[Создание программы сортировки списка файлов]]></description>
			<content:encoded><![CDATA[<p>В прошлой статье  &#034;<a href="poisk-fajlov.html">Поиск файлов</a>&#034; мы начали разработку небольшой библиотеки для поиска файлов. На данный момент мы можем найти файлы, но не можем упорядочить результаты поиска. В этой статье я покажу, как создать класс, который позволит сортировать список файлов любым, удобным нам, способом.<br />
<span id="more-55"></span><br />
<strong>Вступление</strong><br />
Прежде всего, нам нужно определиться, что мы будем сортировать, и как. Наш класс для поиска файлов имеет несколько методов <code>find(...)</code>, которые возвращают список файлов (объект типа <code>List</code>) с объектами типа <code>File</code>. Таким образом, мы можем получить любую информацию о найденных файлах (имя, размер, размещение и т.д.).</p>
<p>Теперь решим, каким образом нам нужно отсортировать результаты поиска. Наиболее часто требуется сортировка по имени, типу, размеру и дате создания файла.</p>
<p>В этой статье мы напишем методы, необходимые для сортировки по имени файла (это одна из наиболее сложных сортировок). Итак, нам нужно, отсортировать все найденные файлы и папки в следующем порядке:</p>
<ul>
<li>первыми идут файлы с минимальной глубиной вложения (т.е. те, которые находятся ближе к начальной папке поиска);</li>
<li>файлы, которые находятся внутри одной папки, должны быть отсортированы в алфавитном порядке (нужно обеспечить правильную обработку не латинских символов).</li>
</ul>
<p>Результаты сортировки должны быть возвращены в виде списка (<code>List</code>) с объектами типа <code>File</code>, т.е. мы меняем только порядок следования элементов и ничего более.</p>
<p><strong>Сортировка списка файлов на Java</strong></p>
<p>Теперь, когда задача ясна, посмотрим, как мы можем её решить. В первую очередь, нам нужен какой-нибудь алгоритм сортировки. С этим проблем нет. На сегодняшний день, разработано множество таких алгоритмов. Парочку этих алгоритмов можно найти практически в любом учебнике по программированию. Так что, если хотите, берите книжку&#8230;, или можно воспользоваться стандартной библиотекой Java, конкретнее, методом <code>sort(List list, Comparator c)</code> класса <code>Collections</code> из пакета <code>java.util</code>.</p>
<p>Этот метод выполняет сортировку списка объектов, который передается ему в первом параметре (<code>list</code>). Тут у вас может возникнуть вполне закономерный вопрос: &#034;А как именно он будет сортировать файлы&#034;. Ответ простой: &#034;Так, как мы ему расскажем&#034;:-). Дело в том, что любой алгоритм сортировки принимает решения о порядке следования объектов на основании результатов их сравнения, т.е. при сортировке мы всегда должны иметь возможность получить результат сравнения двух любых объектов. Например, если бы мы сортировали список с объектами стандартного типа, например, <code>int</code>, то метод <code>sort</code> упорядочил бы их в порядке возрастания без дополнительных усилий с нашей стороны.</p>
<p>Но о том, как мы хотим отсортировать наш список, методу <code>sort</code> ничего не известно. Поэтому мы должны написать метод, который выполняет сравнение двух объектов из нашего списка. Этот метод (<code>int compare(Object o1, Object o2)</code>) определён в интерфейсе <code>Comparator</code>. Он должен возвращать «1», если первый аргумент (<code>o1</code>) больше второго (<code>o2</code>), «0» &#8211; если аргументы равны, и «-1» &#8211; если второй объект больше. Как вы, наверное, уже поняли, указатель на класс, который содержит наш метод сравнения (<code>compare(...)</code>) передаётся методу <code>sort</code> во втором параметре. Метод <code>sort</code> будет сортировать наши объекты в порядке возрастания, сравнивая их при помощи нашего метода <code>compare(...)</code>. Изменяя метод <code>compare(...)</code> мы можем задать любой порядок сортировки.</p>
<p>Теперь посмотрим как будет выглядеть наш класс сортировки файлов (<code>FileSorter</code>)</p>
<pre class="brush: java">package searchtools;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.File;

/**
 * Этот класс предназначен для сортировки списка файлов
 *
 * @author Стаценко Владимир
 * http://www.vova-prog.narod.ru
 */
public class FileSorter implements Comparator {

    Pattern p = null;
    Collator collator = null;

    /** Создает новые экземпляры FileSorter */
    public FileSorter() {
        .
        .
        .
    }

    /* Этот метод выполняет сравнение имен двух файлов.
     * Возвращает:
     *     1 если первый параметр (о1) больше второго (о2),
     *    -1 если первый параметр (о1) меньше второго (о2),
     *     0 если они равны.
     * Имя первого файла считается больше второго имени, если
     * первый файл находится ближе к корню дерева папок.
     * Если файлы находятся в одной папке, то больше то имя,
     * которое идет первым по алфавиту.
     */
    public int compare(Object o1, Object o2) {
        .
        .
        .
    }

    public List sort(List fileList) {
        ArrayList res = new ArrayList(fileList.size());
        res.addAll(fileList);
        Collections.sort(res, this);
        return res;
    }
}</pre>
<p>Как видите, наш класс реализует интерфейс <code>Comparator</code>, и, соответственно, методу <code>sort</code> мы передаём указатель <code>this</code>.</p>
<p>Для того, чтобы наш класс заработал, нам осталось написать метод <code>compare</code>.</p>
<p>Тут все просто. В первую очередь, проверяем равенство объектов (если имена файлов одинаковы, то и файлы равны). Если файлы разные, определяем их глубину вложения. Как вы помните, сначала должны идти файлы с меньшей глубиной вложения. Наконец, если файлы находятся на одной глубине, сравниваем сами имена файлов.</p>
<p>Для определения глубины вложения файлов нам нужно узнать количество символов-разделителей в полном имени файла. Обратите внимание, определять символ-разделитель нужно с помощью переменной <code>File.separator</code>, т.к. он зависит от операционной системы.</p>
<p>Для подсчёта символов-разделителей можно использовать цикл, но есть и более удобный метод, основанный на использовании регулярных выражений (почитать о них вы можете в статье &#034;<a href="analiz-dannyx-s-pomoshhyu-regulyarnyx-vyrazhenij-ili-bystryj-sposob-proverki-vvedennyx-dannyx.html">Анализ данных с помощью регулярных выражений или быстрый способ проверки введенных данных</a>&#034; или в <a href="http://java.sun.com/docs/">Java Tutorial</a>).</p>
<p>Для поддержки различных кодировок очень удобно использовать классы <code>Collator</code> и <code>Locale</code> из пакета <code>java.util</code>. Метод <code>compare</code> класса <code>Collator</code> позволяет выполнить сортировку строк в соответствии с алфавитом языка, который установлен в настройках системы.</p>
<p>Теперь посмотрим на весь класс целиком.</p>
<pre class="brush: java">/*
 * FileSorter.java
 *
*/

package searchtools;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.File;

/**
 * Этот класс предназначен для сортировки списка файлов
 *
 * @author Стаценко Владимир
 * http://www.vova-prog.narod.ru
 */
public class FileSorter implements Comparator {

    //класс для работы с регулярными выражениями
    Pattern p = null;
    //класс для работы со строками на разных языках
    Collator collator = null;

    /** Создает новые экземпляры FileSorter */
    public FileSorter() {
        //определяем системный символ разделитель и создаем
        //шаблон на его основе
        String separator = File.separator;
        if(separator.equals("\\")) {
            separator = "\\";
        }
        //создаем шаблон на основе символа-разделителя
        p = Pattern.compile(separator,
                Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
        //получаем системные настройки (язык и страну)
        String country = System.getProperty("user.country");
        String language = System.getProperty("user.language");
        //создаем экземпляр класса для сравнения строк на
        //основе региональных настроек
        collator = Collator.getInstance(new Locale(country, language));
    }

    /**
     * Этот метод выполняет сравнение имен двух файлов.
     * Возвращает:
     *     1 если первый параметр (о1) больше второго (о2),
     *    -1 если первый параметр (о1) меньше второго (о2),
     *     0 если они равны.
     * Имя первого файла считается больше второго имени, если
     * первый файл находится ближе к корню дерева папок.
     * Если файлы находятся в одной папке, то больше то имя,
     * которое идет первым по алфавиту.
     * @param o1 объект типа File
     * @param o2 объект типа File
     * @return результат сравнения
     */
    public int compare(Object o1, Object o2) {
        //если объекты не равны null и имеют тип File
        if(o1 != null &amp;&amp; o2 != null &amp;&amp;
                o1 instanceof File &amp;&amp; o2 instanceof File) {
            //приводим к типу File
            File f1 = (File)o1;
            File f2 = (File)o2;
            //получаем полный путь к имени файла
            String fullPath1 = f1.getAbsolutePath();
            String fullPath2 = f2.getAbsolutePath();
            //проверяем равенство имен
            if(fullPath1.equals(fullPath2)) {
                //возвращаем 0, т.к. имена одинаковы
                return 0;
            }
            //определяем глубину размещения файла в дереве папок
            //для этого разбиваем полный путь к файлу на
            //лексемы, и определяем их количество
            String[] res1 = p.split(fullPath1);
            String[] res2 = p.split(fullPath2);
            if(res1.length &gt; res2.length) {
                //возвращаем 1, если глубина вложения первого
                //файла больше глубины вложения второго
                return 1;
            }
            if(res1.length &lt; res2.length) {
                //возвращаем "-1" в противном случае
                return -1;
            }
            if(res1.length == res2.length) {
                //если файлы находятся на одинаковой глубине,
                //сортируем их в соответствии с алфавитом
                return collator.compare(fullPath1, fullPath2);
            }
        }
        //здесь мы возвращаем 0, т.к. сравнение объектов
        //выполнить невозможно (т.е. считаем, что объекты
        //одинаковые, во всяком случае, сортировать их
        //нет смысла)
        return 0;
    }

    /**
     * Этот метод выполняет сортировку списка файлов
     * @param fileList не отсортированный список файлов
     * @return отсортированный список файлов
     */
    public List sort(List fileList) {
        //создаем список для результатов (такого же размера
        //как и исходный список)
        ArrayList res = new ArrayList(fileList.size());
        //копируем список
        res.addAll(fileList);
        //выполняем сортировку
        Collections.sort(res, this);
        //возвращаем результат
        return res;
    }
}</pre>
<p>Как видите, значительная часть работы выполнена с помощью стандартных библиотек Java. Так что, можете быть уверены, время, потраченное на их изучение, быстро окупиться.</p>
<p>Если вы захотите изменить способ сортировки, например, сортировать файлы по их размеру, то просто измените метод <code>compare</code>.</p>
<p>Обеспечить поддержку нескольких видов сортировки немного сложнее. Я могу посоветовать использовать следующий метод.</p>
<p>Добавляем несколько констант и одну переменную.</p>
<pre class="brush: java">private final int SORT_BY_NAME = 1; //сортировка по имени файла
private final int SORT_BY_SIZE = 2; //сортировка по размеру файла

private int sortType = 1; //в этой переменной сохраняем текущий тип сортировки</pre>
<p>Во всех методах задаём тип сортировки:</p>
<pre class="brush: java">public List sortByName(List fileList) {
    sortType = SORT_BY_NAME;
    ...
}
public List sortBySize(List fileList) {
    sortType = SORT_BY_SIZE;
    ...
}</pre>
<p>А в методе <code>compare</code> добавляем оператор <code>switch</code> и, конечно, все нужные алгоритмы сравнения.</p>
<pre class="brush: java">switch (sortType) {
    case SORT_BY_NAME:
    //сравнение объектов по их имени
    case SORT_BY_SIZE:
    //сравнение объектов по их размеру
}</pre>
<p>Вот и все. Теперь мы можем не только искать файлы, но и выводить результаты поиска в удобном нам виде.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/sortirovka-spiska-fajlov.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Создание приложения для поиска файлов на Java</title>
		<link>http://www.simplecoding.org/poisk-fajlov.html</link>
		<comments>http://www.simplecoding.org/poisk-fajlov.html#comments</comments>
		<pubDate>Sat, 18 Aug 2007 18:30:10 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/poisk-fajlov.html</guid>
		<description><![CDATA[Создание программы поиска файлов]]></description>
			<content:encoded><![CDATA[<p>Сегодня любая операционная система имеет встроенные средства для поиска файлов. Во многих случаях что-то подобное хотелось бы использовать в своих программах. В этой статье я покажу, как создать небольшой Java класс, который можно будет использовать в любой программе для поиска файлов.<br />
<span id="more-51"></span><br />
<strong>Создание класса для поиска файлов</strong><br />
Сегодня любая операционная система имеет встроенные средства для поиска файлов. Во многих случаях что-то подобное хотелось бы использовать в своих программах. В этой статье я покажу, как создать небольшой Java класс, который можно будет использовать в любой программе для поиска файлов.</p>
<p>В первую очередь, давайте определимся, что именно должен делать наш класс. Для большинства случаев, я думаю, будет достаточно таких возможностей:</p>
<ul>
<li>поиск заданных файлов и папок в начальной папке и всех её вложенных папках;</li>
<li>общая статистика поиска (количество найденных файлов и папок, общий размер файлов);</li>
<li>использование регулярных выражений в качестве шаблонов для имен найденных файлов и папок (выборочный поиск);</li>
<li>поиск отдельно файлов, и отдельно папок.</li>
</ul>
<p>Теперь посмотрим, какие стандартные библиотеки из JDK (java development kit) нам понадобятся. В состав пакета <code>java.io</code> входит класс <code>File</code>, предназначенный для работы с файлами и папками. Он имеет методы для определения содержимого папки. Так что, нам остаётся добавить просмотр вложенных папок и поддержку регулярных выражений.</p>
<p>Несколько слов о том, что такое регулярные выражения. Это текстовые строки, составленные по определённым правилам, которые можно использовать в качестве шаблонов. Библиотека Java содержит пакет<code> java.util.regex</code>, предназначенный для работы с регулярными выражениями. Подробнее почитать о правилах составления и возможностях регулярных выражений можно в статье: <a href="http://www.simplecoding.org/analiz-dannyx-s-pomoshhyu-regulyarnyx-vyrazhenij-ili-bystryj-sposob-proverki-vvedennyx-dannyx.html">Анализ данных с помощью регулярных выражений или быстрый способ проверки введённых данных</a>.</p>
<p>Таким образом, наш класс, назовём его <code>FileFinder</code>, должен иметь такой набор методов.</p>
<p>Для поиска файлов и папок:<br />
<code>public List findAll(String startPath)<br />
public List findAll(String startPath, String mask)<br />
</code><br />
Для поиска только файлов:<br />
<code>public List findFiles(String startPath)<br />
public List findFiles(String startPath, String mask)</code><br />
Для поиска только папок:<br />
<code>public List findDirectories(String startPath)<br />
public List findDirectories(String startPath, String mask)</code><br />
Каждый найденный объект (файл или папка) включается в список результатов только в том случае, если он соответствует регулярному выражению, заданному в параметре <code>mask</code>. Все методы возвращают результат в виде списка объектов типа <code>File</code>.</p>
<p>С помощью методов:<br />
<code>public long getDirectorySize()<br />
public long getFilesNumber()<br />
public long getDirectoriesNumber()</code><br />
определяем количество найденных файлов и папок, и размер файлов.</p>
<p>Теперь, рассмотрим самую интересную часть. Поиск файлов. Он выполняется с помощью двух методов. Первый,<br />
<code>private List find(String startPath, String mask, int objectType)<br />
</code><br />
выполняет начальную подготовку к поиску: сброс счётчиков, проверку допустимости параметров, компиляцию регулярного выражения и т.п.. Второй метод,<br />
<code>private void search(File topDirectory, List res, int objectType)<br />
</code><br />
вызывается только из метода <code>find(...)</code>, он и выполняет поиск. В качестве параметров, методу <code>search(...)</code> передаются: имя папки, указатель на список для хранения найденных объектов, и тип нужного объекта (файлы, папки, всё подряд). С помощью метода <code>listFiles()</code> класса <code>File</code> определяем список файлов и папок в текущей папке (параметр <code>topDirectory</code>), а затем, для каждой найденной папки снова вызываем метод <code>search(...)</code>, но в параметре <code>topDirectory</code> передаём найденную папку. Такой способ вызова методов называется рекурсией. Т.е. метод <code>search(...)</code> будет вызывать сам себя до тех пор, пока не пройдёт все вложенные папки. Каждый найденный объект (папка или файл) проверяется на соответствие регулярному выражению (если оно задано) с помощью метода <code>accept()</code>, и, если проверка прошла успешно, добавляется в список результатов.</p>
<p>Теперь посмотрим на весь класс целиком.</p>
<pre class="brush: java">package searchtools;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Этот класс предназначен для поиска файлов
 *
 * @author Стаценко Владимир
 * http://www.vova-prog.narod.ru
 */
public class FileFinder {

    //классы для работы с регулярными выражениями
    private Pattern p = null;
    private Matcher m = null;

    //общий размер найденных файлов
    private long totalLength = 0;
    //общее количество найденных файлов
    private long filesNumber = 0;
    //общее количество просмотренных директорий
    private long directoriesNumber = 0;

    //константы для определения объектов, которые нужно найти
    private final int FILES = 0;
    private final int DIRECTORIES = 1;
    private final int ALL = 2;

    /** Создает новые экземпляры FileFinder */
    public FileFinder() {
    }

    /**
     * Этот метод выполняет поиск всех объектов (файлов и директорий),
     * начиная с заданной директории (startPath)
     * @param startPath Начальная директория поиска
     * @return Список (List) найденных объектов
     * @throws java.lang.Exception если возникли ошибки в процессе поиска
     */
    public List findAll(String startPath) throws Exception {
        return find(startPath, "", ALL);
    }

    /**
     * Этот метод выполняет поиск объектов (файлов и директорий),
     * которые соответствуют заданному регулярному выражению (mask),
     * начиная с заданной директории (startPath)
     * @param startPath Начальная директория поиска
     * @param mask регулярное выражение, которому должны соответствовать
     * имена найденный объектов
     * @throws java.lang.Exception если возникли ошибки в процессе поиска
     * @return Список (List) найденных объектов
     */
    public List findAll(String startPath, String mask)
            throws Exception {
        return find(startPath, mask, ALL);
    }

    /**
     * Этот метод выполняет поиск всех файлов,
     * начиная с заданной директории (startPath)
     * @param startPath Начальная директория поиска
     * @return Список (List) найденных объектов
     * @throws java.lang.Exception если возникли ошибки в процессе поиска
     */
    public List findFiles(String startPath)
            throws Exception {
        return find(startPath, "", FILES);
    }

    /**
     * Этот метод выполняет поиск файлов,
     * которые соответствуют заданному регулярному выражению (mask),
     * начиная с заданной директории (startPath)
     * @param startPath Начальная директория поиска
     * @param mask регулярное выражение, которому должны соответствовать
     * имена найденный объектов
     * @throws java.lang.Exception если возникли ошибки в процессе поиска
     * @return Список (List) найденных объектов
     */
    public List findFiles(String startPath, String mask)
            throws Exception {
        return find(startPath, mask, FILES);
    }

    /**
     * Этот метод выполняет поиск всех директорий (папок),
     * начиная с заданной директории (startPath)
     * @param startPath Начальная директория поиска
     * @return Список (List) найденных объектов
     * @throws java.lang.Exception если возникли ошибки в процессе поиска
     */
    public List findDirectories(String startPath)
            throws Exception {
        return find(startPath, "", DIRECTORIES);
    }

    /**
     * Этот метод выполняет поиск директорий (папок),
     * которые соответствуют заданному регулярному выражению (mask),
     * начиная с заданной директории (startPath)
     * @param startPath Начальная директория поиска
     * @param mask регулярное выражение, которому должны соответствовать
     * имена найденный объектов
     * @throws java.lang.Exception если возникли ошибки в процессе поиска
     * @return Список (List) найденных объектов
     */
    public List findDirectories(String startPath, String mask)
            throws Exception {
        return find(startPath, mask, DIRECTORIES);
    }

    /**
     * Возвращает суммарный размер найденных файлов
     * @return размер найденных файлов (байт)
     */
    public long getDirectorySize() {
        return totalLength;
    }

    /**
     * Возвращает общее количество найденных файлов
     * @return количество найденных файлов
     */
    public long getFilesNumber() {
        return filesNumber;
    }

    /**
     * Возвращает общее количество найденных директорий (папок)
     * @return количество найденных директорий (папок)
     */
    public long getDirectoriesNumber() {
        return directoriesNumber;
    }

    /*
    Проверяет, соответствует ли имя файла заданному
    регулярному выражению. Возвращает true, если найденный
    объект соответствует регулярному выражению, false - в
    противном случае.
    */
    private boolean accept(String name) {
        //если регулярное выражение не задано...
        if(p == null) {
            //...значит объект подходит
            return true;
        }
        //создаем Matcher
        m = p.matcher(name);
        //выполняем проверку
        if(m.matches()) {
            return true;
        }
        else {
            return false;
        }
    }

    /*
    Этот метод выполняет начальные установки поиска.
    Затем вызывает метод search для выполнения поиска.
    */
    private List find(String startPath, String mask, int objectType)
            throws Exception {
        //проверка параметров
        if(startPath == null || mask == null) {
            throw new Exception("Ошибка: не заданы параметры поиска");
        }
        File topDirectory = new File(startPath);
        if(!topDirectory.exists()) {
            throw new Exception("Ошибка: указанный путь не существует");
        }
        //если задано регулярное выражение, создаем Pattern
        if(!mask.equals("")) {
            p = Pattern.compile(mask,
                    Pattern.CASE_INSENSITIVE | Pattern.UNIcomment_CASE);
        }
        //обнуляем все счетчики
        filesNumber = 0;
        directoriesNumber = 0;
        totalLength = 0;
        //создаем список результатов
        ArrayList res = new ArrayList(100);

        //выполняем поиск
        search(topDirectory, res, objectType);

        //присваиваем null шаблону, т.к. при следующем вызове find...
        //регулярное выражение может быть не задано
        p = null;
        //возвращаем результат
        return res;
    }

    /*
    Этот метод выполняет поиск объектов заданного типа.
    Если, в процессе поиска, встречает вложенную директорию
    (папку), то рекурсивно вызывает сам себя.
    Результаты поиска сохраняются в параметре res.
    Текущая директория - topDirectory.
    Тип объекта (файл или директория) - objectType.
    */
    private void search(File topDirectory, List res, int objectType) {
        //получаем список всех объектов в текущей директории
        File[] list = topDirectory.listFiles();
        //просматриваем все объекты по-очереди
        for(int i = 0; i &lt; list.length; i++) {
            //если это директория (папка)...
            if(list[i].isDirectory()) {
                //...выполняем проверку на соответствие типу объекта
                // и регулярному выражению...
                if(objectType != FILES &amp;&amp; accept(list[i].getName())) {
                    //...добавляем текущий объект в список результатов,
                    //и обновляем значения счетчиков
                    directoriesNumber++;
                    res.add(list[i]);
                }
                //выполняем поиск во вложенных директориях
                search(list[i], res, objectType);
            }
            //если это файл
            else {
                //...выполняем проверку на соответствие типу объекта
                // и регулярному выражению...
                if(objectType != DIRECTORIES &amp;&amp; accept(list[i].getName())) {
                    //...добавляем текущий объект в список результатов,
                    //и обновляем значения счетчиков
                    filesNumber++;
                    totalLength += list[i].length();
                    res.add(list[i]);
                }
            }
        }
    }
}</pre>
<p>Как видите, ничего сложного. Большая часть – это комментарии.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/poisk-fajlov.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Средства разработки Java приложений: необходимые и просто полезные программы</title>
		<link>http://www.simplecoding.org/sredstva-razrabotki-na-java-neobxodimye-i-prosto-poleznye-programmy.html</link>
		<comments>http://www.simplecoding.org/sredstva-razrabotki-na-java-neobxodimye-i-prosto-poleznye-programmy.html#comments</comments>
		<pubDate>Sat, 18 Aug 2007 18:04:37 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/sredstva-razrabotki-na-java-neobxodimye-i-prosto-poleznye-programmy.html</guid>
		<description><![CDATA[Обзор средств разработки на Java]]></description>
			<content:encoded><![CDATA[<p>Какой бы язык программирования вы не начали изучать, вам неизбежно придётся столкнуться с проблемой выбора нужных для разработки программ.<br />
Программирование на Java не исключение. Скорее наоборот. Количество различных сред разработки исчисляется десятками.<br />
В этой статье я хочу рассказать о минимально необходимом комплекте инструментов для разработки на Java, и о некоторых программах, которые значительно облегчают жизнь программиста.<br />
<span id="more-50"></span><br />
<strong>Необходимые программы</strong><br />
Одно из значительных, на мой взгляд, преимуществ Java перед другими языками программирования, это наличие бесплатных интегрированных сред разработки (IDE), которые по возможностям практически не уступают их коммерческим аналогам.</p>
<p>Я не собираюсь приводить подробный анализ каждой программы. Это не реально сделать в одной статье (даже очень большой:-)). Я просто расскажу о доступных и бесплатных инструментах, которыми сам пользуюсь.</p>
<p>Итак, начнём с необходимых программ.</p>
<p>Разработчиком языка Java является <a href="http://www.sun.com/">Sun Microsystems</a>. Она же и предоставляет необходимое программное обеспечение (<a href="http://www.sun.com/">http://java.sun.com/</a>).</p>
<p>Для запуска программ нам понадобится среда выполнения Java – Java Runtime Environment (JRE).</p>
<p>Т.к. одним запуском программ мы не ограничиваемся, то следующим у нас по списку идет комплект разработки программного обеспечения – JDK (Java Development Kit). Он содержит компилятор, стандартные библиотеки и т.п.</p>
<p>Тут необходимы некоторые пояснения. Существует три Java платформы:</p>
<p>1. Java 2 Standard Edition (J2SE)<br />
2. Java 2 Enterprise Edition (J2EE)<br />
3. Java 2 Micro Edition (J2ME)</p>
<p>Каждая из этих платформ предназначена для разработки своего типа программ.</p>
<p>Первая (J2SE) позволяет разрабатывать обычные (desktop) приложения и апплеты (по-сути такие же приложения, только с возможностью внедрения в html-страницу).</p>
<p>Вторая (J2EE) предназначена для разработки серверных приложений (сервлетов, jsp-страниц, компонентов JavaBeans). По сути, J2EE это J2SE плюс Java System Application Server (сервер приложений) и дополнительные библиотеки.</p>
<p>Третья (J2ME) – это платформа для мобильных устройств. Она не входит ни в одну из предыдущих, хотя похожа на J2SE. Дело в том, что мобильные устройства (телефоны, КПК и т.д.) обладают значительно меньшими ресурсами, по сравнению с обычными компьютерами и ноутбуками. И это касается не только памяти и процессора, но и размеров экрана и клавиатуры. Поэтому в J2ME большинство библиотек имеют ограниченный набор возможностей, по сравнению с J2SE, или вообще совершенно другие.</p>
<p>Завершает список минимально необходимых программ текстовый редактор. Очень желательно с подсветкой синтаксиса.</p>
<p>Выбор тут очень большой. От простейших, вроде Блокнота, до достаточно &#034;продвинутых&#034;, например, syn Text Editor.</p>
<p>Советую обратить внимание на Notepad++, syn Text Editor, PSPad. Все они обеспечивают подсветку синтаксиса, работу с несколькими файлами (в табах), подсветку скобок ({}) и т.п.</p>
<p>Наличие такого редактора полезно, даже если вы используете IDE. Потому что очень часто нужно просто посмотреть какой-нибудь файл, а в IDE открыть другой проект, и открывать в ней дополнительные файлы не очень удобно, возникает путаница.</p>
<p>Таким образом, мы имеем минимальный комплект для разработки программ на Java:</p>
<ul>
<li>JRE – среда выполнения;</li>
<li>JDK для соответствующей платформы (J2SE, J2EE, J2ME) – компилятор и библиотеки;</li>
<li>текстовый редактор.</li>
</ul>
<p>Минимальный комплект даёт возможность писать программы, но не более того. Каждая операция (компиляция, запуск, создание jar-файла) потребует введения длинных команд в консоли. Ясно, что это дело быстро надоест.</p>
<p>Тут очень пригодиться программа под названием <a href="http://ant.apache.org/">Apache Ant</a>. По сути, это аналог утилиты make, только кроссплатформенный и ориентированный на использование с Java. С его помощью можно автоматизировать практически любую последовательность операций. Например, вы можете выполнить компиляцию проекта, протестировать его и упаковать в jar-архив с помощью всего одной команды. Для этого нужно только создать build-файл с соответствующими задачами. Подробнее о том, как это сделать, можно почитать в статье: <a href="nastrojka-i-ispolzovanie-apache-ant.html">Настройка и использование Apache Ant</a>.<br />
В общем, Ant приобрёл очень широкое распространение, и используется как составляющая часть многих Java IDE.</p>
<p>Теперь перейдём к более &#034;продвинутым&#034; средствам разработки, т.е. интегрированным средам разработки (IDE).</p>
<p>Как я уже говорил, выбор довольно большой. Но я бы хотел выделить две: <a href="http://www.netbeans.org/">NetBeans</a> и <a href="http://www.eclipse.org/">Eclipse</a>. Почему именно эти? Все просто. Во-первых, они полностью бесплатные. Во-вторых, они поддерживают разработку на всех трёх платформах (J2SE, J2EE, J2ME).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/sredstva-razrabotki-na-java-neobxodimye-i-prosto-poleznye-programmy.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Анализ данных с помощью регулярных выражений или быстрый способ проверки введенных данных</title>
		<link>http://www.simplecoding.org/analiz-dannyx-s-pomoshhyu-regulyarnyx-vyrazhenij-ili-bystryj-sposob-proverki-vvedennyx-dannyx.html</link>
		<comments>http://www.simplecoding.org/analiz-dannyx-s-pomoshhyu-regulyarnyx-vyrazhenij-ili-bystryj-sposob-proverki-vvedennyx-dannyx.html#comments</comments>
		<pubDate>Sat, 18 Aug 2007 17:21:22 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/analiz-dannyx-s-pomoshhyu-regulyarnyx-vyrazhenij-ili-bystryj-sposob-proverki-vvedennyx-dannyx.html</guid>
		<description><![CDATA[Эта статья рассказывает об использовании регулярных выражений (regular expressions) для проверки введенных данных]]></description>
			<content:encoded><![CDATA[<p>Все, кто хоть немного занимается программированием, сталкивались с проблемой правильности ввода данных. Основная сложность заключается в том, что большинство людей не любят читать справку к программе, не любят по несколько раз проверять введённые данные, зато очень любят быстро нажимать на все кнопки подряд, и громко жаловаться на малейшие ошибки в программе:-).<br />
<span id="more-44"></span><br />
<strong>Регулярные выражения. Зачем они нужны?</strong><br />
Кроме того, существуют объективные причины возникновения ошибок. Например, усталость или некачественно составленная документация.</p>
<p>Все это приводит к тому, что программист вынужден тщательно проверять вводимые данные, и сообщать обо всех ошибках пользователю, объясняя при этом как эту ошибку исправить.</p>
<p>В большинстве случаев данные от пользователя поступают в виде текстовых строк. Т.е. нам нужно преобразовать данные к определённому типу.<br />
И вот здесь все зависит от того, какие именно данные мы хотим получить.<br />
Если нам нужен просто какой-нибудь текст (например, имя пользователя), то проверка достаточно простая:</p>
<pre class="brush: java">if(name == null || name.equals("")) {
//сообщение об ошибке
}</pre>
<p>Мы просто убеждаемся, что что-то введено.<br />
Проверить правильность ввода чисел тоже несложно. Можно воспользоваться методами <code>parse</code>… классов <code>Double</code>, <code>Integer</code> и т.п.</p>
<p>Например,</p>
<pre class="brush: java">try {
    int v = Integer. parseInt(inputString);
}
catch(NumberFormatException err) {
// сообщение об ошибке
}</pre>
<p>Но, есть данные, для которых используется специальная форма записи. Например, адреса eMail, телефонные номера и т.п.</p>
<p>Проверку таких данных выполнить сложнее. Нужно проверять наличие обязательных элементов (например, символ @ в адресе eMail), их взаимное расположение и т.д.<br />
Кроме того, могут возникнуть дополнительные задачи. Например, выделение кода города из телефонного номера.<br />
Конечно, для выполнения таких проверок можно написать специальную функцию, содержащую один или несколько циклов, в которых будет выполняться проверка соответствия строки всем требованиям. Но в этом случае, зачастую, получается, что объем кода, выполняющего эти проверки, составляет, чуть ли не половину всей программу (если не больше).</p>
<p>К счастью, существует ряд методов, позволяющих существенно упростить задачу.<br />
Об одном из них я и хочу рассказать. Этот метод заключается в использовании регулярных выражений (regular expressions).<br />
Никогда о них не слышали? Не страшно. Я уверен, что вы постоянно ими пользуетесь. Например, если вам нужно найти все файлы с расширением mp3, то в программе поиска вы пишите &#034;*.mp3&#034;. Это и есть регулярное выражение. В данном случае программа поиска выдаст вам список файлов, у которых имя состоит из любого количества любых символов, после имени идет символ &#034;.&#034;, а за ним – &#034;*mp3&#034;. Если вы напишите &#034;A*.mp3&#034;, то получите список файлов, которые начинаются на букву &#034;A&#034;, и имеют расширение &#034;mp3&#034;.</p>
<p>Вообще, регулярное выражение представляет собой шаблон, с которым можно сравнивать текстовые строки. В приведённом примере, программа поиска сравнивает все имена файлов с заданным шаблоном, и показывает только те, которые с ним совпали.</p>
<p>Средства Java для работы с регулярными выражениями</p>
<p>В стандартную библиотеку Java входит пакет, специально предназначенный для работы с регулярными выражениями &#8211; <code>java.util.regex</code>.<br />
Эта библиотека может быть использована для выполнения таких задач:</p>
<ul>
<li>поиск данных;</li>
<li>проверка данных;</li>
<li>выборочное изменение данных;</li>
<li>выделение фрагментов данных;</li>
<li>и др..</li>
</ul>
<p>Получить подробную информацию о библиотеке можно из официальной справки к JavaSDK, размещённой на сайте <a href="http://java.sun.com/">java.sun.com</a>. Здесь же можно почитать The Java Tutorial (учебное пособие по Java), в котором регулярным выражениям посвящён отдельный урок.</p>
<p>В этой статье я хочу показать примеры использования регулярных выражений для проверки правильности ввода данных, и извлечения фрагментов этих данных.<br />
Основную работу выполняют два класса: <code>Pattern</code> и <code>Matcher</code>.<br />
<code>Pattern</code> – представляет собой сам шаблон, т.е. наше регулярное выражение.<br />
<code>Matcher</code> – это объект, который выполняет сравнение заданной строки с шаблоном.<br />
Для того чтобы создать объект типа <code>Pattern</code> нужно воспользоваться его статическим методом<br />
<code>compile(&lt; регулярное выражение &gt;)</code> или<br />
<code>compile(&lt; регулярное выражение &gt;, &lt;параметры&gt;)</code>.<br />
Создать <code>Matcher</code> можно с помощью объекта <code>Pattern</code>.</p>
<p>Например, так:</p>
<pre class="brush: java">Pattern p = Pattern.compile("^\\s+",
    Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(inputString);</pre>
<p>После этого можно сравнивать шаблон со строкой, выполнять поиск нужных фрагментов и т.д.<br />
Но, прежде всего, давайте разберёмся, как составлять регулярные выражения.</p>
<p>В простейшем случае регулярное выражение представляет собой просто текст, например, &#034;стол&#034;. Такое выражение можно использовать для поиска слова &#034;стол&#034; в строке, для замены этого слова на какое-нибудь другое и т.д..</p>
<p>Для создания более сложных выражений используются специальные символы (метасимволы). К ним относятся: <code>([{\^$|)?*+.</code>. Эти символы имеют специальное значение, которое зависит от их положения в выражении.</p>
<p>Но, что будет, если мы захотим использовать эти символы в выражении в их обычном значении? Для этого нужно перед этим символом поставить <code>\</code>.</p>
<p>Внимание: если регулярное выражение записано в программе, а не читается из файла или формы, то необходимо использовать два символа <code>\</code> подряд (<code>\\</code>). Вы, конечно, помните, что при обработке строк Java считает символ <code>\</code> служебным (начало эскейп-последовательности), а для того, чтобы получить просто <code>\</code> нужно ввести <code>\\</code>.</p>
<p>Теперь посмотрим, как можно использовать специальные символы при составлении выражений. Наверное, наиболее распространённый символ – это "<code>.</code>". Он означает – любой символ. Если поставить справа от символа знак "<code>+</code>", то это будет означать, что предыдущий символ может встречаться несколько раз. Поясню сказанное на простых примерах:<br />
выражение "<code>.+</code>" будет соответствовать любому тексту (один или более любых символов);<br />
"<code>A.+</code>" – любое выражение, которое начинается на букву "А".<br />
Если мы хотим найти текст с известным расположением в строке, то можно воспользоваться символами:<br />
<code>^</code> - начало строки<br />
<code>$</code> - конец строки</p>
<p>С помощью квадратных скобок (<code>[]</code>) можно задать класс символов. Класс символов задаёт некоторый набор символов, который можно использовать в выражениях. Например, выражение &#034;<code>[кп]от</code>&#034; соответствует словам &#034;кот&#034; и &#034;пот&#034;.<br />
Вот ещё несколько примеров использования классов символов.</p>
<table style="border-collapse: collapse; font-size: 90%">
<tr>
<td style="border: 1px solid #000000; width: 20%"><code>[^abc]</code></td>
<td style="border: 1px solid #000000">любые символы кроме abc (в данном случае символ ^ используется как отрицание)</td>
</tr>
<tr>
<td style="border: 1px solid #000000"><code>[a-d[m-p]]</code></td>
<td style="border: 1px solid #000000">любые символы от a до d и от m до p (по алфавиту)</td>
</tr>
<tr>
<td style="border: 1px solid #000000"><code>[a-z&amp;&amp;[^bc]]</code></td>
<td style="border: 1px solid #000000">любые символы от a до z кроме b и c</td>
</tr>
</table>
<p>Кроме этого существуют, так называемые предопределённые классы. Например,</p>
<table style="border-collapse: collapse; font-size: 90%">
<tr>
<td style="border: 1px solid #000000; width: 20%"><code>\d</code></td>
<td style="border: 1px solid #000000">означает любую цифру</td>
</tr>
<tr>
<td style="border: 1px solid #000000"><code>\D</code></td>
<td style="border: 1px solid #000000">любые символы кроме цифр</td>
</tr>
<tr>
<td style="border: 1px solid #000000">\s</td>
<td style="border: 1px solid #000000">пробельные символы (<code>[ \t\n\x0B\f\r]</code>)</td>
</tr>
<tr>
<td style="border: 1px solid #000000"><code>\S</code></td>
<td style="border: 1px solid #000000">любые символы кроме пробельных</td>
</tr>
<tr>
<td style="border: 1px solid #000000"><code>\w</code></td>
<td style="border: 1px solid #000000">любые текстовые символы <code>[a-zA-Z_0-9]</code>  (как вы заметили сюда символы русского алфавита не входят, как их включить, я покажу позже)</td>
</tr>
<tr>
<td style="border: 1px solid #000000"><code>\W</code></td>
<td style="border: 1px solid #000000">любые не текстовые символы</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/analiz-dannyx-s-pomoshhyu-regulyarnyx-vyrazhenij-ili-bystryj-sposob-proverki-vvedennyx-dannyx.html/feed</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Тщательная перетасовка колоды карт. Пример Java приложения.</title>
		<link>http://www.simplecoding.org/tshhatelnaya-peretasovka-kolody-kart.html</link>
		<comments>http://www.simplecoding.org/tshhatelnaya-peretasovka-kolody-kart.html#comments</comments>
		<pubDate>Fri, 17 Aug 2007 13:14:47 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/tshhatelnaya-peretasovka-kolody-kart.html</guid>
		<description><![CDATA[Описание алгоритма тщательной перетасовки колоды карт]]></description>
			<content:encoded><![CDATA[<p>В данной статье я бы хотел показать один из вариантов алгоритма, выполняющего перетасовку колоды игральных карт, и, безусловно, обсудить его достоинства и недостатки.<br />
<span id="more-40"></span><br />
Если вы захотите написать программу для игры в карты, то неизбежно столкнетесь с необходимостью перетасовки колоды карт. Обычно, эта операция выполняется перед каждой сдачей карт, то есть, возможно, десятки раз за игру (в зависимости от правил конкретной игры). Поэтому качество выполнения данной операции может существенно сказаться на результатах игры.</p>
<p>На первый взгляд, в решении этой задачи нет ничего сложного. Нужно просто поменять местами карты в колоде так, чтобы они располагались случайным образом. Но что означает &#034;случайным образом&#034;? Ответ простой: &#034;Во взаимном расположении карт не должно быть никаких закономерностей&#034;. Но ведь компьютер выполняет только то, что написано в программе. Команды из серии: &#034;Возьми то, не знаю что&#034;, тут не проходят. Поэтому в первую очередь нам нужен источник случайных чисел.</p>
<p>И вот тут возникает проблема. На сегодняшний день не существует источника по-настоящему случайных чисел. Но зато есть огромное количество алгоритмов, которые позволяют получать, так называемые, псевдослучайные числа. Практически каждый язык программирования имеет встроенные функции для генерирования псевдослучайных последовательностей чисел. Разница между случайными и псевдослучайными числами в том, что последние получены с использованием какого-то алгоритма. А это означает наличие некоторой закономерности в появлении таких чисел.</p>
<p>Я не буду анализировать особенности этих алгоритмов, это тема не статьи, а книги (скорее нескольких). Те, кому интересно, могут посмотреть литературу по вычислительной математике или теории чисел.</p>
<p>В этой статье я расскажу о возможностях, которые нам предоставляет стандартная библиотека языка Java. Есть два варианта. Первый – использовать метод random() класса java.lang.Math.. Второй – воспользоваться одним из методов класса java.util.Random.</p>
<p>Мы будем использовать второй вариант, т.к. он обеспечивает более широкую функциональность.</p>
<p>В первую очередь, я хочу показать, что этот класс генерирует псевдослучайные числа. Напишем простенькую программку:</p>
<pre class="brush: java">import java.util.Random;public class Main {
public Main() {
    }
public static void main(String[] args) {
        //создаем новый генератор псевдослучайных чисел, и задаем
        //начальное значение для алгоритма генерации чисел
        Random generator = new Random(20);
        //выводим десять случайных чисел
        for(int i = 0; i &lt; 10; i++) {
            if(i == 9) {
                System.out.println(generator.nextInt(100));
            }
            else {
                System.out.print(generator.nextInt(100) + "; ");
            }
        }
    }
}</pre>
<p>Тут все предельно просто. Программа генерирует 10 случайных чисел, и выводит их в одну строку. Если мы запустим программу 3 раза подряд, то получим три строки с числами:<br />
<code>53; 36; 1; 61; 5; 95; 33; 55; 93; 88<br />
53; 36; 1; 61; 5; 95; 33; 55; 93; 88<br />
53; 36; 1; 61; 5; 95; 33; 55; 93; 88</code><br />
Как видите, все строки одинаковые. Это происходит из-за того, что аргументом в конструкторе класса Random у нас является одно и то же число (20). Кстати, если использовать конструктор без аргументов, то начальное значение будет выбрано по специальному алгоритму, и генерируемые числа будут разными.</p>
<p>Но я не зря использовал именно этот конструктор. Дело в том, что в качестве начального значения для генератора случайных чисел можно использовать текущее значение системного времени. Действительно, нельзя точно предугадать в какой момент времени пользователь запустит программу, миллисекундой раньше, миллисекундой позже&#8230;</p>
<p>Создать генератор случайных чисел, с системным временем в качестве базового числа, можно так:</p>
<pre class="brush: java">Random generator = new Random(new Date().getTime());</pre>
<p>Или, если у вас уже есть объект типа Random:</p>
<pre class="brush: java">generator.setSeed(new Date().getTime());</pre>
<p>Итак, с созданием случайных чисел разобрались. Переходим непосредственно к алгоритму перетасовки карт.<br />
Прежде всего, просмотрите его исходный код, а затем я объясню, как это все работает.</p>
<pre class="brush: java">public static void reshuffle(int[] pack) {
    if(pack != null) {
        int length = pack.length;
        //создаем генератор случайных чисел, в качестве начального
        //значения передаем системное время
        Random generator = new Random(new Date().getTime());
        //тосуем колоду карт
        //перебираем все карты колоды
        for(int i = 0; i &lt; length; i++) {
            //генерируем случайное число, в диапазоне от нуля до
            //конца колоды
            int newPos = generator.nextInt(length);
            //меняем местами текущую карту с картой, которая находится
            //в pack[newPos]
            int curCard = pack[i];
            pack[i] = pack[newPos];
            pack[newPos] = curCard;
            //для увеличения эффекта "случайности" возникновения чисел,
            //в течении перетасовки колоды, четыре раза устанавливаем
            //новое начальное значение генератора случайных чисел
            if(i%(length/4) == 0) {
                //генерируем случайный интервал времени (мс)
                int pause = generator.nextInt(20);
                try {
                    //останавливаем работу программы на полученный
                    //интервал времени (максимально возможная задержка
                    //восемдесят миллисекунд)
                    Thread.currentThread().sleep(pause);
                }
                catch (InterruptedException ex) {}
                //уставливаем новое начальное значение генератора
                generator.setSeed(new Date().getTime());
            }
        }
    }
}</pre>
<p>За основу я взял давно известный алгоритм, но для увеличения степени “случайности” возникновения чисел, ввел несколько изменений.</p>
<p>Допустим, у нас есть колода из 36 карт. Для её хранения мы используем массив из 36 элементов, каждый из которых может принимать значения от 0 до 35.</p>
<p>Перетасовка выполняется следующим образом. Мы последовательно перебираем все ячейки массива с картами. Для каждой ячейки мы генерируем случайное число (newPos) в диапазоне от 0 до 35. Это число является новым положением карты в массиве. Т.е. мы меняем местами текущую карту с картой, которая лежит в ячейке с индексом newPos.</p>
<p>Теперь обратите внимание на строки начиная с if(i%(length/4) == 0) {. Этот блок кода будет выполняться четыре раза в течение работы метода. Принцип работы следующий. В первую очередь мы получаем случайное число в диапазоне от 0 до 20. Почему выбран именно этот диапазон, я объясню чуть позже. Это число задает время, на которое программа приостанавливает свою работу.</p>
<p>Остановка программы выполняем с помощью метода sleep(). После этого, мы опять устанавливаем текущее время в качестве нового базового значения для генератора случайных чисел.</p>
<p>Теперь разберемся, что все это нам дает. В первую очередь увеличивается время выполнения перетасовки. Это, конечно, не очень хорошо, но давайте подумаем. Максимально возможная задержка составляет 80 мс. Данный алгоритм предназначен для использования в карточных играх, в которых, при перетасовке карт, игроку обычно показывают какую-нибудь анимацию (это увеличивает реалистичность игры). Длительность такой анимации обычно около секунды или больше (игрок должен хоть что-то рассмотреть:-)). Т.е., за время этой анимации, можно будет раз десять перетасовать колоду.</p>
<p>А теперь посмотрим на сильные стороны этого алгоритма. Мы четыре раза устанавливаем новое базовое число. Предсказать значение этого числа практически невозможно, и не только потому, что длительность паузы мы выбираем случайным образом. Любая современная операционная система вносит дополнительный эффект случайности в работу алгоритма. Дело в том, что в системе выполняется одновременно несколько десятков процессов (программ). Но один процессор (не многоядерный) может выполнять одновременно только одну программу. Поэтому для создания эффекта многозадачности используется специальная программа – планировщик, которая переключает процессы. Сначала выполняется несколько команд из одной программы, потом – несколько из другой, и так далее. Порядок переключения программ зависит от многих причин. Это и приоритеты процессов, и тактовая частота процессора, и версия операционной системы, и многое другое.</p>
<p>Таким образом, существует высокая вероятность того, что выполнение нашего метода перетасовки будет прервано планировщиком (и не один раз). Системное время, естественно, не зависит от порядка работы нашей программы, и значения, которые возвращает метод getTime() предсказать практически невозможно. А именно этого мы и добиваемся.</p>
<p>Для тестирования работы алгоритма я написал небольшую программу. В неё входят 3 файла с исходными кодами. Reshuffler.java – имеет один статический метод, который и выполняет перетасовку карт. CardsPack.java – этот файл, содержит класс, который используется для создания колоды карт. Он содержит два метода: getPackOfCards() – возвращает массив с номерами карт;<br />
toString() – возвращает строку с названиями карт в колоде.<br />
Оба эти метода находятся в пакете cards.tools.<br />
Main.java – содержит класс с функцией main, которая выполняет следующие операции:</p>
<ul>
<li>создает новую колоду;</li>
<li>выводит её содержимое;</li>
<li>перетасовывает колоду;</li>
<li>и опять выводит её содержимое.</li>
</ul>
<p>Теперь посмотрим результаты работы программы:</p>
<table style="border: 1px solid #000000; border-collapse: collapse; font-size: 90%">
<tr>
<td style="border: 1px solid #000000"><strong>Начальное расположение карт в колоде</strong></td>
<td style="border: 1px solid #000000"><strong>Расположение карт после сортировки</strong></td>
</tr>
<tr>
<td style="border: 1px solid #000000">шестерка пик<br />
семерка пик<br />
восьмерка пик<br />
девятка пик<br />
десятка пик<br />
валет пик<br />
дама пик<br />
король пик<br />
туз пик<br />
шестерка треф<br />
семерка треф<br />
восьмерка треф<br />
девятка треф<br />
десятка треф<br />
валет треф<br />
дама треф<br />
король треф<br />
туз треф<br />
шестерка бубен<br />
семерка бубен<br />
восьмерка бубен<br />
девятка бубен<br />
десятка бубен<br />
валет бубен<br />
дама бубен<br />
король бубен<br />
туз бубен<br />
шестерка червей<br />
семерка червей<br />
восьмерка червей<br />
девятка червей<br />
десятка червей<br />
валет червей<br />
дама червей<br />
король червей<br />
туз червей</td>
<td style="border: 1px solid #000000">король пик<br />
десятка червей<br />
король червей<br />
восьмерка червей<br />
девятка треф<br />
валет червей<br />
восьмерка треф<br />
десятка пик<br />
шестерка треф<br />
семерка треф<br />
шестерка бубен<br />
король бубен<br />
туз треф<br />
валет пик<br />
туз бубен<br />
девятка пик<br />
король треф<br />
валет бубен<br />
восьмерка пик<br />
дама пик<br />
дама треф<br />
девятка червей<br />
семерка бубен<br />
туз червей<br />
десятка треф<br />
семерка червей<br />
шестерка червей<br />
десятка бубен<br />
дама бубен<br />
восьмерка бубен<br />
девятка бубен<br />
туз пик<br />
шестерка пик<br />
семерка пик<br />
дама червей<br />
валет треф</td>
</tr>
</table>
<p>Как видите, у нас все получилось.</p>
<p><strong>Скачать исходный код проекта:</strong> <a href="http://www.simplecoding.org/wp-content/uploads/2007/08/cards_reshuffler_src.zip" title="cards_reshuffler_src.zip (2,6 кБ)">cards_reshuffler_src.zip (2,6 кБ)</a>.</p>
<p><strong>Скачать программу:</strong><a href="http://www.simplecoding.org/wp-content/uploads/2007/08/cards_reshuffler_prog.zip" title="cards_reshuffler_prog.zip (2,3 кБ)">cards_reshuffler_prog.zip (2,3 кБ)</a>.</p>
<p>Желаю успехов.</p>
<p><strong>Постовой</strong></p>
<p><a href="http://polinar.com.ua/ozon.htm">центр озонотерапии</a><br />
<a href="http://polinar.com.ua/psycho.htm">клиническая психотерапия</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/tshhatelnaya-peretasovka-kolody-kart.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Настройка и использование Apache Ant для разработки Java приложений</title>
		<link>http://www.simplecoding.org/nastrojka-i-ispolzovanie-apache-ant.html</link>
		<comments>http://www.simplecoding.org/nastrojka-i-ispolzovanie-apache-ant.html#comments</comments>
		<pubDate>Fri, 17 Aug 2007 11:48:48 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/nastrojka-i-ispolzovanie-apache-ant.html</guid>
		<description><![CDATA[использование Apache Ant]]></description>
			<content:encoded><![CDATA[<p>Практически все, кто когда-нибудь занимался программированием на Java, слышали о программе под названием <a href="http://ant.apache.org/">Apache Ant</a>. Её используют большинство современных сред разработки, такие как <a href="http://www.eclipse.org/">Eclipse</a>, <a href="http://www.netbeans.org/">NetBeans</a> и многие другие. Так чем же объясняется такая популярность Ant?<br />
<span id="more-38"></span><br />
<strong>Вступление, или несколько слов о том, зачем это надо</strong></p>
<p>Давайте разбираться по порядку. Ant – это инструмент для работы с проектами, в самом широком смысле. С его помощью можно выполнить компиляцию, отладку и тестирование проекта, создавать новые и удалять существующие файлы и папки, создавать архивы с исходными кодами, и многое другое. Перечень функций, которые поддерживает Ant, занимает несколько страниц, кроме того, вы можете создавать свои собственные функции.</p>
<p>Тут возникает вопрос: &#034;Ну и что, все эти операции можно выполнить и без Ant&#034;. Да, можно, но Ant даёт возможность это сделать с помощью всего одной команды. Это не только ускоряет работу, но и страхует от ошибок. При выполнении длинной цепочки действий всегда можно что-нибудь забыть.</p>
<p>Естественно, все эти операции Ant выполняет с помощью дополнительных средств, например, для компиляции проекта у вас должен быть установлен <a href="http://java.sun.com/">Java SDK</a> (software development kit). Сам по себе, Ant выполняет чтение и анализ специального файла (обычно он называется <code>build.xml</code>), который содержит команды для работы с проектом. Этот файл вы можете создать сами, либо с помощью вашей IDE в ходе разработки проекта.</p>
<p>Как создать такой файл мы рассмотрим чуть позже, а пока разберёмся, какие преимущества нам даёт использование Ant.<br />
Рассмотрим простой пример. Допустим, у нас есть проект, состоящий из одного файла (hello.java) с, наверное, самой популярной в мире программой &#034;Hello, World!&#034;.</p>
<p>Наши задачи:<br />
1) скомпилировать программу;<br />
2) запустить её (для проверки работоспособности);<br />
3) создать jar-файл (файл manifest.mf у нас есть);<br />
4) создать архив с исходниками (например, для размещения в Internet).</p>
<p>В классическом варианте (без использования IDE) для первых трех пунктов вы должны выполнить примерно такой набор команд:</p>
<p><code>javac hello.java<br />
java hello<br />
jar cmf hello.jar manifest.mf hello.class</code></p>
<p>Четвёртый пункт выполняется с помощью вашего любимого архиватора.</p>
<p>Ясно, что писать эти команды после каждого изменения в проекте быстро надоест, особенно, если ваш проект состоит из десятков или сотен файлов, которые расположены в разных папках.<br />
Конечно, самый простой способ решения этой проблемы – использовать какую-нибудь IDE. В этом случае для выполнения первых трех пунктов будет достаточно нажать одну кнопку.<br />
Но вот четвёртый пункт вам, скорее всего, придётся выполнять вручную. А это потенциальный источник ошибок. Можно легко забыть добавить в архив папку с ресурсами к программе, или с тестами, или ещё с чем-нибудь.<br />
Кроме того, у вас могут быть чужие исходники, например, примеры к документации, которые нужно просто запустить, а не заниматься их импортированием в IDE. Или вы хотите передать кому-нибудь свою программу в виде исходных кодов, а этот человек пользуется другой IDE.</p>
<p>Во всех этих случаях использование Ant значительно облегчит вам жизнь.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/nastrojka-i-ispolzovanie-apache-ant.html/feed</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Пример Java приложения. CNC 1.1 &#8211; калькулятор комплексных чисел</title>
		<link>http://www.simplecoding.org/cnc-11-kalkulyator-kompleksnyx-chisel.html</link>
		<comments>http://www.simplecoding.org/cnc-11-kalkulyator-kompleksnyx-chisel.html#comments</comments>
		<pubDate>Fri, 17 Aug 2007 08:06:28 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/cnc-11-kalkulyator-kompleksnyx-chisel.html</guid>
		<description><![CDATA[Программирование на Java, CNC 1.1 - калькулятор]]></description>
			<content:encoded><![CDATA[<p><strong>CNC 1.1 (Complex Number Calculator) &#8211; калькулятор комплексных чисел</strong><br />
Эта программа представляет собой обычный калькулятор с поддержкой комплексных чисел. Использовать её очень просто. Вы вводите математическое выражение, нажимаете кнопку &#034;=&#034;, и получаете ответ.<br />
<span id="more-34"></span><br />
Пользоваться апплетом очень просто. Вводите выражение, которое нужно вычислить в верхнее окно, например, &#034;<code>(1,3 + 4,5)*(3 - 2i) - 4i</code>&#034; и нажимаете кнопку &#034; <code>=</code> &#034;. Справа появляется результат &#034;<code>17,4-15,6i</code>&#034;. В нижнем окне ведётся протокол всех вычислений. Тут же выводятся сообщения об ошибках. Новая запись добавляется каждый раз когда вы нажимаете кнопку &#034; <code>=</code> &#034;.</p>
<p><img src="/wp-content/uploads/2007/08/screenshot.gif" alt="CNC 1.1 - калькулятор комплексных чисел" title="screenshot.gif" width="299" border="0" height="97" /></p>
<p><strong>ВНИМАНИЕ!</strong> Разделитель целой и дробной части (точка или запятая) зависит от настроек вашей операционной системы. Например, в MS Windows эти настройки можно изменить в окне &#034;Языки и региональные стандарты&#034; (Пуск/Настройка/ Панель управления/Языки и региональные стандарты). При этом если, например, вы введёте &#034;2.2&#034;, а десятичный разделитель у вас &#8211; запятая, то программа просто отбросит все, что идёт после точки, т.е. такое число будет считаться равным &#034;2&#034;.</p>
<p>Вы можете использовать следующие операции:</p>
<p>&#034;<code>+</code>&#034; &#8211; сложение<br />
&#034;<code>-</code>&#034; &#8211; вычитание<br />
&#034;<code>*</code>&#034; &#8211; умножение<br />
&#034;<code>/</code>&#034; &#8211; деление</p>
<p>Кроме этого можно использовать круглые скобки &#8211; &#034;<code>(</code>&#034;, &#034;<code>)</code>&#034;.</p>
<p>Например:</p>
<p><code>(2 + 3i) - 5 + 11,6<br />
89,7 - (5-2*3)/(2,4 + 3i)<br />
(3i - (2 * 5 + 4i/(2,35 + 4,75))) </code></p>
<p><strong>Инструкции по использованию апплета и исходники</strong></p>
<p>Вы можете использовать эту программу и изменять её исходный код без каких-либо ограничений.</p>
<p>Существует два варианта CNC: Java-апплет и Java-программа. Как вы понимаете, работают они одинаково. Но их внешний вид может различаться. Дело в том, что программа определяет какая операционная система у вас установлена, и использует соответствующий внешний вид (Look And Feel). Апплет не может определить, на какой платформе он запущен (из-за ограничений, связанных с безопасностью), поэтому все компоненты апплета имеют обычный вид (CrossPlatformLookAndFeel).</p>
<p>Для того, чтобы запустить программу или апплет вам нужно установить J2SE JRE (Java 2 Standart Edition Java Runtime Environment). (У меня установлена версия 1.4.2_03). А для работы с исходными кодами вам также понадобиться SDK (Software Development Kit).<br />
Скачать их можно с сайта <a href="http://java.sun.com/j2se/downloads.html">Sun Microsystems</a>.</p>
<p>Программа упакована в jar-архив, поэтому для её запуска вам нужно только сделать двойной щелчок по иконке.</p>
<p>Апплет тоже упакован в jar-архив. Встроить его в html-страницу можно так:</p>
<p><code style="text-align: left">&lt;applet code="CNC_1_1_applet.class" archive="CNC_1_1_applet.jar" width=550 height=150&gt; &lt;/applet&gt;</code></p>
<p><strong>Скачать:</strong></p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2007/08/cnc_1_1_src.zip" title="Исходный код">Исходный код (calc_src.zip &#8211; 12,4 кБ)</a>. Файл &#034;mainFrame.java&#034; &#8211; содержит функцию <code>main</code> программы (для апплета не нужен). Файл &#034;CNC_1_0_applet.java&#034; &#8211; содержит метод <code>init</code> апплета (для программы не нужен). Все остальные файлы общие.</p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2007/08/cnc_1_1_applet.zip" title="Апплет (CNC_1_1_applet.zip - 12,6 кБ)">Апплет (CNC_1_1_applet.zip &#8211; 12,6 кБ)</a></p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2007/08/cnc_1_1.zip" title="Программу (CNC_1_1.zip - 12,6 кБ)">Программу (CNC_1_1.jar &#8211; 12,6 кБ)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/cnc-11-kalkulyator-kompleksnyx-chisel.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Java апплет. Стрелочные часы.</title>
		<link>http://www.simplecoding.org/strelochnye-chasy.html</link>
		<comments>http://www.simplecoding.org/strelochnye-chasy.html#comments</comments>
		<pubDate>Fri, 17 Aug 2007 07:37:14 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/strelochnye-chasy.html</guid>
		<description><![CDATA[Этот пример демонстрирует базовые возможности библиотеки Graphics2D, которая используется для работы с двумерными изображениями. Здесь подробно описаны создание и работа апплета, представляющего собой стрелочные часы. На этом примере мы рассмотрим использование многих возможностей библиотеки: создание сложных геометрических форм, управление сглаживанием и прозрачностью, изменение рисунка в реальном времени, двойную буферизацию и др. Апплет создаёт обычные стрелочные [...]]]></description>
			<content:encoded><![CDATA[<p>Этот пример демонстрирует базовые возможности библиотеки Graphics2D, которая используется для работы с двумерными изображениями. Здесь подробно описаны создание и работа апплета, представляющего собой стрелочные часы. На этом примере мы рассмотрим использование многих возможностей библиотеки: создание сложных геометрических форм, управление сглаживанием и прозрачностью, изменение рисунка в реальном времени, двойную буферизацию и др.<br />
<span id="more-31"></span><br />
Апплет создаёт обычные стрелочные часы. Если заметите, что они показывают не то время, которое вы хотели бы видеть, просто измените время системных часов на вашем компьютере, и, максимум через секунду все будет нормально.</p>
<p>Посмотреть пример работающего апплета можно <a href="http://www.vova-prog.narod.ru/examples/clock/clock.html">здесь</a>.</p>
<p>Если апплет у вас не запустился, то, возможно, вам нужно установить Java Plug-in. Его установка происходит автоматически, когда вы устанавливаете J2SE JRE (java 2 standart edition java runtime environment) или SDK (software development kit). Скачать их можно с сайта  <a href="http://java.sun.com/j2se/downloads.html">Sun Microsystems</a>.<br />
Апплет тестировался с версиями 1.4.2_03 и 1.5.0_06.</p>
<p>Апплет создан с помощью <a href="http://www.netbeans.org/">NetBeans IDE 3.6</a></p>
<p>Подробно работа апплета описана в комментариях к <a href="http://www.simplecoding.org/wp-content/uploads/2007/08/clock_src.zip" title="Исходный код апплета">исходным кодам</a>. Здесь я хочу описать только на основные принципы работы апплета и особенности его использования.</p>
<p>В первую очередь рассмотрим, как встроить апплет в web-страницу.</p>
<p><code>&lt;applet code=CircleClock.class archive="CircleClock.jar" width = 300 height = 300&gt;<br />
&lt;param name=dialColor value="FFFEeFEFE"&gt;<br />
&lt;param name=hairLineColor value="FF42C151"&gt;<br />
&lt;param name=hoursNeedleColor value="7F000000"&gt;<br />
&lt;param name=minutesNeedleColor value="7F0000FF"&gt;<br />
&lt;param name=secondsNeedleColor value="7FFF0000"&gt;<br />
&lt;/applet&gt;</code></p>
<p>Первая строка стандартная. В ней задаются следующие параметры:</p>
<p><code>code</code> &#8211; имя класса, содержащего метод <code>init()</code>.<br />
<code>archive</code> &#8211; имя архива, содержащего апплет (jar-файл).<br />
<code>width</code> &#8211; ширина апплета.<br />
<code>height</code> &#8211; высота апплета.</p>
<p>В принципе, ограничений на ширину и высоту нет (не допускаются только нулевые или отрицательные размеры). Размер стрелок и чёрточек на циферблате будет автоматически изменён, но делать апплет слишком маленьким просто нет смысла. По моим наблюдениям, при размерах 30х30 ещё что-то можно рассмотреть.</p>
<p>Кстати, высота не обязательно должна быть равна ширине. Если они отличаются, то диаметр циферблата будет выбран равным меньшей стороне, а сам циферблат &#8211; отцентрирован относительно большей. Чтобы посмотреть как это работает, задайте размер апплета 700х300 или 100х500.</p>
<p>Следующие пять параметров задают цвета стрелок, циферблата и чёрточек на циферблате.</p>
<p>При этом параметр <code>name</code> указывает название элемента, а параметр <code>value</code> &#8211; его цвет.</p>
<p><code>dialColor</code> &#8211; цвет циферблата;<br />
<code>hairLineColor</code> &#8211; цвет чёрточек на циферблате;<br />
<code>hoursNeedleColor</code> &#8211; цвет часовой стрелки;<br />
<code>minutesNeedleColor</code> &#8211; цвет минутной стрелки;<br />
<code>secondsNeedleColor</code> &#8211; цвет секундной стрелки.</p>
<p>Как вы, наверное, догадались, цвета задаются в 16-тиричной системе счисления, а цветовая схема &#8211; ARGB (alpha, red, green, blue), т.е. первые две цифры задают прозрачность, вторые &#8211; красную составляющую цвета, третьи &#8211; зелёную, четвёртые &#8211; синюю.</p>
<p>При этом FF соответствует максимально насыщенному цвету (или нулевой прозрачности), а 00 &#8211; отсутствию данной составляющей в цвете (или 100% прозрачности).</p>
<p>Приведём несколько примеров:</p>
<p><code>FFFFFFFF</code> &#8211; не прозрачный белый цвет;<br />
<code>7F000000</code> &#8211; чёрный цвет (~50% прозрачность);<br />
<code>7F0000FF</code> &#8211; синий цвет (~50% прозрачность);<br />
<code>7F00FF00</code> &#8211; зелёный цвет (~50% прозрачность);</p>
<p>Если вы захотите какую-нибудь стрелку сделать не видимой, то просто сделайте первые две цифры равными &#034;00&#034; (100% прозрачность), цвет при этом можно задавать любой (все равно стрелка будет не видна).</p>
<p>Теперь рассмотрим как работает апплет.</p>
<p>При запуске апплета выполняется установка цветов, определение размеров, расчёт размеров стрелок, чёрточек на циферблате и т.д.</p>
<p>Далее нам необходимо с какой-то периодичностью обновлять содержимое апплета (т. е. определять текущее время и поворачивать стрелки). Для этого создаём параллельный поток (<code>timer</code>), который периодически вызывает функцию <code>update()</code>.</p>
<p>При каждом обновлении апплета мы определяем время, рассчитываем углы поворота стрелок, и выполняем перерисовку окна апплета. На перерисовке я хочу остановиться подробнее. В принципе, можно рисовать каждую стрелку сразу в окне апплета, но при этом могут возникнуть мерцания. Поэтому лучше использовать следующий приём (т.н. двойную буферизацию): создаём рисунок (объект класса BufferedImage) с размерами апплета, рисуем на нем циферблат, стрелки и др., в окне апплета рисуем уже готовый рисунок.</p>
<p>Кстати, этот апплет использует библиотеку Java2D (пакет java.awt.Graphics2D). Она входит в состав платформы Java 2, т.е. это стандартная библиотека, но некоторые классы появились только в версии 1.4, поэтому с более старыми версиями могут быть проблемы.</p>
<p>Подробнее работа программы описана в комментариях и исходникам.</p>
<p><strong>Скачать:</strong></p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2007/08/clock_src.zip" title="Исходный код апплета">Исходный код апплета (clock_src.zip &#8211; 5,8 кБ)</a></p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2007/08/circleclock.zip" title="Стрелочные часы (java-апплет, 6кБ)">Стрелочные часы (java-апплет, 6кБ)</a>.</p>
<p><strong>Постовой</strong></p>
<p>Интересная и перспективная <a href="http://www.netbee.ua/">работа в Украине</a></p>
<p><a href="http://kiev.netbee.ua/">Работа в Киеве</a> &#8211; множество открытых вакансий</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/strelochnye-chasy.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

