пятница, 8 февраля 2013 г.

Vaadin 7.0.0, Netbeans. Как быстро создать проект.

Заранее прошу прощения за слишком подробное описание, но так можно избежать многих лишних вопросов от тех, кто никогда не работал в Netbeans и/или c Vaadin.

С выходом стабильной 7-й версии веб-фреймворка Vaadin, захотелось создать тестовый проект, а так же позже перетащить основной с 6-ки на 7-ку.
Здесь я не стану описывать как создать проект с помощью, скажем так, архитектурного файла maven, потому как, практически им не пользуюсь за ненадобностью (когда понадобится - разберусь подробно :) ), все это есть на сайте Vaadin'а.
Создаем простой проект с локальными библиотеками vaadin. Такой, чтобы можно было запустить и отобразить надпись "Hello Vaadin!" с помощью компонентов фреймворка.

И так поехали, что нам нужно (будем брать последние на текущий момент версии):
- Netbeans 7.2
- Пакет с jar-файлами, качаем отсюда.

Погнали:
Создаем новый проект в Netbeans:
- File - New Project - Java Web - Web Application.
- Пишем имя проекта в поле Project Name, назовем его "Vaadin7". При желании, выберем расположение папки проекта.
- Next
- Выбираем в выпадающем меню наш сервер приложений. У меня это Apache Tomcat. Выбор сервера приложений это отдельная тема. Выбираем версию Java EE, как правило работаем с 6-й.
- Поле Context Path я очистил, это путь, который будет отображаться в браузере, сразу после локального адреса, например наш Context Path = /gtm это значит, что в браузере при запуске будет написано что-то вроде этого http://localhost:8080/gtm. Я же хочу, чтобы проект грузился просто при заходе по http://localhost:8080/. Этот параметр можно настроить позже в файле context.xml или в свойствах проекта.
- Next
- На следующей странице нам предлагают выбрать фреймворки, пропускаем это окно и жмем Finish.

Проект создан, но главная страница у него это *.jsp, нам это не нужно, мы хотим Vaadin :)
По умолчанию структура такая:










- Удаляем файл index.jsp

Создаем файл web.xml в каталоге WEB-INF.
- Жмем правой кнопкой по этой папке
- New - Other - XML - XML Document.
- Называем его web, но сам файлик, как вы увидите в поле ниже, будет в расширением xml.
- Выбираем в следующем окне тип нашего XML - Well-formed Document (по умолчанию) и жмем Finish.

Удаляем все что в нем понаписано и вставляем следующий текст:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
    id="WebApp_ID" version="2.4"
                   xmlns="http://java.sun.com/xml/ns/j2ee"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 
    <servlet>
        <servlet-name>Login</servlet-name>
       <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
        <init-param>
            <description>Vaadin application class to start</description>
            <param-name>UI</param-name>
            <param-value>nix.common.LoginForm</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>Login</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
 
</web-app>


- Сохраняем.


Теперь создадим в папке Source Packages новые папки/пакеты.
- Правой кнопкой по папке
- New - Other - Other - Folder. Либо New - Java - Java Package.
(По факту не важно что вы добавите папку или пакет, для Java оно не важно, физически пакеты это папки.)
- Назовем первую папку nix.
- Таким же макаром в папке nix, создадим папку common.
- В папке common создадим java-файл с именем LoginForm.java. Создается точно так же как и папки/пакеты, но выбираем New - Other - Java - Java Class. (Все добавленные ранее типы объектов остаются в списке быстрого добавления, думаю вы уже заметили).
Пока файл трогать не будем, давайте добавим в проект скачанные ранее библиотеки Vaadin 7.

Распакуем скачанный архив, вот его структура:























Нам понадобятся 8 файлов, 7 из корневой папки:
- vaadin-client-7.0.0.jar
- vaadin-client-compiled-7.0.0.jar
- vaadin-client-compiler-7.0.0.jar
- vaadin-server-7.0.0.jar
- vaadin-shared-7.0.0.jar
- vaadin-theme-compiler-7.0.0.jar
- vaadin-themes-7.0.0.jar

и один из папки libs:
- jsoup-1.6.3.jar

Соберем их все в одну папку и сохраним куда-нибудь отдельно, туда, где мы будем хранить библиотеки.
Щелкаем правой кнопкой по папке Libraries и может:
- Add JAR/Folder  (сразу добавляем все наши файлы к проекту, для примера я так и сделал).
- Add Library (Если вы через меню Netbeans'a, Tools - Ant Libraries, добавили и как-нибудь назвали свою библиотеку).
В итоге получили такую вот структуру проекта:






















Вернемся к нашему java классу LoginForm.java, дополним его кодом, получим следующее содержание:


package nix.common;

import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

public class LoginForm extends UI {

    @Override
    protected void init(VaadinRequest request) {
        VerticalLayout view = new VerticalLayout();
        view.addComponent(new Label("Hello Vaadin!"));
        setContent(view);
    }
}

Вот и все.
Теперь, если вы все сделали верно, то при запуске откроется ваш браузер по-умолчанию и в нем будет надпись "Hello Vaadin!" на сером фоне.



Основные, отличия 7-го Vaadin'а от 6-го в плане настроек это то, что теперь вместо пакета
com.vaadin.Application
используется
com.vaadin.ui.UI
Что и было использовано в java-классе.

Кроме того, пришлось изменить и web.xml.
Раньше было: <servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class>
Теперь: <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
и
Раньше было:
                       <init-param>
            <param-name>application</param-name>
            <param-value>nix.common.LoginForm</param-value>
                      </init-param>
Теперь:
                      <init-param>

            <param-name>UI</param-name>
            <param-value>nix.common.LoginForm</param-value>
                     </init-param>

Кроме того, теперь не нужно качать отдельно пакеты GWT и компилить их для проекта, они уже включены в библиотеки в том виде, в котором нужно.
Есть вопросы - пишите их в комментариях, а я пока пошел добавлять другой функционал в тестовый проект :)

среда, 16 января 2013 г.

Update в PostghreSQL, перенос данных из одной таблицы в другую

Глупейшая ситуация возникла, однако.
Потратил не менее 30 минут на написание вот такого простого запроса.

UPDATE invoices SET contractorname = c.name from contractors c where invoices.contractorid = c.id

Дело в том, что мне потребовалось перенести ИМЯ Клиента из таблицы Клиентов в поле находящееся в таблице Счетов.
В таблице Счетов id клиента уже был.
Чтобы такого не повторилось, и я в случае чего быстренько вспомнил, распишу все подробно, так как с SQL сталкиваюсь редко и стараюсь писать запросы как можно более простые и понятные.

UPDATE invoices
-- будем апдейтить эту таблицу Счетов 'invoices'.
SET contractorname = c.name from contractors c
-- будем апдейтить поле 'contractorname' с именем клиента в таблице Счетов
-- = апдейтить его будем данными из поля 'с.name' в таблице Клиенты 'contractors '
WHERE invoices.contractorid = c.id
-- ну и условие, по которому у нас будут сравниваться поля в одной и в другой таблице.

Сначала я по какой-то непонятной мне старой привычке хотел написать следующее:
UPDATE invoices, contractors  SET invoices.contractorname = contractors.name WHERE invoices.contractorid = contractors.id
Но это не прокатывает в PostgreSQL.

В общем гуггл руллит :)

воскресенье, 2 декабря 2012 г.

Mac OS "Сообщения", список контактов ICQ



Кому лень читать - жмем комманд+1 при активном окне сообщений и список контактов появится.

 Если кого-нибудь интересует как добавить в стандартный месенджер сообщений в Mac OS аккаунт ICQ, то для этого достаточно зайти в гугл, все это очень легко находится.
 Но вот чего я действительно не смог найти, дак это, как же после того, как добавил учетную запись ICQ в программу "сообщения" открыть список контактов.
 Все оказалось проще, в меню "окно" выбираем пункт "друзья" или жмем комбинацию из первого предложения.

пятница, 25 мая 2012 г.

Повторившийся трекинг (repeated tracking)

Забавный случай только что произошел :)
Пару дней назад заказал на ебее (www.ebay.com) одну вещь, решил посмотреть через http://www.track-trace.com/ где там моя вещица.. ну вроде все в порядке:



















Жму на вкладку, чтобы выбрать страну, выбираю, естественно "Рашу", и что же я вижу - оказывается, я уже получил свой товар еще в феврале 2011 :)


Раньше считал, что номера уникальны, ну или как минимум повторяются  лет через 5, и старые повторы удаляются.
Что ж, и такое бывает как видно. Буду ждать.

среда, 29 февраля 2012 г.

Перевод числа в прописной вид (деньги, рубли)

        Пришла необходимость добавить в систему отображение цифр, а конкретнее цен в счетах, в прописном виде.
т.е. "100.00" переводим в "Сто рублей 00 копеек."
        Долго не мудрствуя обратился к Google'у. Наткнулся на простенький и тем привлекательный код автора называющего себя runcore. Спасибо ему большое. Абсолютно честно сплагиатил у него, немного изменив под себя.
        Все что я до этого находил было либо перегружено возможностями, такими как отображение разных валют, и потому разбираться не особо хотелось. Либо код был настолько "быдло", что рассматривать его просто было противно.
Привожу код здесь.

/**
 * Класс для работы с деньгами
 * @author runcore
 */

import java.util.ArrayList;
import java.util.Collections;
import java.math.BigDecimal;


public class NumToStrMoney {

    /**
     * Сумма денег
     */
    private BigDecimal amount;

    /**
     * Конструктор из Long
     */
    public NumToStrMoney(long l) {
        String s = String.valueOf(l);
        if (!s.contains(".")) {
            s += ".0";
        }
        this.amount = new BigDecimal(s);
    }

    /**
     * Конструктор из Double
     */
    public NumToStrMoney(double l) {
        String s = String.valueOf(l);
        if (!s.contains(".")) {
            s += ".0";
        }
        this.amount = new BigDecimal(s);
    }

    /**
     * Конструктор из String
     */
    public NumToStrMoney(String s) {
        if (!s.contains(".")) {
            s += ".0";
        }
        this.amount = new BigDecimal(s);
    }

    /**
     * Вернуть сумму как строку
     */
    public String asString() {
        return amount.toString();
    }

    /**
     * Вернуть сумму прописью, с точностью до копеек
     */
    public String num2str() {
        return num2str(false);
    }

    /**
     * Выводим сумму прописью
     * @param stripkop boolean флаг - показывать копейки или нет
     * @return String Сумма прописью
     */
    public String num2str(boolean stripkop) {
        String[][] sex = {
            {"", "один", "два", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять"},
            {"", "одна", "две", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять"},};
        String[] str100 = {"", "сто", "двести", "триста", "четыреста", "пятьсот", "шестьсот", "семьсот", "восемьсот", "девятьсот"};
        String[] str11 = {"", "десять", "одиннадцать", "двенадцать", "тринадцать", "четырнадцать", "пятнадцать", "шестнадцать", "семнадцать", "восемнадцать", "девятнадцать", "двадцать"};
        String[] str10 = {"", "десять", "двадцать", "тридцать", "сорок", "пятьдесят", "шестьдесят", "семьдесят", "восемьдесят", "девяносто"};
        String[][] forms = {
            {"копейка", "копейки", "копеек", "1"},
            {"рубль", "рубля", "рублей", "0"},
            {"тысяча", "тысячи", "тысяч", "1"},
            {"миллион", "миллиона", "миллионов", "0"},
            {"миллиард", "миллиарда", "миллиардов", "0"},
            {"триллион", "триллиона", "триллионов", "0"}, // можно добавлсть дальше секстиллионы и т.д.
        };
// получаем отдельно рубли и копейки
        long rub = amount.longValue();
        String[] moi = amount.toString().split("\\.");
        long kop = Long.valueOf(moi[1]);
        if (!moi[1].substring(0, 1).equals("0")) {// начинаетсс не с нулс
            if (kop < 10) {
                kop *= 10;
            }
        }
        String kops = String.valueOf(kop);
        if (kops.length() == 1) {
            kops = "0" + kops;
        }
        long rub_tmp = rub;
// Разбиватель суммы на сегменты по 3 цифры с конца
        ArrayList segments = new ArrayList();
        while (rub_tmp > 999) {
            long seg = rub_tmp / 1000;
            segments.add(rub_tmp - (seg * 1000));
            rub_tmp = seg;
        }
        segments.add(rub_tmp);
        Collections.reverse(segments);
// снализируем сегменты
        String o = "";
        if (rub == 0) {// если соль
            o = "ноль " + morph(0, forms[1][0], forms[1][1], forms[1][2]);
            if (stripkop) {
                return o;
            } else {
                return o + " " + kop + " " + morph(kop, forms[0][0], forms[0][1], forms[0][2]);
            }
        }
// Больше нуля
        int lev = segments.size();
        for (int i = 0; i < segments.size(); i++) {// перебираем сегменты
            int sexi = (int) Integer.valueOf(forms[lev][3].toString());// определсем род
            int ri = (int) Integer.valueOf(segments.get(i).toString());// текущий сегмент
            if (ri == 0 && lev > 1) {// если сегмент ==0 И не последний уровень(там Units)
                lev--;
                continue;
            }
            String rs = String.valueOf(ri); // число в строку
// нормализация
            if (rs.length() == 1) {
                rs = "00" + rs;// два нулика в префикс?
            }
            if (rs.length() == 2) {
                rs = "0" + rs; // или лучше один?
            }// получаем циферки длс анализа
            int r1 = (int) Integer.valueOf(rs.substring(0, 1)); //первас цифра
            int r2 = (int) Integer.valueOf(rs.substring(1, 2)); //вторас
            int r3 = (int) Integer.valueOf(rs.substring(2, 3)); //третьс
            int r22 = (int) Integer.valueOf(rs.substring(1, 3)); //вторас и третьс
// Супер-нано-анализатор циферок
            if (ri > 99) {
                o += str100[r1] + " "; // Сотни
            }
            if (r22 > 20) {// >20
                o += str10[r2] + " ";
                o += sex[sexi][r3] + " ";
            } else { // <=20
                if (r22 > 9) {
                    o += str11[r22 - 9] + " "; // 10-20
                } else {
                    o += sex[sexi][r3] + " "; // 0-9
                }
            }
// Единицы измерения (рубли...)
            o += morph(ri, forms[lev][0], forms[lev][1], forms[lev][2]) + " ";
            lev--;
        }
// Копейки в цифровом виде
        if (stripkop) {
            o = o.replaceAll(" {2,}", " ");
        } else {
            o = o + "" + kops + " " + morph(kop, forms[0][0], forms[0][1], forms[0][2]);
            o = o.replaceAll(" {2,}", " ");
        }
        return o;
    }

    /**
     * Склонсем словоформу
     * @param n Long количество объектов
     * @param f1 String вариант словоформы длс одного объекта
     * @param f2 String вариант словоформы длс двух объектов
     * @param f5 String вариант словоформы длс псти объектов
     * @return String правильный вариант словоформы длс указанного количества объектов
     */
    public static String morph(long n, String f1, String f2, String f5) {
        n = Math.abs(n) % 100;
        long n1 = n % 10;
        if (n > 10 && n < 20) {
            return f5;
        }
        if (n1 > 1 && n1 < 5) {
            return f2;
        }
        if (n1 == 1) {
            return f1;
        }
        return f5;
    }

    public static void main(String[] args) {
        NumToStrMoney ntsm = new NumToStrMoney(15555.48);
        System.out.println(ntsm.asString());
        System.out.println(ntsm.num2str(true));
        System.out.println(ntsm.num2str());
    }
}


В трейсе после запуска получим следующее

run-main:
15555.48
пятнадцать тысяч пятьсот пятьдесят пять рублей
пятнадцать тысяч пятьсот пятьдесят пять рублей 48 копеек

Что обычно и требуется дл небольших проектов.

пятница, 20 января 2012 г.

Drift innovation HD170 stealth - битый пиксель



Приобрел на днях этот девайс, для записи своих покатушек на борде. Начал тестировать, и увидел на видео что-то наподобие битого пикселя. Сначала подумал, что это на мониторе. Оказалось, что битый пиксель присутствует на матрице которая принимает изображение.
Немного погуглил и нашел решение - помогло, пиксель исчез.
Делюсь методом.
Нужно просто напросто обновить прошивку камеры. Прошивку можно скачать здесь. Там же есть и способы прошивки для других камер от Drift. Прошить очень просто.
HD170 stealth прошивается так:

  1. Скопируйте скачанный файл в корневой каталог пустой и отформатированной SD-карты памяти. ВАЖНО: не переименовывайте файл.
  2. Вставьте карту памяти в камеру и включите питание. Убедитесь, что у камеры достаточный уровень заряда аккумулятора и процесс обновления прошивки не прервется на полпути.
  3. Выберите в меню Setup последний пункт с номером версии прошивки и подтвердите выбор.
  4. Выберите галочку и кликните на нее, подтверждая выбор.
  5. Светодиод на камере во время процесса будет мигать, а на экране будет надпись "Wait for FW update". По окончании процесса камера выключится.
  6. Включите камеру и проверьте, что прошивка была обновлена.
  7. Отформатируйте карту памяти при помощи меню камеры.
 Этот же метод описан по ссылке с прошивками.

После прошивки, как пишут на форумах, этот битый пиксель "исчезает" благодаря его  окрашиванию на видео в цвет близкий к ближайшим пикселям. И получается, что его как бы и нет. И пользователь даже не догадывается что он там есть/был.